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 HeaderEditing from './HeaderEditing';
5import Header from './Header';
6import RequestTripModal from './RequestTripModal';
7import PassengersList from '../PassengersList';
8import AddPassengerButtons from '../AddPassengerButtons';
9import useProfile from '../../hooks/useProfile';
10import usePermissions from '../../hooks/usePermissions';
11import useMapStore from '../../stores/useMapStore';
12import useEventStore from '../../stores/useEventStore';
13import {PassengerEntity, TravelEntity} from '../../generated/graphql';
14import DrawerPassenger from '../DrawerPassenger';
15import PassengerActions from './PassengerActions';
16import theme from '../../theme';
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 [isEditing, toggleEditing] = useReducer(i => !i, false);
33 const [requestTripModalOpen, toggleRequestTripModal] = useReducer(
34 i => !i,
35 false
36 );
37 const {userId, connected} = useProfile();
38 const focusedTravel = useMapStore(s => s.focusedTravel);
39 const focused = focusedTravel === travel.id;
40 const disableNewPassengers =
41 travel.attributes.passengers?.data?.length >= travel.attributes.seats;
42
43 const [focusPassenger, setFocusPassenger] = useState<PassengerEntity>();
44
45 const registered = useMemo(() => {
46 if (!connected) return false;
47 const isInTravel = travel.attributes.passengers?.data.some(
48 passenger => passenger.attributes.user?.data?.id === `${userId}`
49 );
50 return isInTravel;
51 }, [travel, userId, connected]);
52
53 if (!travel) return null;
54
55 return (
56 <Paper
57 sx={{
58 position: 'relative',
59 boxShadow: focused
60 ? `0px 0px 5px 2px ${theme.palette.primary.main}`
61 : 'none',
62 scrollMarginTop: theme.spacing(2),
63 }}
64 id={travel.id}
65 >
66 <RequestTripModal
67 open={requestTripModalOpen}
68 toggle={toggleRequestTripModal}
69 travel={travel}
70 />
71 {isEditing && (
72 <HeaderEditing travel={travel} toggleEditing={toggleEditing} />
73 )}
74 {!isEditing && (
75 <>
76 <Header travel={travel} toggleEditing={toggleEditing} />
77 <>
78 <Divider />
79 <AddPassengerButtons
80 travelId={travel.id}
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;