PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.8
Yatra – Travel Booking & Tour Operator Software v3.0.2.8
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / resources / js / hooks / useItineraryFormData.ts

useItineraryFormData.ts in Yatra – Travel Booking & Tour Operator Software 3.0.2.8, at resources/js/hooks/useItineraryFormData.ts

277 lines 8.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Custom hook for fetching all data needed by ItineraryForm
3 */
4
5 import { useQuery } from "@tanstack/react-query";
6 import { useMemo } from "react";
7 import { apiClient } from "../lib/api-client";
8 import { API_ENDPOINTS } from "../lib/api-endpoints";
9 import { usePermissions } from "./usePermissions";
10 import { __ } from "../lib/i18n";
11
12 interface UseItineraryFormDataParams {
13 entryId: number | null;
14 isEditMode: boolean;
15 isEditDayMode: boolean;
16 isAddDayMode: boolean;
17 tripIdParam: string | null;
18 dayParam: string | null;
19 formDataItemTypeId: string;
20 formDataTripId?: string; // Trip ID from form data (for dropdown selection)
21 }
22
23 export const useItineraryFormData = ({
24 entryId,
25 isEditMode,
26 isEditDayMode,
27 isAddDayMode,
28 tripIdParam,
29 dayParam,
30 formDataItemTypeId,
31 formDataTripId,
32 }: UseItineraryFormDataParams) => {
33 const { can } = usePermissions();
34
35 // Fetch trips
36 const { data: tripsData, isLoading: isLoadingTrips } = useQuery({
37 queryKey: ["trips-simple"],
38 queryFn: async () => {
39 try {
40 const response = await apiClient.get("/trips", {
41 params: {
42 per_page: 100,
43 status: "all",
44 },
45 });
46 const trips = response?.data?.data || response?.data || response || [];
47 return Array.isArray(trips) ? trips : [];
48 } catch (error: any) {
49 console.error("Failed to load trips:", error);
50 return [];
51 }
52 },
53 enabled: can("yatra_view_trips"),
54 });
55
56 // Fetch item types
57 const { data: typesData } = useQuery({
58 queryKey: ["item-types-published"],
59 queryFn: async () => {
60 try {
61 const response = await apiClient.get("/item-types", {
62 params: {
63 per_page: 100,
64 status: "publish",
65 },
66 });
67 const types = response?.data?.data || response?.data || response || [];
68 return Array.isArray(types) ? types : [];
69 } catch (error: any) {
70 console.error("Failed to load item types:", error);
71 return [];
72 }
73 },
74 enabled: can("yatra_view_trips"),
75 staleTime: 5 * 60 * 1000,
76 gcTime: 10 * 60 * 1000,
77 });
78
79 // Fetch items - in day mode fetch all items, in activity mode fetch by type
80 const itemsQueryKey = useMemo(
81 () =>
82 isAddDayMode
83 ? ["items-all-published"]
84 : ["items-by-type", formDataItemTypeId],
85 [isAddDayMode, formDataItemTypeId],
86 );
87
88 const { data: itemsData } = useQuery({
89 queryKey: itemsQueryKey,
90 queryFn: async () => {
91 try {
92 if (isAddDayMode) {
93 const response = await apiClient.get("/items", {
94 params: {
95 per_page: 1000,
96 status: "publish",
97 },
98 });
99 const items =
100 response?.data?.data || response?.data || response || [];
101 return Array.isArray(items) ? items : [];
102 }
103
104 if (!formDataItemTypeId) return [];
105
106 const response = await apiClient.get("/items", {
107 params: {
108 per_page: 1000,
109 type_id: formDataItemTypeId,
110 status: "publish",
111 },
112 });
113 const items = response?.data?.data || response?.data || response || [];
114 return Array.isArray(items) ? items : [];
115 } catch (error: any) {
116 console.error("Failed to load items:", error);
117 return [];
118 }
119 },
120 enabled: can("yatra_view_trips"),
121 staleTime: 5 * 60 * 1000,
122 gcTime: 10 * 60 * 1000,
123 });
124
125 // Fetch entry data when editing
126 const { data: entryData, isLoading: isLoadingEntryData } = useQuery({
127 queryKey: ["itinerary-entry", entryId, isEditDayMode ? "day" : "activity"],
128 queryFn: async () => {
129 if (!entryId) return null;
130 try {
131 // Pass mode parameter to API based on isEditDayMode
132 const mode = isEditDayMode ? "day" : "activity";
133 const endpoint = API_ENDPOINTS.ITINERARY_GET(entryId, mode);
134 const response = await apiClient.get(endpoint);
135 const result = response?.data?.data || response?.data || response;
136
137 return result;
138 } catch (error: any) {
139 console.error("Failed to load itinerary entry:", error);
140 return null;
141 }
142 },
143 enabled: isEditMode && !!entryId && can("yatra_view_trips"),
144 });
145
146 // Extract identifiers from the initially loaded entry (could be activity)
147 const entryDayId = useMemo(() => entryData?.day_id, [entryData?.day_id]);
148
149 // Check if entryData is an activity (has non-zero item_type_id and item_id)
150 // Day entries have item_type_id: 0 and item_id: 0
151 const isActivityEntry = useMemo(() => {
152 return (
153 entryData &&
154 entryData.item_type_id !== null &&
155 entryData.item_type_id !== undefined &&
156 entryData.item_type_id !== 0 &&
157 entryData.item_id !== null &&
158 entryData.item_id !== undefined &&
159 entryData.item_id !== 0
160 );
161 }, [entryData]);
162
163 // Fetch day entry when editing a day and entryData is an activity
164 const { data: dayEntryData } = useQuery({
165 queryKey: ["day-entry-by-day-id", entryDayId],
166 queryFn: async () => {
167 if (!entryDayId || !isEditDayMode) return null;
168 try {
169 const response = await apiClient.get(
170 `/itinerary/day-entry-by-day-id/${entryDayId}`,
171 );
172 const dayEntryId =
173 response?.data?.day_entry_id ||
174 response?.day_entry_id ||
175 response?.data?.id ||
176 response?.id ||
177 null;
178 if (dayEntryId) {
179 // Fetch the actual day entry data
180 const entryResponse = await apiClient.get(`/itinerary/${dayEntryId}`);
181 return (
182 entryResponse?.data?.data || entryResponse?.data || entryResponse
183 );
184 }
185 return null;
186 } catch (error: any) {
187 console.error("Failed to load day entry:", error);
188 return null;
189 }
190 },
191 enabled:
192 isEditDayMode &&
193 !!entryDayId &&
194 isActivityEntry &&
195 can("yatra_view_trips"),
196 });
197
198 // Determine the effective entry data (day entry when editing a day)
199 const effectiveEntryData = useMemo(() => {
200 if (isEditDayMode && isActivityEntry && dayEntryData) {
201 return dayEntryData;
202 }
203 return entryData;
204 }, [isEditDayMode, isActivityEntry, dayEntryData, entryData]);
205
206 // Extract stable primitive values from the effective entry data
207 const entryTripId = useMemo(
208 () => effectiveEntryData?.trip_id,
209 [effectiveEntryData?.trip_id],
210 );
211 const entryDay = useMemo(
212 () => effectiveEntryData?.day,
213 [effectiveEntryData?.day],
214 );
215
216 // Fetch trip data for day editing to get all activities
217 const { data: dayTripData } = useQuery({
218 queryKey: ["trip-for-day-edit", entryTripId, entryDay],
219 queryFn: async () => {
220 if (!entryTripId || !isEditDayMode) return null;
221 try {
222 const response = await apiClient.get(`/trips/${entryTripId}`);
223 return response?.data || response;
224 } catch (error: any) {
225 console.error("Failed to load trip data for day edit:", error);
226 return null;
227 }
228 },
229 enabled:
230 isEditDayMode && !!entryTripId && !!entryDay && can("yatra_view_trips"),
231 });
232
233 // Fetch trip data to get day title when in activity mode, and to check existing days in day mode
234 // Use tripIdParam if available (from URL), otherwise use formDataTripId (from dropdown selection)
235 const effectiveTripIdForQuery = tripIdParam || formDataTripId || "";
236
237 const tripDataQueryKey = useMemo(
238 () => ["trip-for-day", effectiveTripIdForQuery, dayParam || ""],
239 [effectiveTripIdForQuery, dayParam],
240 );
241
242 const { data: tripDataForDay } = useQuery({
243 queryKey: tripDataQueryKey,
244 queryFn: async () => {
245 if (!effectiveTripIdForQuery) return null;
246 try {
247 const response = await apiClient.get(
248 `/trips/${effectiveTripIdForQuery}`,
249 );
250 return response?.data || response;
251 } catch (error) {
252 console.error("Failed to fetch trip data:", error);
253 return null;
254 }
255 },
256 enabled:
257 !isEditDayMode && !!effectiveTripIdForQuery && can("yatra_view_trips"),
258 });
259
260 // Use dayTripData when in edit day mode, otherwise use tripDataForDay
261 const effectiveTripData = isEditDayMode ? dayTripData : tripDataForDay;
262
263 return {
264 tripsData: tripsData || [],
265 isLoadingTrips,
266 typesData: typesData || [],
267 itemsData: itemsData || [],
268 entryData: effectiveEntryData,
269 isLoadingEntry: isLoadingEntryData,
270 dayTripData,
271 tripDataForDay,
272 effectiveTripData,
273 entryTripId,
274 entryDay,
275 };
276 };
277