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