import React, { useReducer, useState, useEffect, useMemo, useCallback, } from 'react'; import Typography from '@material-ui/core/Typography'; import IconButton from '@material-ui/core/IconButton'; import Icon from '@material-ui/core/Icon'; import Paper from '@material-ui/core/Paper'; import Divider from '@material-ui/core/Divider'; import {makeStyles} from '@material-ui/core/styles'; import {Trans, useTranslation} from 'react-i18next'; import {useStrapi} from 'strapi-react-context'; import {useEvent} from '../../contexts/Event'; import {useToast} from '../../contexts/Toast'; import PassengersList from '../PassengersList'; import RemoveDialog from '../RemoveDialog'; import CarDialog from './CarDialog'; const sortCars = (a, b) => { const dateA = new Date(a.departure).getTime(); const dateB = new Date(b.departure).getTime(); if (dateA === dateB) return new Date(a.createdAt) - new Date(b.createdAt); else return dateA - dateB; }; const WaitingList = ({car}) => { const classes = useStyles(); const {t} = useTranslation(); const {event} = useEvent(); const {addToast} = useToast(); const strapi = useStrapi(); const [passengers, setPassengers] = useState(event.waiting_list); const [isEditing, toggleEditing] = useReducer(i => !i, false); const [removing, setRemoving] = useState(null); const [adding, setAdding] = useState(null); const cars = useMemo( () => strapi.stores.cars ?.filter(car => car?.event?.id === event?.id) .sort(sortCars), [strapi.stores.cars, event] ); const availability = useMemo(() => { if (!cars) return; return cars.reduce((count, {seats, passengers = []}) => { return count + seats - passengers.length; }, 0); }, [cars]); useEffect(() => { setPassengers(event.waiting_list); }, [event.waiting_list]); const saveWaitingList = useCallback( async (waitingList, i18nError) => { try { await strapi.services.events.update(event.id, { waiting_list: waitingList, }); } catch (error) { console.error(error); addToast(t(i18nError)); } }, [event] ); const addPassenger = useCallback( async passenger => { return saveWaitingList( [...(event.waiting_list || []), passenger], 'passenger.errors.cant_add_passenger' ); }, [saveWaitingList] ); const removePassenger = useCallback( index => { const updatedPassagers = passengers.filter((_, i) => i !== index); setPassengers(updatedPassagers); return saveWaitingList( updatedPassagers, 'passenger.errors.cant_remove_passenger' ); }, [passengers, saveWaitingList] ); const savePassengers = useCallback( async () => saveWaitingList(passengers, 'passenger.errors.cant_save_passengers'), [passengers, saveWaitingList] ); const selectCar = async car => { try { await strapi.services.cars.update(car.id, { passengers: [...(car.passengers || []), passengers[adding]], }); await strapi.services.events.update(event.id, { waiting_list: event.waiting_list.filter((_, i) => i !== adding), }); } catch (error) { console.error(error); addToast(t('passenger.errors.cant_select_car')); } setAdding(null); }; const onEdit = () => { if (isEditing) savePassengers(); toggleEditing(); }; return ( <>
{isEditing ? check : edit} {t('passenger.title')} {t('passenger.availability.seats', {count: availability})}
{isEditing ? ( ) : ( )}
, bold: }} /> } open={removing !== null} onClose={() => setRemoving(null)} onRemove={async () => { removePassenger(removing); savePassengers(); }} /> setAdding(null)} onSelect={selectCar} /> ); }; const useStyles = makeStyles(theme => ({ root: { position: 'relative', }, header: { padding: theme.spacing(2), }, editBtn: { position: 'absolute', top: 0, right: 0, margin: theme.spacing(1), zIndex: theme.zIndex.speedDial, }, })); export default WaitingList;