From ef7a52434e5b6fbfb9c31af0172861a9e2bb0351 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Fri, 4 Dec 2020 03:19:16 +0300 Subject: feat: validate form with yup --- src/containers/BsuFantomSection/EventForm.tsx | 49 +++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/containers/BsuFantomSection/EventForm.tsx b/src/containers/BsuFantomSection/EventForm.tsx index 09bb87b..9fc18b5 100644 --- a/src/containers/BsuFantomSection/EventForm.tsx +++ b/src/containers/BsuFantomSection/EventForm.tsx @@ -1,6 +1,9 @@ import React from 'react'; -import { Grid, TextField, Button } from '@material-ui/core'; +import _ from 'lodash'; +import cronstrue from 'cronstrue'; +import * as Yup from 'yup'; import { Formik, Form, Field } from 'formik'; +import { Grid, TextField, Button, Link } from '@material-ui/core'; import { post } from '../../requests'; import { Event } from '../../types'; @@ -15,7 +18,36 @@ interface Fields { conferenceId: string; } +const describeCrontab = (crontab: string) => { + try { + return cronstrue.toString(crontab); + } catch { + return false; + } +}; + +const validationSchema = Yup.object({ + name: Yup.string().required('This field is required'), + conferenceId: Yup.string().required('This field is required'), + attendanceId: Yup.string(), + schedule: Yup.string() + .required('This field is required') + .test('cron', 'Invalid crontab', value => !!describeCrontab(value || '')) +}); + const EventForm: React.FC = ({ mutate }) => { + + const describeSchedule = (schedule: string) => { + const description = describeCrontab(schedule); + if (description) return `Event will run ${_.lowerFirst(description)}`; + const link = crontab.guru; + return ( + <> + The schedule is invalid. Check out {link} for more help with cron scheduling. + + ); + }; + const handleSubmit = (fields: Fields, { resetForm }: any) => { const { name, schedule, attendanceId, conferenceId } = fields; @@ -41,9 +73,10 @@ const EventForm: React.FC = ({ mutate }) => { return ( - {({ values, errors, touched, isSubmitting }) => ( + {({ values, errors, touched, isValid }) => (
@@ -51,6 +84,8 @@ const EventForm: React.FC = ({ mutate }) => { name="name" label="Name" value={values.name} + error={touched.name && !!errors.name} + helperText={touched.name && errors.name} variant="outlined" fullWidth required @@ -62,6 +97,10 @@ const EventForm: React.FC = ({ mutate }) => { name="schedule" label="Schedule" value={values.schedule} + error={touched.schedule && !!errors.schedule} + helperText={ + (touched.schedule && errors.schedule) || "Should be a valid crontab, for example: 30 12 * * Mon" + } variant="outlined" fullWidth required @@ -73,6 +112,8 @@ const EventForm: React.FC = ({ mutate }) => { name="conferenceId" label="Conference ID" value={values.conferenceId} + error={touched.conferenceId && !!errors.conferenceId} + helperText={touched.conferenceId && errors.conferenceId} variant="outlined" fullWidth required @@ -89,9 +130,13 @@ const EventForm: React.FC = ({ mutate }) => { as={TextField} /> + + {describeSchedule(values.schedule)} +