app/src/containers/WaitingList/index.js (view raw)
1import React, {useReducer, useState, useEffect} from 'react';
2import Typography from '@material-ui/core/Typography';
3import IconButton from '@material-ui/core/IconButton';
4import Icon from '@material-ui/core/Icon';
5import Paper from '@material-ui/core/Paper';
6import Divider from '@material-ui/core/Divider';
7import {makeStyles} from '@material-ui/core/styles';
8import {Trans, useTranslation} from 'react-i18next';
9import {useStrapi} from 'strapi-react-context';
10import {useEvent} from '../../contexts/Event';
11import {useToast} from '../../contexts/Toast';
12import PassengersList from '../PassengersList';
13import RemoveDialog from '../RemoveDialog';
14import CarDialog from './CarDialog';
15
16const WaitingList = ({car}) => {
17 const classes = useStyles();
18 const {t} = useTranslation();
19 const {event} = useEvent();
20 const {addToast} = useToast();
21 const strapi = useStrapi();
22 const [passengers, setPassengers] = useState(event.waiting_list);
23 const [isEditing, toggleEditing] = useReducer(i => !i, false);
24 const [removing, setRemoving] = useState(null);
25 const [adding, setAdding] = useState(null);
26
27 useEffect(() => {
28 setPassengers(event.waiting_list);
29 }, [event.waiting_list]);
30
31 const addPassenger = async passenger => {
32 try {
33 await strapi.services.events.update(event.id, {
34 waiting_list: [...(event.waiting_list || []), passenger],
35 });
36 } catch (error) {
37 console.error(error);
38 addToast(t('passenger.errors.cant_add_passenger'));
39 }
40 };
41
42 const removePassenger = index => {
43 setPassengers(passengers.filter((_, i) => i !== index));
44 };
45
46 const savePassengers = async () => {
47 try {
48 await strapi.services.events.update(event.id, {waiting_list: passengers});
49 } catch (error) {
50 console.error(error);
51 addToast(t('passenger.errors.cant_save_passengers'));
52 }
53 };
54
55 const selectCar = async car => {
56 try {
57 await strapi.services.cars.update(car.id, {
58 passengers: [...(car.passengers || []), passengers[adding]],
59 });
60 await strapi.services.events.update(event.id, {
61 waiting_list: event.waiting_list.filter((_, i) => i !== adding),
62 });
63 } catch (error) {
64 console.error(error);
65 addToast(t('passenger.errors.cant_select_car'));
66 }
67 setAdding(null);
68 };
69
70 const onEdit = () => {
71 if (isEditing) savePassengers();
72 toggleEditing();
73 };
74
75 const onClick = index => {
76 if (isEditing) setRemoving(index);
77 else setAdding(index);
78 };
79
80 return (
81 <>
82 <Paper className={classes.root}>
83 <div className={classes.header}>
84 <IconButton className={classes.editBtn} onClick={onEdit}>
85 {isEditing ? <Icon>check</Icon> : <Icon>edit</Icon>}
86 </IconButton>
87 <Typography variant="h5">{t('passenger.title')}</Typography>
88 </div>
89 <Divider />
90 <PassengersList
91 hideEmpty
92 places={50}
93 passengers={passengers}
94 addPassenger={addPassenger}
95 onClick={onClick}
96 icon={isEditing ? 'close' : 'chevron_right'}
97 />
98 </Paper>
99 <RemoveDialog
100 text={
101 <Trans
102 i18nKey="passenger.actions.remove_alert"
103 values={{name: passengers ? passengers[removing] : null}}
104 components={{italic: <i />, bold: <strong />}}
105 />
106 }
107 open={removing !== null}
108 onClose={() => setRemoving(null)}
109 onRemove={() => removePassenger(removing)}
110 />
111 <CarDialog
112 open={adding !== null}
113 onClose={() => setAdding(null)}
114 onSelect={selectCar}
115 />
116 </>
117 );
118};
119
120const useStyles = makeStyles(theme => ({
121 root: {
122 position: 'relative',
123 },
124 header: {
125 padding: theme.spacing(2),
126 },
127 editBtn: {
128 position: 'absolute',
129 top: 0,
130 right: 0,
131 zIndex: theme.zIndex.speedDial,
132 },
133}));
134
135export default WaitingList;