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;