all repos — caroster @ 03b6a54cf07ad4b1011d2387873b2fe91faf99ce

[Octree] Group carpool to your event https://caroster.io

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;