all repos — caroster @ 50c371504df1ebada58e03e4a29205cb108057f3

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

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

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