all repos — caroster @ 124dfa21a7100f628775f5a0f49841048f8584ea

[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 = [...event.waitingList, removedPassenger].map(
 42          ({__typename, user, ...item}) =>
 43            user && user.id ? {...item, user: user.id} : item
 44        );
 45        const passengers = existingPassengers.filter(
 46          item => item.id !== passengerId
 47        );
 48        await updateEventMutation({
 49          variables: {
 50            uuid: event.uuid,
 51            eventUpdate: {
 52              waitingList,
 53            },
 54          },
 55        });
 56        await updateTravelMutation({
 57          variables: {
 58            id: travel.id,
 59            travelUpdate: {
 60              passengers,
 61            },
 62          },
 63          refetchQueries: ['eventByUUID'],
 64        });
 65      } catch (error) {
 66        console.error(error);
 67        addToast(t('travel.errors.cant_remove_passenger'));
 68      }
 69    }
 70  };
 71
 72  const updateTravel = async update => {
 73    try {
 74      // If new seats count is under current passengers count, put excedent in event waiting list
 75      // TODO: Move these logics to backend
 76      if (travel.passengers?.length > update.vehicle?.seats) {
 77        const lostPassengers = travel.passengers.slice(update.vehicle?.seats);
 78        if (lostPassengers.length > 0)
 79          await updateEventMutation({
 80            variables: {
 81              uuid: event.uuid,
 82              eventUpdate: {
 83                waitingList: formatPassengers([
 84                  ...(event.waitingList || []),
 85                  ...lostPassengers.map(({name}) => ({name})),
 86                ]),
 87              },
 88            },
 89            refetchQueries: ['eventByUUID'],
 90          });
 91      }
 92      const departure = moment(
 93        `${moment(update.travel.date).format('YYYY-MM-DD')} ${moment(
 94          update.travel.time
 95        ).format('HH:mm')}`,
 96        'YYYY-MM-DD HH:mm'
 97      ).toISOString();
 98      await updateTravelMutation({
 99        variables: {
100          id: travel.id,
101          travelUpdate: {
102            departure,
103            passengers: formatPassengers(
104              travel.passengers,
105              travel.vehicle?.seats
106            ),
107          },
108        },
109      });
110      await updateVehicleMutation({
111        variables: {
112          id: travel?.vehicle?.id,
113          vehicleUpdate: update.vehicle,
114        },
115      });
116    } catch (error) {
117      console.error(error);
118      addToast('travel.errors.cant_update');
119    }
120    return false;
121  };
122
123  const removeTravel = async () => {
124    try {
125      // Put passengers in event waiting list (if any)
126      // TODO Move these logics to backend and delete vehicle if no user linked
127      if (Array.isArray(travel?.passengers) && travel.passengers.length > 0)
128        await updateEventMutation({
129          variables: {
130            uuid: event.uuid,
131            eventUpdate: {
132              waitingList: formatPassengers([
133                ...(event.waitingList || []),
134                ...travel.passengers.map(({name}) => ({name})),
135              ]),
136            },
137          },
138          refetchQueries: [
139            {query: EventByUuidDocument, variables: {uuid: event.uuid}},
140          ],
141        });
142      await deleteTravelMutation({
143        variables: {
144          id: travel.id,
145        },
146      });
147      addToast(t('travel.actions.removed'));
148    } catch (error) {
149      console.error(error);
150      addToast('travel.errors.cant_remove');
151    }
152  };
153
154  return {sendPassengerToWaitingList, updateTravel, removeTravel};
155};
156
157const formatPassengers = (passengers = [], seats: number = 1000) => {
158  if (!passengers) return [];
159  return passengers
160    .slice(0, seats)
161    .map(({__typename, ...passenger}) => passenger);
162};
163
164export default useActions;