all repos — caroster @ 8cf97f406bef2a68157869e2f6398d45b8bec77a

[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
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;