all repos — caroster @ 8348766d9bcad4a9f09713120ea7589e9fed3881

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

frontend/containers/NewTravelDialog/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 useActions from './useActions';
 17
 18const NewTravelDialog = ({open, toggle}) => {
 19  const {t} = useTranslation();
 20  const classes = useStyles();
 21  const event = useEventStore(s => s.event);
 22  const actions = useActions({event});
 23
 24  const dateMoment = useMemo(() => {
 25    if (!event?.date) return moment();
 26    else return moment(event.date);
 27  }, [event?.date]);
 28
 29  // States
 30  const [name, setName] = useState('');
 31  const [seats, setSeats] = useState(4);
 32  const [meeting, setMeeting] = useState('');
 33  const [date, setDate] = useState(dateMoment);
 34  const [time, setTime] = useState(dateMoment);
 35  const [phone, setPhone] = useState('');
 36  const [details, setDetails] = useState('');
 37  const canCreate = !!name && !!seats;
 38
 39  const onCreate = async e => {
 40    if (e.preventDefault) e.preventDefault();
 41
 42    const travel = {
 43      meeting,
 44      date,
 45      time,
 46      details,
 47      vehicle: {
 48        name,
 49        seats,
 50        phone_number: phone,
 51      },
 52    };
 53    await actions.createTravel(travel);
 54    toggle();
 55
 56    // Clear states
 57    setName('');
 58    setSeats(4);
 59    setMeeting('');
 60    setDate(moment());
 61    setPhone('');
 62    setDetails('');
 63  };
 64
 65  return (
 66    <Dialog
 67      fullWidth
 68      maxWidth="sm"
 69      open={open}
 70      onClose={toggle}
 71      TransitionComponent={Transition}
 72    >
 73      <form onSubmit={onCreate}>
 74        <DialogTitle>{t('travel.creation.title')}</DialogTitle>
 75        <DialogContent>
 76          <DatePicker
 77            label={t('travel.creation.date')}
 78            fullWidth
 79            helperText=" "
 80            value={date}
 81            onChange={setDate}
 82            format="DD/MM/YYYY"
 83            cancelLabel={t('generic.cancel')}
 84            autoFocus
 85            id="NewTravelDateTime"
 86          />
 87          <TimePicker
 88            label={t('travel.creation.time')}
 89            fullWidth
 90            helperText=" "
 91            value={time}
 92            onChange={setTime}
 93            cancelLabel={t('generic.cancel')}
 94            ampm={false}
 95            minutesStep={5}
 96            id="NewTravelTime"
 97          />
 98          <TextField
 99            label={t('travel.creation.name')}
100            fullWidth
101            helperText=" "
102            value={name}
103            onChange={e => setName(e.target.value)}
104            name="name"
105            id="NewTravelName"
106          />
107          <TextField
108            label={t('travel.creation.phone')}
109            fullWidth
110            helperText=" "
111            value={phone}
112            onChange={e => setPhone(e.target.value)}
113            name="phone"
114            id="NewTravelPhone"
115          />
116          <TextField
117            label={t('travel.creation.meeting')}
118            fullWidth
119            multiline
120            rowsMax={4}
121            inputProps={{maxLength: 250}}
122            helperText={`${meeting.length}/250`}
123            value={meeting}
124            onChange={e => setMeeting(e.target.value)}
125            name="meeting"
126            id="NewTravelMeeting"
127          />
128          <TextField
129            label={t('travel.creation.notes')}
130            fullWidth
131            multiline
132            rowsMax={4}
133            inputProps={{maxLength: 250}}
134            helperText={`${details.length}/250`}
135            value={details}
136            onChange={e => setDetails(e.target.value)}
137            name="details"
138            id="NewTravelDetails"
139          />
140          <div className={classes.slider}>
141            <Typography variant="caption">
142              {t('travel.creation.seats')}
143            </Typography>
144            <Slider
145              value={seats}
146              onChange={(e, value) => setSeats(value)}
147              step={1}
148              marks={MARKS}
149              min={1}
150              max={MARKS.length}
151              valueLabelDisplay="auto"
152              id="NewTravelSeats"
153            />
154          </div>
155        </DialogContent>
156        <DialogActions>
157          <Button
158            color="primary"
159            id="NewTravelCancel"
160            onClick={toggle}
161            tabIndex={-1}
162          >
163            {t('generic.cancel')}
164          </Button>
165          <Button
166            color="primary"
167            variant="contained"
168            type="submit"
169            disabled={!canCreate}
170            aria-disabled={!canCreate}
171            id="NewTravelSubmit"
172          >
173            {t('generic.create')}
174          </Button>
175        </DialogActions>
176      </form>
177    </Dialog>
178  );
179};
180
181const Transition = forwardRef(function Transition(props, ref) {
182  return <Slide direction="up" ref={ref} {...props} />;
183});
184
185const MARKS = [1, 2, 3, 4, 5, 6, 7, 8].map(value => ({
186  value,
187  label: value,
188}));
189
190const useStyles = makeStyles(theme => ({
191  slider: {
192    marginTop: theme.spacing(2),
193  },
194}));
195
196export default NewTravelDialog;