frontend/containers/Travel/index.tsx (view raw)
1import {useMemo, useReducer, useState} from 'react';
2import Divider from '@mui/material/Divider';
3import Paper from '@mui/material/Paper';
4import {useTheme} from '@mui/styles';
5import HeaderEditing from './HeaderEditing';
6import Header from './Header';
7import RequestTripModal from './RequestTripModal';
8import PassengersList from '../PassengersList';
9import AddPassengerButtons from '../AddPassengerButtons';
10import useProfile from '../../hooks/useProfile';
11import usePermissions from '../../hooks/usePermissions';
12import useMapStore from '../../stores/useMapStore';
13import useEventStore from '../../stores/useEventStore';
14import {PassengerEntity, TravelEntity} from '../../generated/graphql';
15import DrawerPassenger from '../DrawerPassenger';
16import PassengerActions from './PassengerActions';
17
18interface Props {
19 travel: TravelEntity;
20 onAddSelf: () => void;
21 onAddOther: () => void;
22}
23
24const Travel = (props: Props) => {
25 const {travel} = props;
26 const isCarosterPlus = useEventStore(s =>
27 s.event.enabled_modules?.includes('caroster-plus')
28 );
29 const {
30 userPermissions: {canSeePassengerDetails},
31 } = usePermissions();
32 const theme = useTheme();
33 const [isEditing, toggleEditing] = useReducer(i => !i, false);
34 const [requestTripModalOpen, toggleRequestTripModal] = useReducer(
35 i => !i,
36 false
37 );
38 const {userId, connected} = useProfile();
39 const focusedTravel = useMapStore(s => s.focusedTravel);
40 const focused = focusedTravel === travel.id;
41 const disableNewPassengers =
42 travel.attributes.passengers?.data?.length >= travel.attributes.seats;
43
44 const [focusPassenger, setFocusPassenger] = useState<PassengerEntity>();
45
46 const registered = useMemo(() => {
47 if (!connected) return false;
48 const isInTravel = travel.attributes.passengers?.data.some(
49 passenger => passenger.attributes.user?.data?.id === `${userId}`
50 );
51 return isInTravel;
52 }, [travel, userId, connected]);
53
54 if (!travel) return null;
55
56 return (
57 <Paper
58 sx={{
59 position: 'relative',
60 boxShadow: focused
61 ? `0px 0px 5px 2px ${theme.palette.primary.main}`
62 : 'none',
63 scrollMarginTop: theme.spacing(2),
64 }}
65 id={travel.id}
66 >
67 <RequestTripModal
68 open={requestTripModalOpen}
69 toggle={toggleRequestTripModal}
70 travel={travel}
71 />
72 {isEditing && (
73 <HeaderEditing travel={travel} toggleEditing={toggleEditing} />
74 )}
75 {!isEditing && (
76 <>
77 <Header travel={travel} toggleEditing={toggleEditing} />
78 <>
79 <Divider />
80 <AddPassengerButtons
81 registered={registered}
82 variant="travel"
83 disabled={disableNewPassengers}
84 onAddOther={props.onAddOther}
85 onAddSelf={
86 isCarosterPlus ? toggleRequestTripModal : props.onAddSelf
87 }
88 />
89 </>
90 {travel.attributes.passengers.data.length > 0 && <Divider />}
91 <PassengersList
92 passengers={travel.attributes.passengers.data}
93 travel={travel}
94 Actions={({passenger}) => (
95 <PassengerActions
96 passenger={passenger}
97 travel={travel}
98 setFocusPassenger={setFocusPassenger}
99 />
100 )}
101 />
102 {focusPassenger && canSeePassengerDetails(focusPassenger) && (
103 <DrawerPassenger
104 isOpen={!!focusPassenger}
105 onClose={() => setFocusPassenger(undefined)}
106 firstName={
107 focusPassenger?.attributes.user?.data?.attributes.firstName
108 }
109 lastName={
110 focusPassenger?.attributes.user?.data?.attributes.lastName
111 }
112 email={focusPassenger?.attributes.email}
113 phone={focusPassenger?.attributes.phone}
114 phoneCountry={focusPassenger?.attributes.phoneCountry}
115 />
116 )}
117 </>
118 )}
119 </Paper>
120 );
121};
122
123export default Travel;