all repos — caroster @ 5bd547765b3767f6a06f03e35145ab9328a997dc

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