all repos — caroster @ ea414277b269eb8ba96835769f2e44ca1069f093

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

frontend/containers/Travel/useActions.ts (view raw)

  1import {useTranslation} from 'react-i18next';
  2import useEventStore from '../../stores/useEventStore';
  3import useToastStore from '../../stores/useToastStore';
  4import {
  5  useUpdateTravelMutation,
  6  useUpdateEventMutation,
  7  useDeleteTravelMutation,
  8  EventByUuidDocument,
  9  Travel,
 10  EditTravelInput,
 11} from '../../generated/graphql';
 12
 13interface Props {
 14  travel: Travel;
 15}
 16
 17const useActions = (props: Props) => {
 18  const {travel} = props;
 19  const {t} = useTranslation();
 20  const event = useEventStore(s => s.event);
 21  const addToast = useToastStore(s => s.addToast);
 22  const [updateEventMutation] = useUpdateEventMutation();
 23  const [updateTravelMutation] = useUpdateTravelMutation();
 24  const [deleteTravelMutation] = useDeleteTravelMutation();
 25
 26  const sendPassengerToWaitingList = async (passengerId: string) => {
 27    if (travel?.passengers) {
 28      try {
 29        const {id, ...removedPassenger} = travel.passengers?.find(
 30          item => item.id === passengerId
 31        );
 32        if (!removedPassenger) {
 33          throw 'No corresponding passenger';
 34        }
 35        const existingPassengers =
 36          travel.passengers?.map(({__typename, user, ...item}) =>
 37            user && user.id ? {...item, user: user.id} : item
 38          ) || [];
 39        const waitingList = [...event.waitingList, removedPassenger].map(
 40          ({__typename, user, ...item}) =>
 41            user && user.id ? {...item, user: user.id} : item
 42        );
 43        const passengers = existingPassengers.filter(
 44          item => item.id !== passengerId
 45        );
 46        await updateEventMutation({
 47          variables: {
 48            uuid: event.uuid,
 49            eventUpdate: {
 50              waitingList,
 51            },
 52          },
 53        });
 54        await updateTravelMutation({
 55          variables: {
 56            id: travel.id,
 57            travelUpdate: {
 58              passengers,
 59            },
 60          },
 61          refetchQueries: ['eventByUUID'],
 62        });
 63      } catch (error) {
 64        console.error(error);
 65        addToast(t('travel.errors.cant_remove_passenger'));
 66      }
 67    }
 68  };
 69
 70  const updateTravel = async (travelUpdate: EditTravelInput) => {
 71    try {
 72      // If new seats count is under current passengers count, put excedent in event waiting list
 73      // TODO: Move these logics to backend
 74      if (travel.passengers?.length > travelUpdate.seats) {
 75        const lostPassengers = travel.passengers.slice(travelUpdate.seats);
 76        if (lostPassengers.length > 0)
 77          await updateEventMutation({
 78            variables: {
 79              uuid: event.uuid,
 80              eventUpdate: {
 81                waitingList: formatPassengers([
 82                  ...(event.waitingList || []),
 83                  ...lostPassengers.map(({name}) => ({name})),
 84                ]),
 85              },
 86            },
 87            refetchQueries: ['eventByUUID'],
 88          });
 89      }
 90      await updateTravelMutation({
 91        variables: {
 92          id: travel.id,
 93          travelUpdate: {
 94            ...travelUpdate,
 95            passengers: formatPassengers(travel.passengers, travel.seats),
 96          },
 97        },
 98      });
 99    } catch (error) {
100      console.error(error);
101      addToast(t('travel.errors.cant_update'));
102    }
103    return false;
104  };
105
106  const removeTravel = async () => {
107    try {
108      // Put passengers in event waiting list (if any)
109      // TODO Move these logics to backend and delete vehicle if no user linked
110      if (Array.isArray(travel?.passengers) && travel.passengers.length > 0)
111        await updateEventMutation({
112          variables: {
113            uuid: event.uuid,
114            eventUpdate: {
115              waitingList: formatPassengers([
116                ...(event.waitingList || []),
117                ...travel.passengers.map(({name}) => ({name})),
118              ]),
119            },
120          },
121          refetchQueries: [
122            {query: EventByUuidDocument, variables: {uuid: event.uuid}},
123          ],
124        });
125      await deleteTravelMutation({
126        variables: {
127          id: travel.id,
128        },
129      });
130      addToast(t('travel.actions.removed'));
131    } catch (error) {
132      console.error(error);
133      addToast(t('travel.errors.cant_remove'));
134    }
135  };
136
137  return {sendPassengerToWaitingList, updateTravel, removeTravel};
138};
139
140const formatPassengers = (passengers = [], seats: number = 1000) => {
141  if (!passengers) return [];
142  return passengers
143    .slice(0, seats)
144    .map(({__typename, ...passenger}) => passenger);
145};
146
147export default useActions;