PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
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 / lib / i18n.ts

i18n.ts in Yatra – Travel Booking & Tour Operator Software 3.0.16, at resources/js/lib/i18n.ts

254 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Internationalization (i18n) utility
3 * Handles translations for UI text
4 */
5
6 declare global {
7 interface Window {
8 yatraAdmin?: {
9 apiUrl?: string;
10 restUrl?: string;
11 nonce?: string;
12 brandLogoUrl?: string;
13 /**
14 * Operator-facing brand name. When the White Label module is
15 * active (Agency-tier only) and the operator has filled in
16 * "Plugin name" in WL settings, this is THAT value — otherwise
17 * it's "Yatra". Use this everywhere instead of hardcoding
18 * "Yatra" so the UI reflects the operator's brand for resellers.
19 *
20 * Injected by AdminAssetsProvider via `yatra_get_brand_name()`.
21 */
22 brandName?: string;
23 pluginUrl?: string;
24 currentUserAvatar?: string;
25 currentUser?: number;
26 siteUrl?: string;
27 permissions?: string[];
28 roles?: string[];
29 capabilities?: Record<string, boolean>;
30 isPro?: boolean;
31 /** Yatra → Modules → Custom Landing Pages enabled (Pro). */
32 customLandingPagesModuleEnabled?: boolean;
33 isProActive?: boolean;
34 version?: string;
35 proVersion?: string | null;
36 translations?: Record<string, string>;
37 locale?: string;
38 emailAutomationEnabled?: boolean;
39 emailTemplateOverridesEnabled?: boolean;
40 tripConsentEnabled?: boolean;
41 additionalServicesEnabled?: boolean;
42 abandonedBookingRecoveryEnabled?: boolean;
43 dynamicPricingEnabled?: boolean;
44 dynamicFormFieldEnabled?: boolean;
45 bookingFormConditionsEnabled?: boolean;
46 advancedDiscountEnabled?: boolean;
47 showGoogleCalendarSettingsUI?: boolean;
48 showMailchimpSettingsUI?: boolean;
49 showFacebookPixelSettingsUI?: boolean;
50 showGoogleAnalyticsSettingsUI?: boolean;
51 flexiblePaymentsEnabled?: boolean;
52 // Growth + Agency tier modules — set by their respective Pro
53 // modules via yatra_admin_localized_data filter, OR by the
54 // free plugin's AdminAssetsProvider (canonical source via
55 // ModuleManager::isModuleEnabled). useModules() also writes
56 // these at runtime once /modules resolves.
57 aiAssistantEnabled?: boolean;
58 whiteLabelEnabled?: boolean;
59 whatsappEnabled?: boolean;
60 channelManagerEnabled?: boolean;
61 webhooksEnabled?: boolean;
62 scheduledPaymentsEnabled?: boolean;
63 currency?: string;
64 date_format?: string;
65 time_format?: string;
66 calendar_name?: string;
67 connected?: boolean;
68 redirect_uri?: string;
69 last_sync?: string | null;
70 googleCalendarRedirectUri?: string;
71 mailchimp?: {
72 connected?: boolean;
73 listId?: string;
74 listName?: string;
75 syncOnBooking?: boolean;
76 syncOnPayment?: boolean;
77 addTags?: boolean;
78 defaultTags?: string[];
79 doubleOptin?: boolean;
80 fieldMapping?: Record<string, string>;
81 };
82 facebookPixel?: {
83 connected?: boolean;
84 pixelId?: string;
85 trackViewContent?: boolean;
86 trackInitiateCheckout?: boolean;
87 trackPurchase?: boolean;
88 useConversionsApi?: boolean;
89 testEventCode?: string;
90 eventConfig?: Record<
91 string,
92 { enabled: boolean; custom_params?: string[] }
93 >;
94 parameterMapping?: Record<string, string>;
95 };
96 googleAnalytics?: {
97 connected?: boolean;
98 measurementId?: string;
99 trackViewItem?: boolean;
100 trackBeginCheckout?: boolean;
101 trackPurchase?: boolean;
102 useMeasurementProtocol?: boolean;
103 debugMode?: boolean;
104 customDimensions?: Array<{
105 name: string;
106 yatra_field: string;
107 scope?: string;
108 }>;
109 eventConfig?: Record<
110 string,
111 { enabled: boolean; custom_params?: string[] }
112 >;
113 };
114 googleCalendar?: {
115 client_id?: string;
116 client_secret?: string;
117 calendar_id?: string;
118 calendar_name?: string;
119 connected?: boolean;
120 redirect_uri?: string;
121 last_sync?: string | null;
122 };
123 // Team & Access (Agency-tier) — injected by Team module's
124 // LocalizedData service. Absent when module isn't installed.
125 teamEnabled?: boolean;
126 /**
127 * Forward-looking "keep access on module disable" setting.
128 * Only consulted when the Team & Access module is DISABLED:
129 * - `false` (default): yatra_* caps are stripped for non-admin
130 * users until the module is re-enabled.
131 * - `true`: WP-native role machinery keeps resolving caps from
132 * the stored role records — team members keep their access
133 * even after disabling the module.
134 *
135 * When the module is enabled, this setting is irrelevant —
136 * caps resolve normally through the full layered chain (admin
137 * fallback, expiry, revoke, role, grant).
138 */
139 teamKeepAccessOnModuleDisable?: boolean;
140 isWpAdmin?: boolean;
141 userCaps?: string[];
142 userScopes?: {
143 destinations: number[];
144 activities: number[];
145 trips: number[];
146 categories: number[];
147 };
148 };
149 }
150 }
151
152 /**
153 * Internationalization (i18n) utility
154 * Handles translations for UI text
155 */
156
157 import {
158 __ as wpI18n__,
159 _x as wpI18n_x,
160 sprintf as wpSprintf,
161 } from "@wordpress/i18n";
162
163 function __(key: string): string;
164 function __(key: string, textDomain: string): string;
165 function __(key: string, textDomain?: string): string {
166 // If the frontend bootstrapped a translations map (e.g., account page),
167 // use it as the highest priority source. This allows Loco Translate / PHP
168 // string catalogs to power React UIs without requiring JS translation JSON files.
169 if (typeof window !== "undefined") {
170 const w = window as unknown as {
171 yatraAccountPage?: { translations?: Record<string, string> };
172 yatraAdmin?: { translations?: Record<string, string> };
173 };
174 const fromAccount = w.yatraAccountPage?.translations?.[key];
175 if (typeof fromAccount === "string" && fromAccount !== "") {
176 return fromAccount;
177 }
178 const fromAdmin = w.yatraAdmin?.translations?.[key];
179 if (typeof fromAdmin === "string" && fromAdmin !== "") {
180 return fromAdmin;
181 }
182 }
183
184 // Use direct WordPress i18n function which is working correctly
185 if (typeof window !== "undefined" && (window as any).wp?.i18n?.__) {
186 return (window as any).wp.i18n.__(key, textDomain || "yatra");
187 }
188 // Fallback to @wordpress/i18n
189 return wpI18n__(key, textDomain || "yatra");
190 }
191
192 function _x(key: string, context: string): string;
193 function _x(key: string, context: string, textDomain: string): string;
194 function _x(key: string, context: string, textDomain?: string): string {
195 // Use direct WordPress i18n function which is working correctly
196 if (typeof window !== "undefined" && (window as any).wp?.i18n?._x) {
197 return (window as any).wp.i18n._x(key, context, textDomain || "yatra");
198 }
199 // Fallback to @wordpress/i18n
200 return wpI18n_x(key, context, textDomain || "yatra");
201 }
202
203 function sprintf(format: string, ...args: (string | number)[]): string {
204 if (typeof window !== "undefined" && (window as any).wp?.i18n?.sprintf) {
205 return (window as any).wp.i18n.sprintf(format, ...args);
206 }
207 return (wpSprintf as (fmt: string, ...a: (string | number)[]) => string)(
208 format,
209 ...args,
210 );
211 }
212
213 /**
214 * Operator brand name — "Yatra" by default, or whatever the operator
215 * has set in the White Label module (Agency tier).
216 *
217 * Use this in user-visible strings instead of hardcoding "Yatra":
218 *
219 * const brand = brandName();
220 * sprintf(__("%s role", "yatra"), brand) // "Acme role" if rebranded
221 *
222 * Always pass the brand as an interpolated argument so the translatable
223 * string stays generic — that keeps `make-pot` extraction working AND
224 * means a translator only has to translate "%s role" once, regardless
225 * of brand.
226 */
227 function brandName(): string {
228 if (typeof window === "undefined") return "Yatra";
229 return (window.yatraAdmin?.brandName as string | undefined) || "Yatra";
230 }
231
232 export { __, _x, sprintf, brandName };
233
234 /**
235 * Get translated string with number
236 * @param single - Single form
237 * @param plural - Plural form
238 * @param number - Number to determine form
239 * @param textDomain - Optional text domain; accepted for API parity with
240 * WordPress's own `_n()` so call sites that already pass
241 * `"yatra"` as a fourth arg type-check. Currently
242 * unused — `__()` does its own domain resolution via
243 * the translations map injected on `window.yatraAdmin`.
244 * @returns Translated string
245 */
246 export const _n = (
247 single: string,
248 plural: string,
249 number: number,
250 _textDomain?: string,
251 ): string => {
252 return number === 1 ? __(single) : __(plural);
253 };
254