app/src/containers/Car/HeaderEditing.js (view raw)
1import React, {useState, useReducer} from 'react';
2import Typography from '@material-ui/core/Typography';
3import IconButton from '@material-ui/core/IconButton';
4import Icon from '@material-ui/core/Icon';
5import Button from '@material-ui/core/Button';
6import moment from 'moment';
7import {makeStyles} from '@material-ui/core/styles';
8import {DateTimePicker} from '@material-ui/pickers';
9import {useTranslation} from 'react-i18next';
10import TextField from '@material-ui/core/TextField';
11import Slider from '@material-ui/core/Slider';
12import {useStrapi} from 'strapi-react-context';
13import {useToast} from '../../contexts/Toast';
14import {useEvent} from '../../contexts/Event';
15import RemoveDialog from './RemoveDialog';
16
17const HeaderEditing = ({car, toggleEditing}) => {
18 const classes = useStyles();
19 const {t} = useTranslation();
20 const strapi = useStrapi();
21 const {event} = useEvent();
22 const {addToast} = useToast();
23 const [removing, toggleRemoving] = useReducer(i => !i, false);
24
25 // States
26 const [name, setName] = useState(car?.name ?? '');
27 const [seats, setSeats] = useState(car?.seats ?? 4);
28 const [meeting, setMeeting] = useState(car?.meeting ?? '');
29 const [date, setDate] = useState(
30 car?.departure ? moment(car.departure) : moment()
31 );
32 const [phone, setPhone] = useState(car?.phone_number ?? '');
33 const [details, setDetails] = useState(car?.details ?? '');
34
35 const onSave = async () => {
36 try {
37 // If new seats count is under current passengers count, put excedent in event waiting list
38 if (!!car.passengers && car.passengers.length > seats) {
39 const lostPassengers = car.passengers.slice(seats);
40 if (lostPassengers.length > 0)
41 await strapi.services.events.update(event.id, {
42 waiting_list: [...(event.waiting_list ?? []), ...lostPassengers],
43 });
44 }
45 // Update car
46 await strapi.services.cars.update(car.id, {
47 name,
48 seats,
49 meeting,
50 departure: date.toISOString(),
51 phone_number: phone,
52 details,
53 passengers: car.passengers ? car.passengers.slice(0, seats) : [],
54 });
55 toggleEditing();
56 } catch (error) {
57 console.error(error);
58 addToast('car.errors.cant_update');
59 }
60 };
61
62 const onRemove = async () => {
63 try {
64 // Put passengers in event waiting list (if any)
65 if (Array.isArray(car?.passengers) && car.passengers.length > 0)
66 await strapi.services.events.update(event.id, {
67 waiting_list: [...(event.waiting_list ?? []), ...car.passengers],
68 });
69 // Remove car
70 await strapi.services.cars.remove(car.id);
71 addToast(t('car.actions.removed'));
72 toggleEditing();
73 } catch (error) {
74 console.error(error);
75 addToast('car.errors.cant_remove');
76 }
77 };
78
79 return (
80 <div className={classes.header}>
81 <IconButton className={classes.editBtn} onClick={onSave}>
82 <Icon>done</Icon>
83 </IconButton>
84 <DateTimePicker
85 label={t('event.creation.date')}
86 value={date}
87 onChange={setDate}
88 className={classes.textField}
89 fullWidth
90 format="LLLL"
91 disablePast
92 id="UpdateCarDateTime"
93 name="date"
94 />
95 <TextField
96 className={classes.textField}
97 label={t('car.creation.name')}
98 fullWidth
99 autoFocus
100 margin="dense"
101 value={name}
102 onChange={e => setName(e.target.value)}
103 id="UpdateCarName"
104 name="name"
105 />
106 <TextField
107 className={classes.textField}
108 label={t('car.creation.phone')}
109 fullWidth
110 autoFocus
111 margin="dense"
112 value={phone}
113 onChange={e => setPhone(e.target.value)}
114 id="UpdateCarPhone"
115 name="phone"
116 />
117 <TextField
118 className={classes.textField}
119 label={t('car.creation.meeting')}
120 fullWidth
121 margin="dense"
122 multiline
123 rows={2}
124 value={meeting}
125 onChange={e => setMeeting(e.target.value)}
126 id="UpdateCarMeeting"
127 name="meeting"
128 />
129 <TextField
130 className={classes.textField}
131 label={t('car.creation.notes')}
132 fullWidth
133 margin="dense"
134 multiline
135 rows={2}
136 value={details}
137 onChange={e => setDetails(e.target.value)}
138 id="UpdateCarDetails"
139 name="details"
140 />
141 <div className={classes.slider}>
142 <Typography variant="caption">{t('car.creation.seats')}</Typography>
143 <Slider
144 value={seats}
145 onChange={(e, value) => setSeats(value)}
146 step={1}
147 marks={[1, 2, 3, 4, 5, 6, 7, 8].map(value => ({
148 value,
149 label: value,
150 }))}
151 min={1}
152 max={8}
153 valueLabelDisplay="auto"
154 />
155 </div>
156 <div className={classes.actions}>
157 <Button color="secondary" variant="outlined" onClick={toggleRemoving}>
158 {t('car.actions.remove')}
159 </Button>
160 </div>
161 <RemoveDialog
162 open={removing}
163 toggle={toggleRemoving}
164 onRemove={onRemove}
165 />
166 </div>
167 );
168};
169
170const useStyles = makeStyles(theme => ({
171 header: {padding: theme.spacing(2)},
172 editBtn: {
173 position: 'absolute',
174 top: 0,
175 right: 0,
176 zIndex: theme.zIndex.speedDial,
177 },
178 section: {
179 marginTop: theme.spacing(2),
180 },
181 slider: {
182 marginTop: theme.spacing(2),
183 },
184 actions: {
185 display: 'flex',
186 justifyContent: 'center',
187 margin: theme.spacing(2, 0),
188 },
189}));
190
191export default HeaderEditing;