all repos — caroster @ d093130068a7eaa39a600bd411181a85f168dc74

[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 {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: {canDeletePassenger, 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            travel={travel}
 83            Button={({onClick, passenger}) =>
 84              canDeletePassenger({
 85                id: passenger.id,
 86                attributes: {...passenger.attributes, travel: {data: travel}},
 87              }) && (
 88                <ListItemSecondaryAction>
 89                  <Button color="primary" onClick={onClick} tabIndex={-1}>
 90                    {t`travel.passengers.remove`}
 91                  </Button>
 92                </ListItemSecondaryAction>
 93              )
 94            }
 95          />
 96        </>
 97      )}
 98    </Paper>
 99  );
100};
101
102export default Travel;