all repos — caroster @ ac7c129ce3a5f103886fee0c738d5aab39af722a

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

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

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