all repos — caroster @ fbbba765aecc6071265d67442cb91027ab465530

[Octree] Group carpool to your event https://caroster.io

frontend/containers/NewCarDialog/index.tsx (view raw)

  1import {useState, forwardRef, useMemo} from 'react';
  2import Dialog from '@material-ui/core/Dialog';
  3import DialogActions from '@material-ui/core/DialogActions';
  4import DialogContent from '@material-ui/core/DialogContent';
  5import DialogTitle from '@material-ui/core/DialogTitle';
  6import Button from '@material-ui/core/Button';
  7import Slide from '@material-ui/core/Slide';
  8import TextField from '@material-ui/core/TextField';
  9import Slider from '@material-ui/core/Slider';
 10import Typography from '@material-ui/core/Typography';
 11import {makeStyles} from '@material-ui/core/styles';
 12import moment from 'moment';
 13import {useTranslation} from 'react-i18next';
 14import useAddToEvents from '../../hooks/useAddToEvents';
 15import useEventStore from '../../stores/useEventStore';
 16import useToastsStore from '../../stores/useToastStore';
 17import {useCreateCarMutation} from '../../generated/graphql';
 18
 19const NewCarDialog = ({open, toggle}) => {
 20  const {t} = useTranslation();
 21  const classes = useStyles();
 22  const addToast = useToastsStore(s => s.addToast);
 23  const {addToEvent} = useAddToEvents();
 24  const event = useEventStore(s => s.event);
 25  const [createCar] = useCreateCarMutation({refetchQueries: ['eventByUUID']});
 26  const dateMoment = useMemo(() => {
 27    if (!event?.date) return moment();
 28    else return moment(event.date);
 29  }, [event?.date]);
 30
 31  // States
 32  const [name, setName] = useState('');
 33  const [seats, setSeats] = useState(4);
 34  const [meeting, setMeeting] = useState('');
 35  const [date, setDate] = useState(dateMoment.format('YYYY-MM-DD'));
 36  const [time, setTime] = useState(dateMoment.format('HH:mm'));
 37  const [phone, setPhone] = useState('');
 38  const [details, setDetails] = useState('');
 39  const canCreate = !!name && !!seats;
 40
 41  const onCreate = async e => {
 42    if (e.preventDefault) e.preventDefault();
 43    try {
 44      const departure = moment(
 45        `${date} ${time}`,
 46        'YYYY-MM-DD HH:mm'
 47      ).toISOString();
 48      await createCar({
 49        variables: {
 50          car: {
 51            name,
 52            seats,
 53            meeting,
 54            departure,
 55            phone_number: phone,
 56            details,
 57            event: event.id,
 58          },
 59        },
 60      });
 61      addToEvent(event.id);
 62      addToast(t('car.creation.created'));
 63      toggle();
 64
 65      // Clear states
 66      setName('');
 67      setSeats(4);
 68      setMeeting('');
 69      setDate(moment().format('YYYY-MM-DD'));
 70      setPhone('');
 71      setDetails('');
 72    } catch (error) {
 73      console.error(error);
 74      addToast(t('car.errors.cant_create'));
 75    }
 76    return false;
 77  };
 78
 79  return (
 80    <Dialog
 81      fullWidth
 82      maxWidth="sm"
 83      open={open}
 84      onClose={toggle}
 85      TransitionComponent={Transition}
 86    >
 87      <form onSubmit={onCreate}>
 88        <DialogTitle>{t('car.creation.title')}</DialogTitle>
 89        <DialogContent>
 90          <TextField
 91            label={t('car.creation.name')}
 92            value={name}
 93            onChange={e => setName(e.target.value)}
 94            fullWidth
 95            autoFocus
 96            id="NewCarName"
 97            name="name"
 98          />
 99          <TextField
100            label={t('car.creation.date')}
101            value={date}
102            onChange={e => setDate(e.target.value)}
103            className={classes.picker}
104            fullWidth
105            id="NewCarDateTime"
106            name="date"
107            type="date"
108            InputLabelProps={{
109              shrink: true,
110            }}
111          />
112          <TextField
113            label={t('car.creation.time')}
114            value={time}
115            onChange={e => setTime(e.target.value)}
116            className={classes.picker}
117            fullWidth
118            id="NewCarTime"
119            name="time"
120            type="time"
121            InputLabelProps={{
122              shrink: true,
123            }}
124          />
125          <Typography variant="caption">{t('car.creation.seats')}</Typography>
126          <Slider
127            value={seats}
128            onChange={(e, value) => setSeats(value)}
129            step={1}
130            min={1}
131            max={MARKS.length}
132            marks={MARKS}
133            valueLabelDisplay="auto"
134          />
135          <TextField
136            label={t('car.creation.meeting')}
137            value={meeting}
138            onChange={e => setMeeting(e.target.value)}
139            fullWidth
140            margin="dense"
141            id="NewCarMeeting"
142            name="meeting"
143          />
144          <TextField
145            label={t('car.creation.phone')}
146            value={phone}
147            onChange={e => setPhone(e.target.value)}
148            fullWidth
149            margin="dense"
150            id="NewCarPhone"
151            name="phone"
152          />
153          <TextField
154            label={t('car.creation.notes')}
155            value={details}
156            onChange={e => setDetails(e.target.value)}
157            fullWidth
158            margin="dense"
159            inputProps={{maxLength: 250}}
160            helperText={`${details.length}/250`}
161            multiline
162            rows={4}
163            id="NewCarDetails"
164            name="details"
165          />
166        </DialogContent>
167        <DialogActions>
168          <Button
169            color="primary"
170            id="NewCarCancel"
171            onClick={toggle}
172            tabIndex={-1}
173          >
174            {t('generic.cancel')}
175          </Button>
176          <Button
177            color="primary"
178            variant="contained"
179            type="submit"
180            disabled={!canCreate}
181            aria-disabled={!canCreate}
182            id="NewCarSubmit"
183          >
184            {t('generic.create')}
185          </Button>
186        </DialogActions>
187      </form>
188    </Dialog>
189  );
190};
191
192const Transition = forwardRef(function Transition(props, ref) {
193  return <Slide direction="up" ref={ref} {...props} />;
194});
195
196const MARKS = [1, 2, 3, 4, 5, 6, 7, 8].map(value => ({
197  value,
198  label: value,
199}));
200
201const useStyles = makeStyles(theme => ({
202  picker: {
203    marginTop: theme.spacing(3),
204    marginBottom: theme.spacing(3),
205  },
206}));
207
208export default NewCarDialog;