]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/results/ReportForm.js
open tournament type
[alttp.git] / resources / js / components / results / ReportForm.js
1 import axios from 'axios';
2 import { withFormik } from 'formik';
3 import PropTypes from 'prop-types';
4 import React from 'react';
5 import { Button, Col, Form, Modal, Row } from 'react-bootstrap';
6 import { withTranslation } from 'react-i18next';
7 import toastr from 'toastr';
8
9 import LargeCheck from '../common/LargeCheck';
10 import laravelErrorsToFormik from '../../helpers/laravelErrorsToFormik';
11 import { findResult } from '../../helpers/User';
12 import { formatTime, parseTime } from '../../helpers/Result';
13 import i18n from '../../i18n';
14 import yup from '../../schema/yup';
15
16 const ReportForm = ({
17         errors,
18         handleBlur,
19         handleChange,
20         handleSubmit,
21         onCancel,
22         round,
23         touched,
24         values,
25 }) =>
26 <Form noValidate onSubmit={handleSubmit}>
27         <Modal.Body>
28                 {!round.locked ?
29                         <Row>
30                                 <Form.Group as={Col} sm={9} controlId="report.time">
31                                         <Form.Label>{i18n.t('results.reportTime')}</Form.Label>
32                                         <Form.Control
33                                                 isInvalid={!!(touched.time && errors.time)}
34                                                 name="time"
35                                                 onBlur={handleBlur}
36                                                 onChange={handleChange}
37                                                 placeholder={values.forfeit ? 'DNF' : '1:22:59'}
38                                                 type="text"
39                                                 value={values.time || ''}
40                                         />
41                                         {touched.time && errors.time ?
42                                                 <Form.Control.Feedback type="invalid">
43                                                         {i18n.t(errors.time)}
44                                                 </Form.Control.Feedback>
45                                         :
46                                                 <Form.Text muted>
47                                                         {parseTime(values.time) ?
48                                                                 i18n.t(
49                                                                         'results.reportPreview',
50                                                                         { time: formatTime({ time: parseTime(values.time) })},
51                                                                 )
52                                                         : null}
53                                                 </Form.Text>
54                                         }
55                                 </Form.Group>
56                                 <Form.Group as={Col} sm={3} controlId="report.forfeit">
57                                         <Form.Label>{i18n.t('results.forfeit')}</Form.Label>
58                                         <Form.Control
59                                                 as={LargeCheck}
60                                                 isInvalid={!!(touched.forfeit && errors.forfeit)}
61                                                 name="forfeit"
62                                                 onBlur={handleBlur}
63                                                 onChange={handleChange}
64                                                 value={!!values.forfeit}
65                                         />
66                                 </Form.Group>
67                         </Row>
68                 : null}
69                 <Row>
70                         <Form.Group as={Col} sm={12} controlId="report.comment">
71                                 <Form.Label>{i18n.t('results.comment')}</Form.Label>
72                                 <Form.Control
73                                         as="textarea"
74                                         isInvalid={!!(touched.comment && errors.comment)}
75                                         name="comment"
76                                         onBlur={handleBlur}
77                                         onChange={handleChange}
78                                         value={values.comment || ''}
79                                 />
80                         </Form.Group>
81                 </Row>
82         </Modal.Body>
83         <Modal.Footer>
84                 {onCancel ?
85                         <Button onClick={onCancel} variant="secondary">
86                                 {i18n.t('button.cancel')}
87                         </Button>
88                 : null}
89                 <Button type="submit" variant="primary">
90                         {i18n.t('button.save')}
91                 </Button>
92         </Modal.Footer>
93 </Form>;
94
95 ReportForm.propTypes = {
96         errors: PropTypes.shape({
97                 comment: PropTypes.string,
98                 forfeit: PropTypes.string,
99                 time: PropTypes.string,
100         }),
101         handleBlur: PropTypes.func,
102         handleChange: PropTypes.func,
103         handleSubmit: PropTypes.func,
104         onCancel: PropTypes.func,
105         round: PropTypes.shape({
106                 locked: PropTypes.bool,
107         }),
108         touched: PropTypes.shape({
109                 comment: PropTypes.bool,
110                 forfeit: PropTypes.bool,
111                 time: PropTypes.bool,
112         }),
113         values: PropTypes.shape({
114                 comment: PropTypes.string,
115                 forfeit: PropTypes.bool,
116                 time: PropTypes.string,
117         }),
118 };
119
120 export default withFormik({
121         displayName: 'ReportForm',
122         enableReinitialize: true,
123         handleSubmit: async (values, actions) => {
124                 const { comment, forfeit, round_id, time, user_id } = values;
125                 const { setErrors } = actions;
126                 const { onCancel } = actions.props;
127                 try {
128                         await axios.post('/api/results', {
129                                 comment,
130                                 forfeit,
131                                 round_id,
132                                 time: parseTime(time) || 0,
133                                 user_id,
134                         });
135                         toastr.success(i18n.t('results.reportSuccess'));
136                         if (onCancel) {
137                                 onCancel();
138                         }
139                 } catch (e) {
140                         toastr.error(i18n.t('results.reportError'));
141                         if (e.response && e.response.data && e.response.data.errors) {
142                                 setErrors(laravelErrorsToFormik(e.response.data.errors));
143                         }
144                 }
145         },
146         mapPropsToValues: ({ round, user }) => {
147                 const result = findResult(user, round);
148                 return {
149                         comment: result && result.comment ? result.comment : '',
150                         forfeit: result ? !!result.forfeit : false,
151                         round_id: round.id,
152                         time: result && result.time ? formatTime(result) : '',
153                         user_id: user.id,
154                 };
155         },
156         validationSchema: yup.object().shape({
157                 comment: yup.string(),
158                 forfeit: yup.boolean().required(),
159                 time: yup.string().time().when('forfeit', {
160                         is: false,
161                         then: yup.string().required().time(),
162                 }),
163         }),
164 })(withTranslation()(ReportForm));