all repos — caroster @ 5d5e4ac4d7656640903b1bbc356776619411befb

[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
 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;