import {useReducer, useState, useMemo, useCallback} from 'react'; import router from 'next/dist/client/router'; import useMediaQuery from '@mui/material/useMediaQuery'; import Container from '@mui/material/Container'; import TuneIcon from '@mui/icons-material/Tune'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import Icon from '@mui/material/Icon'; import Paper from '@mui/material/Paper'; import Divider from '@mui/material/Divider'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined'; import {useTheme} from '@mui/material/styles'; import {Trans, useTranslation} from 'next-i18next'; import useToastStore from '../../stores/useToastStore'; import useEventStore from '../../stores/useEventStore'; import usePassengersActions from '../../hooks/usePassengersActions'; import RemoveDialog from '../RemoveDialog'; import AddPassengerButtons from '../AddPassengerButtons'; import AssignButton from './AssignButton'; import PassengersList from '../PassengersList'; interface Props { canAddSelf: boolean; registered: boolean; onAddSelf: () => void; onAddOther: () => void; } const WaitingList = (props: Props) => { const {canAddSelf, registered} = props; const {t} = useTranslation(); const event = useEventStore(s => s.event); const theme = useTheme(); const mobile = useMediaQuery(theme.breakpoints.down('md')); const addToast = useToastStore(s => s.addToast); const [isEditing, toggleEditing] = useReducer(i => !i, false); const [removingPassenger, setRemovingPassenger] = useState(null); const travels = useMemo( () => event?.travels?.data?.length > 0 ? event?.travels?.data.slice().sort(sortTravels) : [], [event?.travels?.data] ); const {removePassenger} = usePassengersActions(); const availability = useMemo(() => { if (!travels) return; return travels.reduce((count, {attributes: {seats, passengers}}) => { if (!seats) return 0; else if (!passengers) return count + seats; return count + seats - passengers?.data?.length; }, 0); }, [travels]); const removePassengerCallback = useCallback(removePassenger, [ event, removePassenger, ]); const onClickPassenger = useCallback( (passengerId: string) => { const selectedPassenger = event?.waitingPassengers?.data.find( item => item.id === passengerId ); if (isEditing) setRemovingPassenger(selectedPassenger); else router.push(`/e/${event.uuid}/assign/${selectedPassenger.id}`); }, [isEditing, event] ); const onRemove = async () => { try { await removePassengerCallback(removingPassenger.id); addToast(t('passenger.deleted')); } catch (error) { console.error(error); addToast(t('passenger.errors.cant_remove_passenger')); } }; return ( {isEditing ? check : } {t('passenger.title')} {t('passenger.availability.seats', {count: availability})} {event?.waitingPassengers?.data?.length > 0 && ( isEditing ? ( ) : ( onClickPassenger(passenger.id)} /> ) } /> )} , bold: }} /> } open={!!removingPassenger} onClose={() => setRemovingPassenger(null)} onRemove={onRemove} /> ); }; const sortTravels = (a, b) => { const dateA = new Date(a.departureDate).getTime(); const dateB = new Date(b.departureDate).getTime(); if (dateA === dateB) return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(); else return dateA - dateB; }; export default WaitingList;