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