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;