frontend/containers/Travel/index.tsx (view raw)
1import {useMemo, useReducer} from 'react';
2import Divider from '@mui/material/Divider';
3import Paper from '@mui/material/Paper';
4import Button from '@mui/material/Button';
5import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction';
6import {useTheme} from '@mui/styles';
7import {useTranslation} from 'react-i18next';
8import HeaderEditing from './HeaderEditing';
9import Header from './Header';
10import useActions from './useActions';
11import PassengersList from '../PassengersList';
12import AddPassengerButtons from '../AddPassengerButtons';
13import useProfile from '../../hooks/useProfile';
14import usePermissions from '../../hooks/usePermissions';
15import useMapStore from '../../stores/useMapStore';
16import {Travel as TravelType} from '../../generated/graphql';
17
18interface Props {
19 travel: TravelType & {id: string};
20 getAddPassengerFunction: (addSelf: boolean) => () => void;
21}
22
23const Travel = (props: Props) => {
24 const {travel} = props;
25 const {
26 userPermissions: {editableTravels, canJoinTravels, canAddToTravel},
27 } = usePermissions();
28 const {t} = useTranslation();
29 const theme = useTheme();
30 const [isEditing, toggleEditing] = useReducer(i => !i, false);
31 const actions = useActions({travel});
32 const {userId, connected} = useProfile();
33 const {focusedTravel} = useMapStore();
34 const focused = focusedTravel === travel.id;
35
36 if (!travel) return null;
37 const disableNewPassengers = travel.passengers.data?.length >= travel.seats;
38
39 const registered = useMemo(() => {
40 if (!connected) return false;
41 const isInTravel = travel.passengers?.data.some(
42 passenger => passenger.attributes.user?.data?.id === `${userId}`
43 );
44
45 return isInTravel;
46 }, [travel, userId]);
47
48 return (
49 <Paper
50 sx={{
51 position: 'relative',
52 boxShadow: focused
53 ? `0px 0px 5px 2px ${theme.palette.primary.main}`
54 : 'none',
55 scrollMarginTop: theme.spacing(2),
56 }}
57 id={travel.id}
58 >
59 {isEditing ? (
60 <HeaderEditing travel={travel} toggleEditing={toggleEditing} />
61 ) : (
62 <Header travel={travel} toggleEditing={toggleEditing} />
63 )}
64 {!isEditing && (
65 <>
66 {(canJoinTravels || canAddToTravel) && (
67 <>
68 <Divider />
69 <AddPassengerButtons
70 getOnClickFunction={props.getAddPassengerFunction}
71 registered={registered}
72 variant="travel"
73 disabled={disableNewPassengers}
74 />
75 </>
76 )}
77 {travel.passengers.data.length > 0 && <Divider />}
78 <PassengersList
79 passengers={travel.passengers.data}
80 onClick={actions.sendPassengerToWaitingList}
81 isTravel
82 Button={({onClick}: {onClick: () => void}) =>
83 editableTravels.includes(travel.id) && (
84 <ListItemSecondaryAction>
85 <Button color="primary" onClick={onClick} tabIndex={-1}>
86 {t`travel.passengers.remove`}
87 </Button>
88 </ListItemSecondaryAction>
89 )
90 }
91 />
92 </>
93 )}
94 </Paper>
95 );
96};
97
98export default Travel;