all repos — caroster @ 13d9c127957995a4b4451e509236ff82153976f2

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

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

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