]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/twitch-bot/GuessingSettingsForm.js
some guessing game fixes
[alttp.git] / resources / js / components / twitch-bot / GuessingSettingsForm.js
1 import { withFormik } from 'formik';
2 import PropTypes from 'prop-types';
3 import React from 'react';
4 import { Button, Col, Form, Row } from 'react-bootstrap';
5 import { useTranslation } from 'react-i18next';
6
7 import laravelErrorsToFormik from '../../helpers/laravelErrorsToFormik';
8 import i18n from '../../i18n';
9 import yup from '../../schema/yup';
10
11 const GuessingSettingsForm = ({
12         errors,
13         handleBlur,
14         handleChange,
15         handleSubmit,
16         onCancel,
17         touched,
18         values,
19 }) => {
20         const { t } = useTranslation();
21
22         return <Form noValidate onSubmit={handleSubmit}>
23                 <Row>
24                         <Form.Group as={Col} controlId="gg.points_exact_first" md={6}>
25                                 <Form.Label>{t('twitchBot.guessingGame.pointsExactFirst')}</Form.Label>
26                                 <Form.Control
27                                         isInvalid={!!(touched.points_exact_first && errors.points_exact_first)}
28                                         max="5"
29                                         min="1"
30                                         name="points_exact_first"
31                                         onBlur={handleBlur}
32                                         onChange={handleChange}
33                                         step="1"
34                                         type="number"
35                                         value={values.points_exact_first || 0}
36                                 />
37                                 {touched.points_exact_first && errors.points_exact_first ?
38                                         <Form.Control.Feedback type="invalid">
39                                                 {t(errors.points_exact_first)}
40                                         </Form.Control.Feedback>
41                                 : null}
42                         </Form.Group>
43                         <Form.Group as={Col} controlId="gg.points_exact_other" md={6}>
44                                 <Form.Label>{t('twitchBot.guessingGame.pointsExactOther')}</Form.Label>
45                                 <Form.Control
46                                         isInvalid={!!(touched.points_exact_other && errors.points_exact_other)}
47                                         max="5"
48                                         min="0"
49                                         name="points_exact_other"
50                                         onBlur={handleBlur}
51                                         onChange={handleChange}
52                                         step="1"
53                                         type="number"
54                                         value={values.points_exact_other || 0}
55                                 />
56                                 {touched.points_exact_other && errors.points_exact_other ?
57                                         <Form.Control.Feedback type="invalid">
58                                                 {t(errors.points_exact_other)}
59                                         </Form.Control.Feedback>
60                                 : null}
61                         </Form.Group>
62                         <Form.Group as={Col} controlId="gg.points_close_first" md={6}>
63                                 <Form.Label>{t('twitchBot.guessingGame.pointsCloseFirst')}</Form.Label>
64                                 <Form.Control
65                                         isInvalid={!!(touched.points_close_first && errors.points_close_first)}
66                                         max="5"
67                                         min="0"
68                                         name="points_close_first"
69                                         onBlur={handleBlur}
70                                         onChange={handleChange}
71                                         step="0.5"
72                                         type="number"
73                                         value={values.points_close_first || 0}
74                                 />
75                                 {touched.points_close_first && errors.points_close_first ?
76                                         <Form.Control.Feedback type="invalid">
77                                                 {t(errors.points_close_first)}
78                                         </Form.Control.Feedback>
79                                 : null}
80                         </Form.Group>
81                         <Form.Group as={Col} controlId="gg.points_close_other" md={6}>
82                                 <Form.Label>{t('twitchBot.guessingGame.pointsCloseOther')}</Form.Label>
83                                 <Form.Control
84                                         isInvalid={!!(touched.points_close_other && errors.points_close_other)}
85                                         max="5"
86                                         min="0"
87                                         name="points_close_other"
88                                         onBlur={handleBlur}
89                                         onChange={handleChange}
90                                         step="0.5"
91                                         type="number"
92                                         value={values.points_close_other || 0}
93                                 />
94                                 {touched.points_close_other && errors.points_close_other ?
95                                         <Form.Control.Feedback type="invalid">
96                                                 {t(errors.points_close_other)}
97                                         </Form.Control.Feedback>
98                                 : null}
99                         </Form.Group>
100                         <Form.Group as={Col} controlId="gg.points_close_max" md={6}>
101                                 <Form.Label>{t('twitchBot.guessingGame.pointsCloseMax')}</Form.Label>
102                                 <Form.Control
103                                         isInvalid={!!(touched.points_close_max && errors.points_close_max)}
104                                         min="0"
105                                         name="points_close_max"
106                                         onBlur={handleBlur}
107                                         onChange={handleChange}
108                                         step="1"
109                                         type="number"
110                                         value={values.points_close_max || 0}
111                                 />
112                                 {touched.points_close_max && errors.points_close_max ?
113                                         <Form.Control.Feedback type="invalid">
114                                                 {t(errors.points_close_max)}
115                                         </Form.Control.Feedback>
116                                 : null}
117                         </Form.Group>
118                         <Form.Group as={Col} controlId="gg.leaderboard_type" md={6}>
119                                 <Form.Label>{t('twitchBot.guessingGame.leaderboardType')}</Form.Label>
120                                 <Form.Select
121                                         isInvalid={!!(touched.leaderboard_type && errors.leaderboard_type)}
122                                         name="leaderboard_type"
123                                         onBlur={handleBlur}
124                                         onChange={handleChange}
125                                         value={values.leaderboard_type || 'all'}
126                                 >
127                                         {['all', 'year', '365', 'month', '30'].map(type =>
128                                                 <option key={type} value={type}>
129                                                         {t(`twitchBot.guessingGame.leaderboardTypes.${type}`)}
130                                                 </option>
131                                         )}
132                                 </Form.Select>
133                                 {touched.leaderboard_type && errors.leaderboard_type ?
134                                         <Form.Control.Feedback type="invalid">
135                                                 {t(errors.leaderboard_type)}
136                                         </Form.Control.Feedback>
137                                 : null}
138                         </Form.Group>
139                 </Row>
140                 <Form.Group controlId="gg.start_message">
141                         <Form.Label>{t('twitchBot.guessingGame.startMessage')}</Form.Label>
142                         <Form.Control
143                                 isInvalid={!!(touched.start_message && errors.start_message)}
144                                 name="start_message"
145                                 onBlur={handleBlur}
146                                 onChange={handleChange}
147                                 type="text"
148                                 value={values.start_message || ''}
149                         />
150                         {touched.start_message && errors.start_message ?
151                                 <Form.Control.Feedback type="invalid">
152                                         {t(errors.start_message)}
153                                 </Form.Control.Feedback>
154                         : null}
155                 </Form.Group>
156                 <Form.Group controlId="gg.stop_message">
157                         <Form.Label>{t('twitchBot.guessingGame.stopMessage')}</Form.Label>
158                         <Form.Control
159                                 isInvalid={!!(touched.stop_message && errors.stop_message)}
160                                 name="stop_message"
161                                 onBlur={handleBlur}
162                                 onChange={handleChange}
163                                 type="text"
164                                 value={values.stop_message || ''}
165                         />
166                         {touched.stop_message && errors.stop_message ?
167                                 <Form.Control.Feedback type="invalid">
168                                         {t(errors.stop_message)}
169                                 </Form.Control.Feedback>
170                         : null}
171                 </Form.Group>
172                 <Form.Group controlId="gg.winners_message">
173                         <Form.Label>{t('twitchBot.guessingGame.winnersMessage')}</Form.Label>
174                         <Form.Control
175                                 isInvalid={!!(touched.winners_message && errors.winners_message)}
176                                 name="winners_message"
177                                 onBlur={handleBlur}
178                                 onChange={handleChange}
179                                 type="text"
180                                 value={values.winners_message || ''}
181                         />
182                         {touched.winners_message && errors.winners_message ?
183                                 <Form.Control.Feedback type="invalid">
184                                         {t(errors.winners_message)}
185                                 </Form.Control.Feedback>
186                         :
187                                 <Form.Text muted>
188                                         {t('twitchBot.guessingGame.winnersMessageHint')}
189                                 </Form.Text>
190                         }
191                 </Form.Group>
192                 <Form.Group controlId="gg.close_winners_message">
193                         <Form.Label>{t('twitchBot.guessingGame.closeWinnersMessage')}</Form.Label>
194                         <Form.Control
195                                 isInvalid={!!(touched.close_winners_message && errors.close_winners_message)}
196                                 name="close_winners_message"
197                                 onBlur={handleBlur}
198                                 onChange={handleChange}
199                                 type="text"
200                                 value={values.close_winners_message || ''}
201                         />
202                         {touched.close_winners_message && errors.close_winners_message ?
203                                 <Form.Control.Feedback type="invalid">
204                                         {t(errors.close_winners_message)}
205                                 </Form.Control.Feedback>
206                         :
207                                 <Form.Text muted>
208                                         {t('twitchBot.guessingGame.closeWinnersMessageHint')}
209                                 </Form.Text>
210                         }
211                 </Form.Group>
212                 <Form.Group controlId="gg.no_winners_message">
213                         <Form.Label>{t('twitchBot.guessingGame.noWinnersMessage')}</Form.Label>
214                         <Form.Control
215                                 isInvalid={!!(touched.no_winners_message && errors.no_winners_message)}
216                                 name="no_winners_message"
217                                 onBlur={handleBlur}
218                                 onChange={handleChange}
219                                 type="text"
220                                 value={values.no_winners_message || ''}
221                         />
222                         {touched.no_winners_message && errors.no_winners_message ?
223                                 <Form.Control.Feedback type="invalid">
224                                         {t(errors.no_winners_message)}
225                                 </Form.Control.Feedback>
226                         : null}
227                 </Form.Group>
228                 <Form.Group controlId="gg.cancel_message">
229                         <Form.Label>{t('twitchBot.guessingGame.cancelMessage')}</Form.Label>
230                         <Form.Control
231                                 isInvalid={!!(touched.cancel_message && errors.cancel_message)}
232                                 name="cancel_message"
233                                 onBlur={handleBlur}
234                                 onChange={handleChange}
235                                 type="text"
236                                 value={values.cancel_message || ''}
237                         />
238                         {touched.cancel_message && errors.cancel_message ?
239                                 <Form.Control.Feedback type="invalid">
240                                         {t(errors.cancel_message)}
241                                 </Form.Control.Feedback>
242                         : null}
243                 </Form.Group>
244                 <Form.Group controlId="gg.invalid_solution_message">
245                         <Form.Label>{t('twitchBot.guessingGame.invalidSolutionMessage')}</Form.Label>
246                         <Form.Control
247                                 isInvalid={!!(touched.invalid_solution_message && errors.invalid_solution_message)}
248                                 name="invalid_solution_message"
249                                 onBlur={handleBlur}
250                                 onChange={handleChange}
251                                 type="text"
252                                 value={values.invalid_solution_message || ''}
253                         />
254                         {touched.invalid_solution_message && errors.invalid_solution_message ?
255                                 <Form.Control.Feedback type="invalid">
256                                         {t(errors.invalid_solution_message)}
257                                 </Form.Control.Feedback>
258                         : null}
259                 </Form.Group>
260                 <Form.Group controlId="gg.active_message">
261                         <Form.Label>{t('twitchBot.guessingGame.activeMessage')}</Form.Label>
262                         <Form.Control
263                                 isInvalid={!!(touched.active_message && errors.active_message)}
264                                 name="active_message"
265                                 onBlur={handleBlur}
266                                 onChange={handleChange}
267                                 type="text"
268                                 value={values.active_message || ''}
269                         />
270                         {touched.active_message && errors.active_message ?
271                                 <Form.Control.Feedback type="invalid">
272                                         {t(errors.active_message)}
273                                 </Form.Control.Feedback>
274                         : null}
275                 </Form.Group>
276                 <Form.Group controlId="gg.not_active_message">
277                         <Form.Label>{t('twitchBot.guessingGame.notActiveMessage')}</Form.Label>
278                         <Form.Control
279                                 isInvalid={!!(touched.not_active_message && errors.not_active_message)}
280                                 name="not_active_message"
281                                 onBlur={handleBlur}
282                                 onChange={handleChange}
283                                 type="text"
284                                 value={values.not_active_message || ''}
285                         />
286                         {touched.not_active_message && errors.not_active_message ?
287                                 <Form.Control.Feedback type="invalid">
288                                         {t(errors.not_active_message)}
289                                 </Form.Control.Feedback>
290                         : null}
291                 </Form.Group>
292                 <div className="button-bar mt-3">
293                         {onCancel ?
294                                 <Button onClick={onCancel} variant="secondary">
295                                         {t('button.cancel')}
296                                 </Button>
297                         : null}
298                         <Button type="submit" variant="primary">
299                                 {t('button.save')}
300                         </Button>
301                 </div>
302         </Form>;
303 };
304
305 GuessingSettingsForm.propTypes = {
306         errors: PropTypes.shape({
307                 active_message: PropTypes.string,
308                 cancel_message: PropTypes.string,
309                 close_winners_message: PropTypes.string,
310                 invalid_solution_message: PropTypes.string,
311                 leaderboard_type: PropTypes.string,
312                 name: PropTypes.string,
313                 no_winners_message: PropTypes.string,
314                 not_active_message: PropTypes.string,
315                 points_close_first: PropTypes.string,
316                 points_close_max: PropTypes.string,
317                 points_close_other: PropTypes.string,
318                 points_exact_first: PropTypes.string,
319                 points_exact_other: PropTypes.string,
320                 start_message: PropTypes.string,
321                 stop_message: PropTypes.string,
322                 winners_message: PropTypes.string,
323         }),
324         handleBlur: PropTypes.func,
325         handleChange: PropTypes.func,
326         handleSubmit: PropTypes.func,
327         name: PropTypes.string,
328         onCancel: PropTypes.func,
329         touched: PropTypes.shape({
330                 active_message: PropTypes.bool,
331                 cancel_message: PropTypes.bool,
332                 close_winners_message: PropTypes.bool,
333                 invalid_solution_message: PropTypes.bool,
334                 leaderboard_type: PropTypes.bool,
335                 name: PropTypes.bool,
336                 no_winners_message: PropTypes.bool,
337                 not_active_message: PropTypes.bool,
338                 points_close_first: PropTypes.bool,
339                 points_close_max: PropTypes.bool,
340                 points_close_other: PropTypes.bool,
341                 points_exact_first: PropTypes.bool,
342                 points_exact_other: PropTypes.bool,
343                 start_message: PropTypes.bool,
344                 stop_message: PropTypes.bool,
345                 winners_message: PropTypes.bool,
346         }),
347         values: PropTypes.shape({
348                 active_message: PropTypes.string,
349                 cancel_message: PropTypes.string,
350                 close_winners_message: PropTypes.string,
351                 invalid_solution_message: PropTypes.string,
352                 leaderboard_type: PropTypes.string,
353                 name: PropTypes.string,
354                 no_winners_message: PropTypes.string,
355                 not_active_message: PropTypes.string,
356                 points_close_first: PropTypes.number,
357                 points_close_max: PropTypes.number,
358                 points_close_other: PropTypes.number,
359                 points_exact_first: PropTypes.number,
360                 points_exact_other: PropTypes.number,
361                 start_message: PropTypes.string,
362                 stop_message: PropTypes.string,
363                 winners_message: PropTypes.string,
364         }),
365 };
366
367 export default withFormik({
368         displayName: 'GuessingSettingsForm',
369         enableReinitialize: true,
370         handleSubmit: async (values, actions) => {
371                 const { setErrors } = actions;
372                 const { onSubmit } = actions.props;
373                 try {
374                         await onSubmit(values);
375                 } catch (e) {
376                         if (e.response && e.response.data && e.response.data.errors) {
377                                 setErrors(laravelErrorsToFormik(e.response.data.errors));
378                         }
379                 }
380         },
381         mapPropsToValues: ({ name, settings }) => {
382                 const getNumericValue = (s, n, d) => s && Object.prototype.hasOwnProperty.call(s, n)
383                         ? s[n] : d;
384                 const getStringValue = (s, n, d) => s && Object.prototype.hasOwnProperty.call(s, n)
385                         ? s[n] : i18n.t(`twitchBot.guessingGame.default${d}`);
386                 return {
387                         active_message: getStringValue(settings, 'active_message', 'ActiveMessage'),
388                         cancel_message: getStringValue(settings, 'cancel_message', 'CancelMessage'),
389                         close_winners_message:
390                                 getStringValue(settings, 'close_winners_message', 'CloseWinnersMessage'),
391                         invalid_solution_message:
392                                 getStringValue(settings, 'invalid_solution_message', 'InvalidSolutionMessage'),
393                         leaderboard_type: (settings && settings.leaderboard_type) || 'all',
394                         name: name || '',
395                         no_winners_message: getStringValue(settings, 'no_winners_message', 'NoWinnersMessage'),
396                         not_active_message: getStringValue(settings, 'not_active_message', 'NotActiveMessage'),
397                         points_close_first: getNumericValue(settings, 'points_close_first', 1),
398                         points_close_max: getNumericValue(settings, 'points_close_max', 3),
399                         points_close_other: getNumericValue(settings, 'points_close_other', 1),
400                         points_exact_first: getNumericValue(settings, 'points_exact_first', 1),
401                         points_exact_other: getNumericValue(settings, 'points_exact_other', 1),
402                         start_message: getStringValue(settings, 'start_message', 'StartMessage'),
403                         stop_message: getStringValue(settings, 'stop_message', 'StopMessage'),
404                         winners_message: getStringValue(settings, 'winners_message', 'WinnersMessage'),
405                 };
406         },
407         validationSchema: yup.object().shape({
408                 active_message: yup.string(),
409                 cancel_message: yup.string(),
410                 close_winners_message: yup.string(),
411                 leaderboard_type: yup.string(),
412                 invalid_solution_message: yup.string(),
413                 name: yup.string().required(),
414                 no_winners_message: yup.string(),
415                 not_active_message: yup.string(),
416                 points_close_first: yup.number(),
417                 points_close_max: yup.number(),
418                 points_close_other: yup.number(),
419                 points_exact_first: yup.number(),
420                 points_exact_other: yup.number(),
421                 start_message: yup.string(),
422                 stop_message: yup.string(),
423                 winners_message: yup.string(),
424         }),
425 })(GuessingSettingsForm);