]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/results/ReportForm.js
server calculated scoring
[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/Participant';
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         touched,
23         values,
24 }) =>
25 <Form noValidate onSubmit={handleSubmit}>
26         <Modal.Body>
27                 <Row>
28                         <Form.Group as={Col} sm={9} controlId="report.time">
29                                 <Form.Label>{i18n.t('results.reportTime')}</Form.Label>
30                                 <Form.Control
31                                         isInvalid={!!(touched.time && errors.time)}
32                                         name="time"
33                                         onBlur={handleBlur}
34                                         onChange={handleChange}
35                                         placeholder={values.forfeit ? 'DNF' : '1:22:59'}
36                                         type="text"
37                                         value={values.time || ''}
38                                 />
39                                 {touched.time && errors.time ?
40                                         <Form.Control.Feedback type="invalid">
41                                                 {i18n.t(errors.time)}
42                                         </Form.Control.Feedback>
43                                 :
44                                         <Form.Text muted>
45                                                 {parseTime(values.time) ?
46                                                         i18n.t(
47                                                                 'results.reportPreview',
48                                                                 { time: formatTime({ time: parseTime(values.time) })},
49                                                         )
50                                                 : null}
51                                         </Form.Text>
52                                 }
53                         </Form.Group>
54                         <Form.Group as={Col} sm={3} controlId="report.forfeit">
55                                 <Form.Label>{i18n.t('results.forfeit')}</Form.Label>
56                                 <Form.Control
57                                         as={LargeCheck}
58                                         isInvalid={!!(touched.forfeit && errors.forfeit)}
59                                         name="forfeit"
60                                         onBlur={handleBlur}
61                                         onChange={handleChange}
62                                         value={!!values.forfeit}
63                                 />
64                         </Form.Group>
65                 </Row>
66         </Modal.Body>
67         <Modal.Footer>
68                 {onCancel ?
69                         <Button onClick={onCancel} variant="secondary">
70                                 {i18n.t('button.cancel')}
71                         </Button>
72                 : null}
73                 <Button type="submit" variant="primary">
74                         {i18n.t('button.save')}
75                 </Button>
76         </Modal.Footer>
77 </Form>;
78
79 ReportForm.propTypes = {
80         errors: PropTypes.shape({
81                 forfeit: PropTypes.string,
82                 time: PropTypes.string,
83         }),
84         handleBlur: PropTypes.func,
85         handleChange: PropTypes.func,
86         handleSubmit: PropTypes.func,
87         onCancel: PropTypes.func,
88         touched: PropTypes.shape({
89                 forfeit: PropTypes.bool,
90                 time: PropTypes.bool,
91         }),
92         values: PropTypes.shape({
93                 forfeit: PropTypes.bool,
94                 time: PropTypes.string,
95         }),
96 };
97
98 export default withFormik({
99         displayName: 'ReportForm',
100         enableReinitialize: true,
101         handleSubmit: async (values, actions) => {
102                 const { forfeit, participant_id, round_id, time } = values;
103                 const { setErrors } = actions;
104                 const { onCancel } = actions.props;
105                 try {
106                         await axios.post('/api/results', {
107                                 forfeit,
108                                 participant_id,
109                                 round_id,
110                                 time: parseTime(time) || 0,
111                         });
112                         toastr.success(i18n.t('results.reportSuccess'));
113                         if (onCancel) {
114                                 onCancel();
115                         }
116                 } catch (e) {
117                         toastr.error(i18n.t('results.reportError'));
118                         if (e.response && e.response.data && e.response.data.errors) {
119                                 setErrors(laravelErrorsToFormik(e.response.data.errors));
120                         }
121                 }
122         },
123         mapPropsToValues: ({ participant, round }) => {
124                 const result = findResult(participant, round);
125                 return {
126                         forfeit: result ? !!result.forfeit : false,
127                         participant_id: participant.id,
128                         round_id: round.id,
129                         time: result && result.time ? formatTime(result) : '',
130                 };
131         },
132         validationSchema: yup.object().shape({
133                 forfeit: yup.boolean().required(),
134                 time: yup.string().time().when('forfeit', {
135                         is: false,
136                         then: yup.string().required().time(),
137                 }),
138         }),
139 })(withTranslation()(ReportForm));