all repos — caroster @ 9f359590899f531edd1ad7be81c01344d86fb9a6

[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(({user, name}) => ({name, user})),
118              ]),
119            },
120          },
121        });
122        await deleteTravelMutation({
123          variables: {
124            id: travel.id,
125          },
126          refetchQueries: [
127            {query: EventByUuidDocument, variables: {uuid: event.uuid}},
128          ],
129        });
130        addToast(t('travel.actions.removed'));
131      }
132    } catch (error) {
133      console.error(error);
134      addToast(t('travel.errors.cant_remove'));
135    }
136  };
137
138  return {sendPassengerToWaitingList, updateTravel, removeTravel};
139};
140
141const formatPassengers = (passengers = [], seats: number = 1000) => {
142  if (!passengers) return [];
143  return passengers.slice(0, seats).map(({__typename, user, ...passenger}) => ({
144    ...passenger,
145    user: user?.id,
146  }));
147};
148
149export default useActions;