all repos — caroster @ 2514e64e14324d01eada51f08410194d01a169c4

[Octree] Group carpool to your event https://caroster.io

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  const disableNewPassengers = travel?.passengers.data?.length >= travel.seats;
36
37  const registered = useMemo(() => {
38    if (!connected) return false;
39    const isInTravel = travel.passengers?.data.some(
40      passenger => passenger.attributes.user?.data?.id === `${userId}`
41    );
42    return isInTravel;
43  }, [travel, userId]);
44
45  return (
46    <Paper
47      sx={{
48        position: 'relative',
49        boxShadow: focused
50          ? `0px 0px 5px 2px ${theme.palette.primary.main}`
51          : 'none',
52        scrollMarginTop: theme.spacing(2),
53      }}
54      id={travel.id}
55    >
56      {isEditing && (
57        <HeaderEditing travel={travel} toggleEditing={toggleEditing} />
58      )}
59      {!isEditing && (
60        <>
61          <Header travel={travel} toggleEditing={toggleEditing} />
62          {(canJoinTravels || canAddToTravel) && (
63            <>
64              <Divider />
65              <AddPassengerButtons
66                getOnClickFunction={props.getAddPassengerFunction}
67                registered={registered}
68                variant="travel"
69                disabled={disableNewPassengers}
70              />
71            </>
72          )}
73          {travel.passengers.data.length > 0 && <Divider />}
74          <PassengersList
75            passengers={travel.passengers.data}
76            onClick={actions.sendPassengerToWaitingList}
77            isTravel
78            Button={({onClick}: {onClick: () => void}) =>
79              editableTravels.includes(travel.id) && (
80                <ListItemSecondaryAction>
81                  <Button color="primary" onClick={onClick} tabIndex={-1}>
82                    {t`travel.passengers.remove`}
83                  </Button>
84                </ListItemSecondaryAction>
85              )
86            }
87          />
88        </>
89      )}
90    </Paper>
91  );
92};
93
94export default Travel;