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
85 size="small"
86 color="primary"
87 className={classes.editBtn}
88 onClick={onEdit}
89 >
90 {isEditing ? <Icon>check</Icon> : <Icon>edit</Icon>}
91 </IconButton>
92 <Typography variant="h5">{t('passenger.title')}</Typography>
93 </div>
94 <Divider />
95 <PassengersList
96 hideEmpty
97 places={50}
98 passengers={passengers}
99 addPassenger={addPassenger}
100 onClick={onClick}
101 icon={isEditing ? 'close' : 'chevron_right'}
102 />
103 </Paper>
104 <RemoveDialog
105 text={
106 <Trans
107 i18nKey="passenger.actions.remove_alert"
108 values={{name: passengers ? passengers[removing] : null}}
109 components={{italic: <i />, bold: <strong />}}
110 />
111 }
112 open={removing !== null}
113 onClose={() => setRemoving(null)}
114 onRemove={() => removePassenger(removing)}
115 />
116 <CarDialog
117 open={adding !== null}
118 onClose={() => setAdding(null)}
119 onSelect={selectCar}
120 />
121 </>
122 );
123};
124
125const useStyles = makeStyles(theme => ({
126 root: {
127 position: 'relative',
128 },
129 header: {
130 padding: theme.spacing(2),
131 },
132 editBtn: {
133 position: 'absolute',
134 top: 0,
135 right: 0,
136 margin: theme.spacing(1),
137 zIndex: theme.zIndex.speedDial,
138 },
139}));
140
141export default WaitingList;