PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.3
Yatra – Travel Booking & Tour Operator Software v3.0.3
3.0.16 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 All 84 releases
yatra / resources / js / hooks / useModules.ts

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

281 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import {
2 useQuery,
3 UseQueryOptions,
4 useMutation,
5 useQueryClient,
6 } from "@tanstack/react-query";
7 import { apiClient } from "../lib/api-client";
8 import { __ } from "../lib/i18n";
9 import { useToast } from "../components/ui/toast";
10
11 export interface ModuleDefinition {
12 slug: string;
13 name: string;
14 description?: string;
15 category?: string;
16 version?: string;
17 docs_url?: string;
18 is_core?: boolean;
19 is_premium?: boolean;
20 is_available?: boolean;
21 requires_pro?: boolean;
22 purchase_url?: string;
23 video_url?: string;
24 enabled: boolean;
25 tags?: string[];
26 updated_at?: string | null;
27 settings_page?: string;
28 }
29
30 interface ModulesResponse {
31 data?: ModuleDefinition[];
32 }
33
34 const fetchModules = async (): Promise<ModuleDefinition[]> => {
35 const response: ModulesResponse = await apiClient.get("/modules");
36 if (Array.isArray(response)) {
37 return response;
38 }
39 if (Array.isArray(response?.data)) {
40 return response.data;
41 }
42 return [];
43 };
44
45 export const useModulesQuery = (
46 options?: Partial<UseQueryOptions<ModuleDefinition[], Error>>,
47 ) => {
48 return useQuery<ModuleDefinition[], Error>({
49 queryKey: ["modules"],
50 queryFn: fetchModules,
51 staleTime: 0,
52 ...options,
53 });
54 };
55
56 interface TogglePayload {
57 slug: string;
58 enabled: boolean;
59 name?: string;
60 }
61
62 const formatNamesList = (names: string[]) => {
63 if (names.length <= 2) {
64 return names.join(", ");
65 }
66 return `${names.slice(0, 2).join(", ")} ${__("and", "yatra")} ${names.length - 2} ${__("more", "yatra")}`;
67 };
68
69 export const useToggleModule = () => {
70 const queryClient = useQueryClient();
71 const { showToast } = useToast();
72
73 return useMutation({
74 mutationFn: async ({ slug, enabled }: TogglePayload) => {
75 const response: ModulesResponse = await apiClient.post(
76 `/modules/${slug}/toggle`,
77 { enabled },
78 );
79 return Array.isArray(response?.data) ? response.data : [];
80 },
81 onSuccess: (data, variables) => {
82 queryClient.setQueryData(["modules"], data);
83
84 // Update global admin variables for navigation
85 if (window.yatraAdmin) {
86 // Update module-specific flags based on the enabled modules
87 const enabledModules = data.filter((m) => m.enabled);
88
89 // Check for specific modules that affect navigation
90 window.yatraAdmin.emailAutomationEnabled = enabledModules.some(
91 (m) => m.slug === "email_automation" || m.slug === "email-automation",
92 );
93 window.yatraAdmin.tripConsentEnabled = enabledModules.some(
94 (m) => m.slug === "trip_consent" || m.slug === "trip-consent",
95 );
96 window.yatraAdmin.additionalServicesEnabled = enabledModules.some(
97 (m) =>
98 m.slug === "additional_services" ||
99 m.slug === "additional-services",
100 );
101 window.yatraAdmin.abandonedBookingRecoveryEnabled = enabledModules.some(
102 (m) =>
103 m.slug === "abandoned_booking_recovery" ||
104 m.slug === "abandoned-booking-recovery",
105 );
106 window.yatraAdmin.dynamicPricingEnabled = enabledModules.some(
107 (m) => m.slug === "dynamic_pricing" || m.slug === "dynamic-pricing",
108 );
109 window.yatraAdmin.flexiblePaymentsEnabled = enabledModules.some(
110 (m) => m.slug === "flexible_payments",
111 );
112 window.yatraAdmin.dynamicFormFieldEnabled = enabledModules.some(
113 (m) => m.slug === "dynamic_form_field",
114 );
115 window.yatraAdmin.showGoogleCalendarSettingsUI = enabledModules.some(
116 (m) => m.slug === "google_calendar" || m.slug === "google-calendar",
117 );
118 window.yatraAdmin.advancedDiscountEnabled = enabledModules.some(
119 (m) =>
120 m.slug === "advanced_discount" || m.slug === "advanced-discount",
121 );
122 // Add flags for Pro feature modules
123 window.yatraAdmin.showMailchimpSettingsUI = enabledModules.some(
124 (m) => m.slug === "mailchimp",
125 );
126 window.yatraAdmin.showFacebookPixelSettingsUI = enabledModules.some(
127 (m) => m.slug === "facebook_pixel",
128 );
129 window.yatraAdmin.showGoogleAnalyticsSettingsUI = enabledModules.some(
130 (m) => m.slug === "google_analytics",
131 );
132 // Note: availabilityModuleEnabled and departuresModuleEnabled removed - now FREE features
133
134 // Trigger a navigation refresh by updating a custom event
135 window.dispatchEvent(
136 new CustomEvent("yatra-modules-updated", {
137 detail: {
138 enabledModules: enabledModules,
139 updatedModule: variables,
140 },
141 }),
142 );
143
144 // Force a layout re-render by updating the URL key
145 const urlKey = (window as any).__yatraUrlKey || 0;
146 (window as any).__yatraUrlKey = urlKey + 1;
147 window.dispatchEvent(new CustomEvent("yatra-force-nav-refresh"));
148 }
149
150 const label = variables.name || variables.slug;
151 showToast(
152 variables.enabled
153 ? __("{module} enabled successfully.", "yatra").replace(
154 "{module}",
155 label,
156 )
157 : __("{module} disabled successfully.", "yatra").replace(
158 "{module}",
159 label,
160 ),
161 "success",
162 );
163 },
164 onError: (error: Error) => {
165 showToast(
166 error.message || __("Failed to update module.", "yatra"),
167 "error",
168 );
169 },
170 });
171 };
172
173 export const useBulkToggleModules = () => {
174 const queryClient = useQueryClient();
175 const { showToast } = useToast();
176
177 return useMutation({
178 mutationFn: async (items: TogglePayload[]) => {
179 const response: ModulesResponse = await apiClient.post(
180 "/modules/bulk-toggle",
181 { items },
182 );
183 return Array.isArray(response?.data) ? response.data : [];
184 },
185 onSuccess: (data, variables = [], context) => {
186 queryClient.setQueryData(["modules"], data);
187
188 // Check if there's a partial success message (some modules blocked)
189 const response = context as any;
190 if (response?.message) {
191 // Show partial success message with warning
192 showToast(response.message, "warning");
193 }
194
195 // Update global admin variables for navigation
196 if (window.yatraAdmin && data) {
197 // Update module-specific flags based on the enabled modules
198 const enabledModules = data.filter((m) => m.enabled);
199
200 // Check for specific modules that affect navigation
201 window.yatraAdmin.emailAutomationEnabled = enabledModules.some(
202 (m) => m.slug === "email_automation" || m.slug === "email-automation",
203 );
204 window.yatraAdmin.tripConsentEnabled = enabledModules.some(
205 (m) => m.slug === "trip_consent" || m.slug === "trip-consent",
206 );
207 window.yatraAdmin.additionalServicesEnabled = enabledModules.some(
208 (m) =>
209 m.slug === "additional_services" ||
210 m.slug === "additional-services",
211 );
212 window.yatraAdmin.abandonedBookingRecoveryEnabled = enabledModules.some(
213 (m) =>
214 m.slug === "abandoned_booking_recovery" ||
215 m.slug === "abandoned-booking-recovery",
216 );
217 window.yatraAdmin.dynamicPricingEnabled = enabledModules.some(
218 (m) => m.slug === "dynamic_pricing" || m.slug === "dynamic-pricing",
219 );
220 window.yatraAdmin.flexiblePaymentsEnabled = enabledModules.some(
221 (m) => m.slug === "flexible_payments",
222 );
223 window.yatraAdmin.dynamicFormFieldEnabled = enabledModules.some(
224 (m) => m.slug === "dynamic_form_field",
225 );
226 window.yatraAdmin.showGoogleCalendarSettingsUI = enabledModules.some(
227 (m) => m.slug === "google_calendar" || m.slug === "google-calendar",
228 );
229 window.yatraAdmin.advancedDiscountEnabled = enabledModules.some(
230 (m) =>
231 m.slug === "advanced_discount" || m.slug === "advanced-discount",
232 );
233 // Add flags for Pro feature modules
234 window.yatraAdmin.showMailchimpSettingsUI = enabledModules.some(
235 (m) => m.slug === "mailchimp",
236 );
237 window.yatraAdmin.showFacebookPixelSettingsUI = enabledModules.some(
238 (m) => m.slug === "facebook_pixel",
239 );
240 window.yatraAdmin.showGoogleAnalyticsSettingsUI = enabledModules.some(
241 (m) => m.slug === "google_analytics",
242 );
243 // Note: availabilityModuleEnabled and departuresModuleEnabled removed - now FREE features
244
245 // Trigger a navigation refresh by updating a custom event
246 window.dispatchEvent(
247 new CustomEvent("yatra-modules-updated", {
248 detail: {
249 enabledModules: enabledModules,
250 updatedModules: variables || [],
251 },
252 }),
253 );
254
255 // Force a layout re-render by updating the URL key
256 const urlKey = (window as any).__yatraUrlKey || 0;
257 (window as any).__yatraUrlKey = urlKey + 1;
258 window.dispatchEvent(new CustomEvent("yatra-force-nav-refresh"));
259 }
260
261 // Only show success message if there wasn't a partial success message
262 if (!response?.message && variables.length > 0) {
263 const names = variables.map((item) => item.name || item.slug);
264 const summary = formatNamesList(names);
265 const message = variables[0].enabled
266 ? __("Enabled: {modules}", "yatra").replace("{modules}", summary)
267 : __("Disabled: {modules}", "yatra").replace("{modules}", summary);
268 showToast(message, "success");
269 } else if (!response?.message) {
270 showToast(__("Modules updated successfully.", "yatra"), "success");
271 }
272 },
273 onError: (error: Error) => {
274 showToast(
275 error.message || __("Failed to update modules.", "yatra"),
276 "error",
277 );
278 },
279 });
280 };
281