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;