]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/episodes/ApplyForm.js
svg dungeon tracker
[alttp.git] / resources / js / components / episodes / ApplyForm.js
1 import { withFormik } from 'formik';
2 import PropTypes from 'prop-types';
3 import React from 'react';
4 import { Button, Form, Modal } from 'react-bootstrap';
5 import { useTranslation } from 'react-i18next';
6
7 import DialogEpisode from './DialogEpisode';
8 import laravelErrorsToFormik from '../../helpers/laravelErrorsToFormik';
9 import { applicableChannels } from '../../helpers/permissions';
10 import { withUser } from '../../hooks/user';
11
12 const ApplyForm = ({
13         as,
14         episode,
15         errors,
16         handleBlur,
17         handleChange,
18         handleSubmit,
19         onCancel,
20         touched,
21         user,
22         values,
23 }) => {
24         const { t } = useTranslation();
25
26         const available_channels = React.useMemo(() => {
27                 return applicableChannels(user, episode, as);
28         }, [as, episode, user]);
29
30         return <Form noValidate onSubmit={handleSubmit}>
31                 <Modal.Body>
32                         <DialogEpisode episode={episode} />
33                         <Form.Group controlId="apply.role">
34                                 <Form.Label>{t('episodes.applyDialog.signUpAs')}</Form.Label>
35                                 <Form.Control
36                                         plaintext
37                                         readOnly
38                                         value={t(`crew.roles.${as}`)}
39                                 />
40                         </Form.Group>
41                         <Form.Group controlId="apply.channel_id">
42                                 <Form.Label>{t('episodes.channel')}</Form.Label>
43                                 <Form.Select
44                                         isInvalid={!!(touched.channel_id && errors.channel_id)}
45                                         name="channel_id"
46                                         onBlur={handleBlur}
47                                         onChange={handleChange}
48                                         value={values.channel_id || 0}
49                                 >
50                                         <option disabled value={0}>{t('general.pleaseSelect')}</option>
51                                         {available_channels.map(c =>
52                                                 <option key={c.id} value={c.id}>
53                                                         {c.title}
54                                                 </option>
55                                         )}
56                                 </Form.Select>
57                                 {touched.channel_id && errors.channel_id ?
58                                         <Form.Control.Feedback type="invalid">
59                                                 {t(errors.channel_id)}
60                                         </Form.Control.Feedback>
61                                 : null}
62                         </Form.Group>
63                 </Modal.Body>
64                 <Modal.Footer>
65                         {onCancel ?
66                                 <Button onClick={onCancel} variant="secondary">
67                                         {t('button.cancel')}
68                                 </Button>
69                         : null}
70                         <Button type="submit" variant="primary">
71                                 {t('button.submit')}
72                         </Button>
73                 </Modal.Footer>
74         </Form>;
75 };
76
77 ApplyForm.propTypes = {
78         as: PropTypes.string,
79         episode: PropTypes.shape({
80         }),
81         errors: PropTypes.shape({
82                 channel_id: PropTypes.string,
83         }),
84         handleBlur: PropTypes.func,
85         handleChange: PropTypes.func,
86         handleSubmit: PropTypes.func,
87         onCancel: PropTypes.func,
88         touched: PropTypes.shape({
89                 channel_id: PropTypes.bool,
90         }),
91         user: PropTypes.shape({
92         }),
93         values: PropTypes.shape({
94                 channel_id: PropTypes.number,
95         }),
96 };
97
98 export default withUser(withFormik({
99         displayName: 'ApplyForm',
100         enableReinitialize: true,
101         handleSubmit: async (values, actions) => {
102                 const { setErrors } = actions;
103                 const { onSubmit } = actions.props;
104                 try {
105                         await onSubmit(values);
106                 } catch (e) {
107                         if (e.response && e.response.data && e.response.data.errors) {
108                                 setErrors(laravelErrorsToFormik(e.response.data.errors));
109                         }
110                 }
111         },
112         mapPropsToValues: ({ as, episode, user }) => {
113                 const channels = applicableChannels(user, episode, as);
114                 return {
115                         as,
116                         channel_id: channels.length ? channels[0].id : 0,
117                         episode_id: episode ? episode.id : 0,
118                 };
119         },
120 })(ApplyForm));