Skip to content

Instantly share code, notes, and snippets.

@hanishi
Last active October 3, 2020 06:41
Show Gist options
  • Save hanishi/4ac7ebc90da4d0dcb799d26e6b72dda3 to your computer and use it in GitHub Desktop.
Save hanishi/4ac7ebc90da4d0dcb799d26e6b72dda3 to your computer and use it in GitHub Desktop.
import React, {useState} from 'react';
import * as Yup from 'yup';
import {Formik} from 'formik';
import {Box, Grid, Switch, TextField, Typography} from '@material-ui/core';
import {Alert} from '@material-ui/lab';
import wait from 'src/utils/wait';
import {isEqual} from 'lodash'
const SubmitListener = (
{formik}
) => {
const [lastValues, updateState] = React.useState(formik.values);
React.useEffect(() => {
const valuesEqualLastValues = isEqual(lastValues, formik.values);
const valuesEqualInitialValues =
formik.values === formik.initialValues;
if (!valuesEqualLastValues) {
updateState(formik.values);
}
if (!valuesEqualLastValues && !valuesEqualInitialValues) {
formik.submitForm().catch(error => {
console.warn(error);
formik.setValues(lastValues, false);
}
);
}
}, [
lastValues,
formik.values,
formik.initialValues,
]);
return null;
};
const Criteria = ({id, initialValue, activate}) => {
const [isAlertVisible, setAlertVisible] = useState(false);
return (
<Formik
initialValues={initialValue}
validationSchema={Yup.object().shape({
numberOfActiveAds: Yup.number().min(1, 'must be at least 1'),
daysOfInterContestInterval: Yup.number().min(1, 'must be at least 1 day'),
daysToRunContest: Yup.number().min(1, 'must be at least 1 day'),
})}
onSubmit={async (values) => {
try {
// NOTE: Make API request
await wait(1000);
activate(values.active);
console.log(JSON.stringify(values));
} catch (err) {
setAlertVisible(true);
throw err
}
}}
>
{(
formik
) => (
<React.Fragment>
{isAlertVisible && (
<Box mb={3}>
<Alert
onClose={() => setAlertVisible(false)}
severity="info"
>
This is an info alert - check it out!
</Alert>
</Box>
)}
{
<React.Fragment>
<SubmitListener formik={formik}/>
<Grid container spacing={2}>
<Grid item xs={12} md={4}>
<TextField
error={Boolean(formik.touched.daysOfInterContestInterval && formik.errors.daysOfInterContestInterval)}
fullWidth
helperText={formik.touched.daysOfInterContestInterval && formik.errors.daysOfInterContestInterval}
label="Intercontest Interval"
name="daysOfInterContestInterval"
onBlur={formik.handleBlur}
onChange={formik.handleChange}
value={formik.values.daysOfInterContestInterval}
variant="outlined"
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField
error={Boolean(formik.touched.daysToRunContest && formik.errors.daysToRunContest)}
fullWidth
helperText={formik.touched.daysToRunContest && formik.errors.daysToRunContest}
label="Contest Interval"
name="daysToRunContest"
onBlur={formik.handleBlur}
onChange={formik.handleChange}
value={formik.values.daysToRunContest}
variant="outlined"
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField
error={Boolean(formik.touched.numberOfActiveAds && formik.errors.numberOfActiveAds)}
fullWidth
helperText={formik.touched.numberOfActiveAds && formik.errors.numberOfActiveAds}
label="Ads activation"
name="numberOfActiveAds"
onBlur={formik.handleBlur}
onChange={formik.handleChange}
value={formik.values.numberOfActiveAds}
variant="outlined"
/>
</Grid>
</Grid>
<Grid container direction="column" alignItems="flex-end" spacing={3}>
<Grid item xs>
<Typography component="div">
<Grid component="label" container alignItems="center" spacing={1}>
<Grid item>Paused</Grid>
<Grid item>
<Switch checked={formik.values.active} onChange={(e) => {
Object.keys(formik.errors).length === 0 && formik.handleChange(e);
}} name="active"/>
</Grid>
<Grid item>Active</Grid>
</Grid>
</Typography>
</Grid>
</Grid>
</React.Fragment>
}
</React.Fragment>
)}
</Formik>
);
};
export default Criteria;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment