import {useEffect, useMemo, useRef, useState} from 'react'; import {makeStyles} from '@material-ui/core/styles'; import Container from '@material-ui/core/Container'; import Slider from 'react-slick'; import {useTranslation} from 'react-i18next'; import { Travel as TravelType, useUpdateTravelMutation, } from '../../generated/graphql'; import useEventStore from '../../stores/useEventStore'; import useTourStore from '../../stores/useTourStore'; import useToastStore from '../../stores/useToastStore'; import useProfile from '../../hooks/useProfile'; import useAddToEvents from '../../hooks/useAddToEvents'; import { AddPassengerToTravel, AddPassengerToWaitingList, } from '../NewPassengerDialog'; import WaitingList from '../WaitingList'; import Travel from '../Travel'; import AddTravel from './AddTravel'; import sliderSettings from './_SliderSettings'; import usePassengersActions from '../../hooks/usePassengersActions'; interface NewPassengerDialogContext { addSelf: boolean; } interface Props { toggleNewTravel: () => void; } const TravelColumns = (props: Props) => { const event = useEventStore(s => s.event); const {travels = []} = event || {}; const slider = useRef(null); const {t} = useTranslation(); const tourStep = useTourStore(s => s.step); const addToast = useToastStore(s => s.addToast); const [updateTravel] = useUpdateTravelMutation(); const {addToEvent} = useAddToEvents(); const {user} = useProfile(); const classes = useStyles(); const [newPassengerTravelContext, toggleNewPassengerToTravel] = useState<{ travel: TravelType; } | null>(null); const [addPassengerToWaitingListContext, toggleNewPassengerToWaitingList] = useState(null); const {addPassengerToTravel} = usePassengersActions(); const canAddSelf = useMemo(() => { const isInWaitingList = event?.waitingList?.some( passenger => passenger.user?.id === user.id ); const isInTravel = event?.travels.some(travel => travel.passengers.some(passenger => passenger.user?.id === user.id) ); return !(isInWaitingList || isInTravel); }, [event, user]); const addSelfToTravel = async (travel: TravelType) => { const passenger = { user: user, email: user.email, name: user.username, }; return addPassengerToTravel({ passenger, travel, onSucceed: () => { addToEvent(event.id); addToast(t('passenger.success.added_self_to_car')); }, }); }; // On tour step changes : component update useEffect(() => { onTourChange(slider.current); }, [tourStep]); return (
() => toggleNewPassengerToWaitingList({addSelf})} /> {travels ?.slice() .sort(sortTravels) .map(travel => ( () => { if (addSelf) { return addSelfToTravel(travel); } else { return toggleNewPassengerToTravel({travel}); } }} /> ))}
{!!newPassengerTravelContext && ( toggleNewPassengerToTravel(null)} travel={newPassengerTravelContext.travel} /> )} {!!addPassengerToWaitingListContext && ( toggleNewPassengerToWaitingList(null)} addSelf={addPassengerToWaitingListContext.addSelf} /> )}
); }; const onTourChange = slider => { const {prev, step, isCreator} = useTourStore.getState(); const fromTo = (step1: number, step2: number) => prev === step1 && step === step2; if (isCreator) { if (fromTo(2, 3) || fromTo(4, 3)) slider?.slickGoTo(0, true); } else if (fromTo(0, 1)) slider?.slickGoTo(0, true); }; const sortTravels = (a: TravelType, b: TravelType) => { if (!b) return 1; const dateA = new Date(a.departure).getTime(); const dateB = new Date(b.departure).getTime(); if (dateA === dateB) return new Date(a.created_at).getTime() - new Date(b.created_at).getTime(); else return dateA - dateB; }; const useStyles = makeStyles(theme => ({ container: { minHeight: '100vh', paddingTop: theme.mixins.toolbar.minHeight, paddingLeft: theme.spacing(6), paddingRight: theme.spacing(6), [theme.breakpoints.down('sm')]: { paddingLeft: theme.spacing(), paddingRight: theme.spacing(), }, display: 'flex', flexDirection: 'column', overflowX: 'hidden', overflowY: 'auto', }, dots: { height: 32, overflow: 'auto', '& overflow': '-moz-scrollbars-none', '-ms-overflow-style': 'none', '&::-webkit-scrollbar': { height: '0 !important', }, '& .slick-dots': { position: 'static', '& li': { display: 'block', }, }, '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': { color: theme.palette.primary.main, }, }, slider: { flexGrow: 1, height: 1, '& .slick-slider': { height: '100%', '& .slick-list': { overflow: 'visible', }, cursor: 'grab', }, }, slide: { padding: theme.spacing(1), marginBottom: theme.spacing(12), outline: 'none', '& > *': { cursor: 'default', }, }, })); export default TravelColumns;