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, canJoinTravels, canAddToTravel},
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();
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 {(canJoinTravels() || canAddToTravel()) && (
79 <>
80 <Divider />
81 <AddPassengerButtons
82 registered={registered}
83 variant="travel"
84 disabled={disableNewPassengers}
85 onAddOther={props.onAddOther}
86 onAddSelf={
87 isCarosterPlus ? toggleRequestTripModal : props.onAddSelf
88 }
89 />
90 </>
91 )}
92 {travel.attributes.passengers.data.length > 0 && <Divider />}
93 <PassengersList
94 passengers={travel.attributes.passengers.data}
95 travel={travel}
96 Actions={({passenger}) => (
97 <PassengerActions
98 passenger={passenger}
99 travel={travel}
100 setFocusPassenger={setFocusPassenger}
101 />
102 )}
103 />
104 {focusPassenger && canSeePassengerDetails(focusPassenger) && (
105 <DrawerPassenger
106 isOpen={!!focusPassenger}
107 onClose={() => setFocusPassenger(undefined)}
108 firstName={
109 focusPassenger?.attributes.user?.data?.attributes.firstName
110 }
111 lastName={
112 focusPassenger?.attributes.user?.data?.attributes.lastName
113 }
114 email={focusPassenger?.attributes.email}
115 phone={focusPassenger?.attributes.phone}
116 phoneCountry={focusPassenger?.attributes.phoneCountry}
117 />
118 )}
119 </>
120 )}
121 </Paper>
122 );
123};
124
125export default Travel;