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 / assets / dist / js / index-Dec_weLB.js

index-Dec_weLB.js in Yatra – Travel Booking & Tour Operator Software 3.0.16, at assets/dist/js/index-Dec_weLB.js

2,777 lines 98.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { a1 as getDefaultExportFromCjs, r as reactExports, j as jsxRuntimeExports, a6 as React, ay as X, aG as Info, V as AlertTriangle, aA as AlertCircle, aE as CheckCircle2, y as ChevronDown, az as reactDomExports, aP as Search } from "./react-vendor-CithbthY.js";
2 function memize(fn, options) {
3 var size = 0;
4 var head;
5 var tail;
6 options = options || {};
7 function memoized() {
8 var node = head, len = arguments.length, args, i;
9 searchCache: while (node) {
10 if (node.args.length !== arguments.length) {
11 node = node.next;
12 continue;
13 }
14 for (i = 0; i < len; i++) {
15 if (node.args[i] !== arguments[i]) {
16 node = node.next;
17 continue searchCache;
18 }
19 }
20 if (node !== head) {
21 if (node === tail) {
22 tail = node.prev;
23 }
24 node.prev.next = node.next;
25 if (node.next) {
26 node.next.prev = node.prev;
27 }
28 node.next = head;
29 node.prev = null;
30 head.prev = node;
31 head = node;
32 }
33 return node.val;
34 }
35 args = new Array(len);
36 for (i = 0; i < len; i++) {
37 args[i] = arguments[i];
38 }
39 node = {
40 args,
41 // Generate the result from original function
42 val: fn.apply(null, args)
43 };
44 if (head) {
45 head.prev = node;
46 node.next = head;
47 } else {
48 tail = node;
49 }
50 if (size === /** @type {MemizeOptions} */
51 options.maxSize) {
52 tail = /** @type {MemizeCacheNode} */
53 tail.prev;
54 tail.next = null;
55 } else {
56 size++;
57 }
58 head = node;
59 return node.val;
60 }
61 memoized.clear = function() {
62 head = null;
63 tail = null;
64 size = 0;
65 };
66 return memoized;
67 }
68 var sprintf$2 = {};
69 (function(exports$1) {
70 !function() {
71 var re = {
72 not_type: /[^T]/,
73 not_primitive: /[^v]/,
74 number: /[diefg]/,
75 numeric_arg: /[bcdiefguxX]/,
76 json: /[j]/,
77 text: /^[^\x25]+/,
78 modulo: /^\x25{2}/,
79 placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
80 key: /^([a-z_][a-z_\d]*)/i,
81 key_access: /^\.([a-z_][a-z_\d]*)/i,
82 index_access: /^\[(\d+)\]/,
83 sign: /^[+-]/
84 };
85 function sprintf2(key) {
86 return sprintf_format(sprintf_parse(key), arguments);
87 }
88 function vsprintf(fmt, argv) {
89 return sprintf2.apply(null, [fmt].concat(argv || []));
90 }
91 function sprintf_format(parse_tree, argv) {
92 var cursor = 1, tree_length = parse_tree.length, arg, output = "", i, k, ph, pad, pad_character, pad_length, is_positive, sign;
93 for (i = 0; i < tree_length; i++) {
94 if (typeof parse_tree[i] === "string") {
95 output += parse_tree[i];
96 } else if (typeof parse_tree[i] === "object") {
97 ph = parse_tree[i];
98 if (ph.keys) {
99 arg = argv[cursor];
100 for (k = 0; k < ph.keys.length; k++) {
101 if (arg == void 0) {
102 throw new Error(sprintf2('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k - 1]));
103 }
104 arg = arg[ph.keys[k]];
105 }
106 } else if (ph.param_no) {
107 arg = argv[ph.param_no];
108 } else {
109 arg = argv[cursor++];
110 }
111 if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
112 arg = arg();
113 }
114 if (re.numeric_arg.test(ph.type) && (typeof arg !== "number" && isNaN(arg))) {
115 throw new TypeError(sprintf2("[sprintf] expecting number but found %T", arg));
116 }
117 if (re.number.test(ph.type)) {
118 is_positive = arg >= 0;
119 }
120 switch (ph.type) {
121 case "b":
122 arg = parseInt(arg, 10).toString(2);
123 break;
124 case "c":
125 arg = String.fromCharCode(parseInt(arg, 10));
126 break;
127 case "d":
128 case "i":
129 arg = parseInt(arg, 10);
130 break;
131 case "j":
132 arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0);
133 break;
134 case "e":
135 arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential();
136 break;
137 case "f":
138 arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg);
139 break;
140 case "g":
141 arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg);
142 break;
143 case "o":
144 arg = (parseInt(arg, 10) >>> 0).toString(8);
145 break;
146 case "s":
147 arg = String(arg);
148 arg = ph.precision ? arg.substring(0, ph.precision) : arg;
149 break;
150 case "t":
151 arg = String(!!arg);
152 arg = ph.precision ? arg.substring(0, ph.precision) : arg;
153 break;
154 case "T":
155 arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase();
156 arg = ph.precision ? arg.substring(0, ph.precision) : arg;
157 break;
158 case "u":
159 arg = parseInt(arg, 10) >>> 0;
160 break;
161 case "v":
162 arg = arg.valueOf();
163 arg = ph.precision ? arg.substring(0, ph.precision) : arg;
164 break;
165 case "x":
166 arg = (parseInt(arg, 10) >>> 0).toString(16);
167 break;
168 case "X":
169 arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase();
170 break;
171 }
172 if (re.json.test(ph.type)) {
173 output += arg;
174 } else {
175 if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
176 sign = is_positive ? "+" : "-";
177 arg = arg.toString().replace(re.sign, "");
178 } else {
179 sign = "";
180 }
181 pad_character = ph.pad_char ? ph.pad_char === "0" ? "0" : ph.pad_char.charAt(1) : " ";
182 pad_length = ph.width - (sign + arg).length;
183 pad = ph.width ? pad_length > 0 ? pad_character.repeat(pad_length) : "" : "";
184 output += ph.align ? sign + arg + pad : pad_character === "0" ? sign + pad + arg : pad + sign + arg;
185 }
186 }
187 }
188 return output;
189 }
190 var sprintf_cache = /* @__PURE__ */ Object.create(null);
191 function sprintf_parse(fmt) {
192 if (sprintf_cache[fmt]) {
193 return sprintf_cache[fmt];
194 }
195 var _fmt = fmt, match, parse_tree = [], arg_names = 0;
196 while (_fmt) {
197 if ((match = re.text.exec(_fmt)) !== null) {
198 parse_tree.push(match[0]);
199 } else if ((match = re.modulo.exec(_fmt)) !== null) {
200 parse_tree.push("%");
201 } else if ((match = re.placeholder.exec(_fmt)) !== null) {
202 if (match[2]) {
203 arg_names |= 1;
204 var field_list = [], replacement_field = match[2], field_match = [];
205 if ((field_match = re.key.exec(replacement_field)) !== null) {
206 field_list.push(field_match[1]);
207 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") {
208 if ((field_match = re.key_access.exec(replacement_field)) !== null) {
209 field_list.push(field_match[1]);
210 } else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
211 field_list.push(field_match[1]);
212 } else {
213 throw new SyntaxError("[sprintf] failed to parse named argument key");
214 }
215 }
216 } else {
217 throw new SyntaxError("[sprintf] failed to parse named argument key");
218 }
219 match[2] = field_list;
220 } else {
221 arg_names |= 2;
222 }
223 if (arg_names === 3) {
224 throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");
225 }
226 parse_tree.push(
227 {
228 placeholder: match[0],
229 param_no: match[1],
230 keys: match[2],
231 sign: match[3],
232 pad_char: match[4],
233 align: match[5],
234 width: match[6],
235 precision: match[7],
236 type: match[8]
237 }
238 );
239 } else {
240 throw new SyntaxError("[sprintf] unexpected placeholder");
241 }
242 _fmt = _fmt.substring(match[0].length);
243 }
244 return sprintf_cache[fmt] = parse_tree;
245 }
246 {
247 exports$1["sprintf"] = sprintf2;
248 exports$1["vsprintf"] = vsprintf;
249 }
250 if (typeof window !== "undefined") {
251 window["sprintf"] = sprintf2;
252 window["vsprintf"] = vsprintf;
253 }
254 }();
255 })(sprintf$2);
256 const sprintfjs = /* @__PURE__ */ getDefaultExportFromCjs(sprintf$2);
257 const logErrorOnce = memize(console.error);
258 function sprintf$1(format, ...args) {
259 try {
260 return sprintfjs.sprintf(format, ...args);
261 } catch (error) {
262 if (error instanceof Error) {
263 logErrorOnce("sprintf error: \n\n" + error.toString());
264 }
265 return format;
266 }
267 }
268 var PRECEDENCE, OPENERS, TERMINATORS, PATTERN;
269 PRECEDENCE = {
270 "(": 9,
271 "!": 8,
272 "*": 7,
273 "/": 7,
274 "%": 7,
275 "+": 6,
276 "-": 6,
277 "<": 5,
278 "<=": 5,
279 ">": 5,
280 ">=": 5,
281 "==": 4,
282 "!=": 4,
283 "&&": 3,
284 "||": 2,
285 "?": 1,
286 "?:": 1
287 };
288 OPENERS = ["(", "?"];
289 TERMINATORS = {
290 ")": ["("],
291 ":": ["?", "?:"]
292 };
293 PATTERN = /<=|>=|==|!=|&&|\|\||\?:|\(|!|\*|\/|%|\+|-|<|>|\?|\)|:/;
294 function postfix(expression) {
295 var terms = [], stack = [], match, operator, term, element;
296 while (match = expression.match(PATTERN)) {
297 operator = match[0];
298 term = expression.substr(0, match.index).trim();
299 if (term) {
300 terms.push(term);
301 }
302 while (element = stack.pop()) {
303 if (TERMINATORS[operator]) {
304 if (TERMINATORS[operator][0] === element) {
305 operator = TERMINATORS[operator][1] || operator;
306 break;
307 }
308 } else if (OPENERS.indexOf(element) >= 0 || PRECEDENCE[element] < PRECEDENCE[operator]) {
309 stack.push(element);
310 break;
311 }
312 terms.push(element);
313 }
314 if (!TERMINATORS[operator]) {
315 stack.push(operator);
316 }
317 expression = expression.substr(match.index + operator.length);
318 }
319 expression = expression.trim();
320 if (expression) {
321 terms.push(expression);
322 }
323 return terms.concat(stack.reverse());
324 }
325 var OPERATORS = {
326 "!": function(a) {
327 return !a;
328 },
329 "*": function(a, b) {
330 return a * b;
331 },
332 "/": function(a, b) {
333 return a / b;
334 },
335 "%": function(a, b) {
336 return a % b;
337 },
338 "+": function(a, b) {
339 return a + b;
340 },
341 "-": function(a, b) {
342 return a - b;
343 },
344 "<": function(a, b) {
345 return a < b;
346 },
347 "<=": function(a, b) {
348 return a <= b;
349 },
350 ">": function(a, b) {
351 return a > b;
352 },
353 ">=": function(a, b) {
354 return a >= b;
355 },
356 "==": function(a, b) {
357 return a === b;
358 },
359 "!=": function(a, b) {
360 return a !== b;
361 },
362 "&&": function(a, b) {
363 return a && b;
364 },
365 "||": function(a, b) {
366 return a || b;
367 },
368 "?:": function(a, b, c) {
369 if (a) {
370 throw b;
371 }
372 return c;
373 }
374 };
375 function evaluate(postfix2, variables) {
376 var stack = [], i, j, args, getOperatorResult, term, value;
377 for (i = 0; i < postfix2.length; i++) {
378 term = postfix2[i];
379 getOperatorResult = OPERATORS[term];
380 if (getOperatorResult) {
381 j = getOperatorResult.length;
382 args = Array(j);
383 while (j--) {
384 args[j] = stack.pop();
385 }
386 try {
387 value = getOperatorResult.apply(null, args);
388 } catch (earlyReturn) {
389 return earlyReturn;
390 }
391 } else if (variables.hasOwnProperty(term)) {
392 value = variables[term];
393 } else {
394 value = +term;
395 }
396 stack.push(value);
397 }
398 return stack[0];
399 }
400 function compile(expression) {
401 var terms = postfix(expression);
402 return function(variables) {
403 return evaluate(terms, variables);
404 };
405 }
406 function pluralForms(expression) {
407 var evaluate2 = compile(expression);
408 return function(n) {
409 return +evaluate2({ n });
410 };
411 }
412 var DEFAULT_OPTIONS = {
413 contextDelimiter: "",
414 onMissingKey: null
415 };
416 function getPluralExpression(pf) {
417 var parts, i, part;
418 parts = pf.split(";");
419 for (i = 0; i < parts.length; i++) {
420 part = parts[i].trim();
421 if (part.indexOf("plural=") === 0) {
422 return part.substr(7);
423 }
424 }
425 }
426 function Tannin(data, options) {
427 var key;
428 this.data = data;
429 this.pluralForms = {};
430 this.options = {};
431 for (key in DEFAULT_OPTIONS) {
432 this.options[key] = options !== void 0 && key in options ? options[key] : DEFAULT_OPTIONS[key];
433 }
434 }
435 Tannin.prototype.getPluralForm = function(domain, n) {
436 var getPluralForm = this.pluralForms[domain], config, plural, pf;
437 if (!getPluralForm) {
438 config = this.data[domain][""];
439 pf = config["Plural-Forms"] || config["plural-forms"] || // Ignore reason: As known, there's no way to document the empty
440 // string property on a key to guarantee this as metadata.
441 // @ts-ignore
442 config.plural_forms;
443 if (typeof pf !== "function") {
444 plural = getPluralExpression(
445 config["Plural-Forms"] || config["plural-forms"] || // Ignore reason: As known, there's no way to document the empty
446 // string property on a key to guarantee this as metadata.
447 // @ts-ignore
448 config.plural_forms
449 );
450 pf = pluralForms(plural);
451 }
452 getPluralForm = this.pluralForms[domain] = pf;
453 }
454 return getPluralForm(n);
455 };
456 Tannin.prototype.dcnpgettext = function(domain, context, singular, plural, n) {
457 var index, key, entry;
458 if (n === void 0) {
459 index = 0;
460 } else {
461 index = this.getPluralForm(domain, n);
462 }
463 key = singular;
464 if (context) {
465 key = context + this.options.contextDelimiter + singular;
466 }
467 entry = this.data[domain][key];
468 if (entry && entry[index]) {
469 return entry[index];
470 }
471 if (this.options.onMissingKey) {
472 this.options.onMissingKey(singular, domain);
473 }
474 return index === 0 ? singular : plural;
475 };
476 const DEFAULT_LOCALE_DATA = {
477 "": {
478 /** @param {number} n */
479 plural_forms(n) {
480 return n === 1 ? 0 : 1;
481 }
482 }
483 };
484 const I18N_HOOK_REGEXP = /^i18n\.(n?gettext|has_translation)(_|$)/;
485 const createI18n = (initialData, initialDomain, hooks) => {
486 const tannin = new Tannin({});
487 const listeners = /* @__PURE__ */ new Set();
488 const notifyListeners = () => {
489 listeners.forEach((listener) => listener());
490 };
491 const subscribe = (callback) => {
492 listeners.add(callback);
493 return () => listeners.delete(callback);
494 };
495 const getLocaleData = (domain = "default") => tannin.data[domain];
496 const doSetLocaleData = (data, domain = "default") => {
497 var _a;
498 tannin.data[domain] = {
499 ...tannin.data[domain],
500 ...data
501 };
502 tannin.data[domain][""] = {
503 ...DEFAULT_LOCALE_DATA[""],
504 ...(_a = tannin.data[domain]) == null ? void 0 : _a[""]
505 };
506 delete tannin.pluralForms[domain];
507 };
508 const setLocaleData = (data, domain) => {
509 doSetLocaleData(data, domain);
510 notifyListeners();
511 };
512 const addLocaleData = (data, domain = "default") => {
513 var _a;
514 tannin.data[domain] = {
515 ...tannin.data[domain],
516 ...data,
517 // Populate default domain configuration (supported locale date which omits
518 // a plural forms expression).
519 "": {
520 ...DEFAULT_LOCALE_DATA[""],
521 ...(_a = tannin.data[domain]) == null ? void 0 : _a[""],
522 ...data == null ? void 0 : data[""]
523 }
524 };
525 delete tannin.pluralForms[domain];
526 notifyListeners();
527 };
528 const resetLocaleData = (data, domain) => {
529 tannin.data = {};
530 tannin.pluralForms = {};
531 setLocaleData(data, domain);
532 };
533 const dcnpgettext = (domain = "default", context, single, plural, number) => {
534 if (!tannin.data[domain]) {
535 doSetLocaleData(void 0, domain);
536 }
537 return tannin.dcnpgettext(domain, context, single, plural, number);
538 };
539 const getFilterDomain = (domain = "default") => domain;
540 const __2 = (text, domain) => {
541 let translation = dcnpgettext(domain, void 0, text);
542 if (!hooks) {
543 return translation;
544 }
545 translation = /** @type {string} */
546 /** @type {*} */
547 hooks.applyFilters("i18n.gettext", translation, text, domain);
548 return (
549 /** @type {string} */
550 /** @type {*} */
551 hooks.applyFilters("i18n.gettext_" + getFilterDomain(domain), translation, text, domain)
552 );
553 };
554 const _x = (text, context, domain) => {
555 let translation = dcnpgettext(domain, context, text);
556 if (!hooks) {
557 return translation;
558 }
559 translation = /** @type {string} */
560 /** @type {*} */
561 hooks.applyFilters("i18n.gettext_with_context", translation, text, context, domain);
562 return (
563 /** @type {string} */
564 /** @type {*} */
565 hooks.applyFilters("i18n.gettext_with_context_" + getFilterDomain(domain), translation, text, context, domain)
566 );
567 };
568 const _n = (single, plural, number, domain) => {
569 let translation = dcnpgettext(domain, void 0, single, plural, number);
570 if (!hooks) {
571 return translation;
572 }
573 translation = /** @type {string} */
574 /** @type {*} */
575 hooks.applyFilters("i18n.ngettext", translation, single, plural, number, domain);
576 return (
577 /** @type {string} */
578 /** @type {*} */
579 hooks.applyFilters("i18n.ngettext_" + getFilterDomain(domain), translation, single, plural, number, domain)
580 );
581 };
582 const _nx = (single, plural, number, context, domain) => {
583 let translation = dcnpgettext(domain, context, single, plural, number);
584 if (!hooks) {
585 return translation;
586 }
587 translation = /** @type {string} */
588 /** @type {*} */
589 hooks.applyFilters("i18n.ngettext_with_context", translation, single, plural, number, context, domain);
590 return (
591 /** @type {string} */
592 /** @type {*} */
593 hooks.applyFilters("i18n.ngettext_with_context_" + getFilterDomain(domain), translation, single, plural, number, context, domain)
594 );
595 };
596 const isRTL = () => {
597 return "rtl" === _x("ltr", "text direction");
598 };
599 const hasTranslation = (single, context, domain) => {
600 var _a, _b;
601 const key = context ? context + "" + single : single;
602 let result = !!((_b = (_a = tannin.data) == null ? void 0 : _a[domain !== null && domain !== void 0 ? domain : "default"]) == null ? void 0 : _b[key]);
603 if (hooks) {
604 result = /** @type { boolean } */
605 /** @type {*} */
606 hooks.applyFilters("i18n.has_translation", result, single, context, domain);
607 result = /** @type { boolean } */
608 /** @type {*} */
609 hooks.applyFilters("i18n.has_translation_" + getFilterDomain(domain), result, single, context, domain);
610 }
611 return result;
612 };
613 if (hooks) {
614 const onHookAddedOrRemoved = (hookName) => {
615 if (I18N_HOOK_REGEXP.test(hookName)) {
616 notifyListeners();
617 }
618 };
619 hooks.addAction("hookAdded", "core/i18n", onHookAddedOrRemoved);
620 hooks.addAction("hookRemoved", "core/i18n", onHookAddedOrRemoved);
621 }
622 return {
623 getLocaleData,
624 setLocaleData,
625 addLocaleData,
626 resetLocaleData,
627 subscribe,
628 __: __2,
629 _x,
630 _n,
631 _nx,
632 isRTL,
633 hasTranslation
634 };
635 };
636 function validateNamespace(namespace) {
637 if ("string" !== typeof namespace || "" === namespace) {
638 console.error("The namespace must be a non-empty string.");
639 return false;
640 }
641 if (!/^[a-zA-Z][a-zA-Z0-9_.\-\/]*$/.test(namespace)) {
642 console.error("The namespace can only contain numbers, letters, dashes, periods, underscores and slashes.");
643 return false;
644 }
645 return true;
646 }
647 function validateHookName(hookName) {
648 if ("string" !== typeof hookName || "" === hookName) {
649 console.error("The hook name must be a non-empty string.");
650 return false;
651 }
652 if (/^__/.test(hookName)) {
653 console.error("The hook name cannot begin with `__`.");
654 return false;
655 }
656 if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(hookName)) {
657 console.error("The hook name can only contain numbers, letters, dashes, periods and underscores.");
658 return false;
659 }
660 return true;
661 }
662 function createAddHook(hooks, storeKey) {
663 return function addHook(hookName, namespace, callback, priority = 10) {
664 const hooksStore = hooks[storeKey];
665 if (!validateHookName(hookName)) {
666 return;
667 }
668 if (!validateNamespace(namespace)) {
669 return;
670 }
671 if ("function" !== typeof callback) {
672 console.error("The hook callback must be a function.");
673 return;
674 }
675 if ("number" !== typeof priority) {
676 console.error("If specified, the hook priority must be a number.");
677 return;
678 }
679 const handler = {
680 callback,
681 priority,
682 namespace
683 };
684 if (hooksStore[hookName]) {
685 const handlers = hooksStore[hookName].handlers;
686 let i;
687 for (i = handlers.length; i > 0; i--) {
688 if (priority >= handlers[i - 1].priority) {
689 break;
690 }
691 }
692 if (i === handlers.length) {
693 handlers[i] = handler;
694 } else {
695 handlers.splice(i, 0, handler);
696 }
697 hooksStore.__current.forEach((hookInfo) => {
698 if (hookInfo.name === hookName && hookInfo.currentIndex >= i) {
699 hookInfo.currentIndex++;
700 }
701 });
702 } else {
703 hooksStore[hookName] = {
704 handlers: [handler],
705 runs: 0
706 };
707 }
708 if (hookName !== "hookAdded") {
709 hooks.doAction("hookAdded", hookName, namespace, callback, priority);
710 }
711 };
712 }
713 function createRemoveHook(hooks, storeKey, removeAll = false) {
714 return function removeHook(hookName, namespace) {
715 const hooksStore = hooks[storeKey];
716 if (!validateHookName(hookName)) {
717 return;
718 }
719 if (!removeAll && !validateNamespace(namespace)) {
720 return;
721 }
722 if (!hooksStore[hookName]) {
723 return 0;
724 }
725 let handlersRemoved = 0;
726 if (removeAll) {
727 handlersRemoved = hooksStore[hookName].handlers.length;
728 hooksStore[hookName] = {
729 runs: hooksStore[hookName].runs,
730 handlers: []
731 };
732 } else {
733 const handlers = hooksStore[hookName].handlers;
734 for (let i = handlers.length - 1; i >= 0; i--) {
735 if (handlers[i].namespace === namespace) {
736 handlers.splice(i, 1);
737 handlersRemoved++;
738 hooksStore.__current.forEach((hookInfo) => {
739 if (hookInfo.name === hookName && hookInfo.currentIndex >= i) {
740 hookInfo.currentIndex--;
741 }
742 });
743 }
744 }
745 }
746 if (hookName !== "hookRemoved") {
747 hooks.doAction("hookRemoved", hookName, namespace);
748 }
749 return handlersRemoved;
750 };
751 }
752 function createHasHook(hooks, storeKey) {
753 return function hasHook(hookName, namespace) {
754 const hooksStore = hooks[storeKey];
755 if ("undefined" !== typeof namespace) {
756 return hookName in hooksStore && hooksStore[hookName].handlers.some((hook) => hook.namespace === namespace);
757 }
758 return hookName in hooksStore;
759 };
760 }
761 function createRunHook(hooks, storeKey, returnFirstArg = false) {
762 return function runHooks(hookName, ...args) {
763 const hooksStore = hooks[storeKey];
764 if (!hooksStore[hookName]) {
765 hooksStore[hookName] = {
766 handlers: [],
767 runs: 0
768 };
769 }
770 hooksStore[hookName].runs++;
771 const handlers = hooksStore[hookName].handlers;
772 if (!handlers || !handlers.length) {
773 return returnFirstArg ? args[0] : void 0;
774 }
775 const hookInfo = {
776 name: hookName,
777 currentIndex: 0
778 };
779 hooksStore.__current.push(hookInfo);
780 while (hookInfo.currentIndex < handlers.length) {
781 const handler = handlers[hookInfo.currentIndex];
782 const result = handler.callback.apply(null, args);
783 if (returnFirstArg) {
784 args[0] = result;
785 }
786 hookInfo.currentIndex++;
787 }
788 hooksStore.__current.pop();
789 if (returnFirstArg) {
790 return args[0];
791 }
792 return void 0;
793 };
794 }
795 function createCurrentHook(hooks, storeKey) {
796 return function currentHook() {
797 var _a;
798 var _hooksStore$__current;
799 const hooksStore = hooks[storeKey];
800 return (_hooksStore$__current = (_a = hooksStore.__current[hooksStore.__current.length - 1]) == null ? void 0 : _a.name) !== null && _hooksStore$__current !== void 0 ? _hooksStore$__current : null;
801 };
802 }
803 function createDoingHook(hooks, storeKey) {
804 return function doingHook(hookName) {
805 const hooksStore = hooks[storeKey];
806 if ("undefined" === typeof hookName) {
807 return "undefined" !== typeof hooksStore.__current[0];
808 }
809 return hooksStore.__current[0] ? hookName === hooksStore.__current[0].name : false;
810 };
811 }
812 function createDidHook(hooks, storeKey) {
813 return function didHook(hookName) {
814 const hooksStore = hooks[storeKey];
815 if (!validateHookName(hookName)) {
816 return;
817 }
818 return hooksStore[hookName] && hooksStore[hookName].runs ? hooksStore[hookName].runs : 0;
819 };
820 }
821 class _Hooks {
822 constructor() {
823 this.actions = /* @__PURE__ */ Object.create(null);
824 this.actions.__current = [];
825 this.filters = /* @__PURE__ */ Object.create(null);
826 this.filters.__current = [];
827 this.addAction = createAddHook(this, "actions");
828 this.addFilter = createAddHook(this, "filters");
829 this.removeAction = createRemoveHook(this, "actions");
830 this.removeFilter = createRemoveHook(this, "filters");
831 this.hasAction = createHasHook(this, "actions");
832 this.hasFilter = createHasHook(this, "filters");
833 this.removeAllActions = createRemoveHook(this, "actions", true);
834 this.removeAllFilters = createRemoveHook(this, "filters", true);
835 this.doAction = createRunHook(this, "actions");
836 this.applyFilters = createRunHook(this, "filters", true);
837 this.currentAction = createCurrentHook(this, "actions");
838 this.currentFilter = createCurrentHook(this, "filters");
839 this.doingAction = createDoingHook(this, "actions");
840 this.doingFilter = createDoingHook(this, "filters");
841 this.didAction = createDidHook(this, "actions");
842 this.didFilter = createDidHook(this, "filters");
843 }
844 }
845 function createHooks() {
846 return new _Hooks();
847 }
848 const defaultHooks = createHooks();
849 const {
850 addAction,
851 addFilter,
852 removeAction,
853 removeFilter,
854 hasAction,
855 hasFilter,
856 removeAllActions,
857 removeAllFilters,
858 doAction,
859 applyFilters,
860 currentAction,
861 currentFilter,
862 doingAction,
863 doingFilter,
864 didAction,
865 didFilter,
866 actions,
867 filters
868 } = defaultHooks;
869 const i18n = createI18n(void 0, void 0, defaultHooks);
870 i18n.getLocaleData.bind(i18n);
871 i18n.setLocaleData.bind(i18n);
872 i18n.resetLocaleData.bind(i18n);
873 i18n.subscribe.bind(i18n);
874 const __$1 = i18n.__.bind(i18n);
875 i18n._x.bind(i18n);
876 i18n._n.bind(i18n);
877 i18n._nx.bind(i18n);
878 i18n.isRTL.bind(i18n);
879 i18n.hasTranslation.bind(i18n);
880 function __(key, textDomain) {
881 var _a, _b, _c, _d, _e, _f;
882 if (typeof window !== "undefined") {
883 const w = window;
884 const fromAccount = (_b = (_a = w.yatraAccountPage) == null ? void 0 : _a.translations) == null ? void 0 : _b[key];
885 if (typeof fromAccount === "string" && fromAccount !== "") {
886 return fromAccount;
887 }
888 const fromAdmin = (_d = (_c = w.yatraAdmin) == null ? void 0 : _c.translations) == null ? void 0 : _d[key];
889 if (typeof fromAdmin === "string" && fromAdmin !== "") {
890 return fromAdmin;
891 }
892 }
893 if (typeof window !== "undefined" && ((_f = (_e = window.wp) == null ? void 0 : _e.i18n) == null ? void 0 : _f.__)) {
894 return window.wp.i18n.__(key, textDomain || "yatra");
895 }
896 return __$1(key, textDomain || "yatra");
897 }
898 function sprintf(format, ...args) {
899 var _a, _b;
900 if (typeof window !== "undefined" && ((_b = (_a = window.wp) == null ? void 0 : _a.i18n) == null ? void 0 : _b.sprintf)) {
901 return window.wp.i18n.sprintf(format, ...args);
902 }
903 return sprintf$1(
904 format,
905 ...args
906 );
907 }
908 function brandName() {
909 var _a;
910 if (typeof window === "undefined") return "Yatra";
911 return ((_a = window.yatraAdmin) == null ? void 0 : _a.brandName) || "Yatra";
912 }
913 const ToastContext = reactExports.createContext(void 0);
914 const useToast = () => {
915 const context = reactExports.useContext(ToastContext);
916 if (!context) {
917 throw new Error("useToast must be used within ToastProvider");
918 }
919 return context;
920 };
921 const ToastProvider = ({
922 children
923 }) => {
924 const [toasts, setToasts] = reactExports.useState([]);
925 const showToast = reactExports.useCallback(
926 (message, type = "success", duration = 4e3) => {
927 const id = `toast-${Date.now()}-${Math.random()}`;
928 const newToast = { id, message, type, duration };
929 setToasts((prev) => [...prev, newToast]);
930 if (duration > 0) {
931 setTimeout(() => {
932 removeToast(id);
933 }, duration);
934 }
935 },
936 // eslint-disable-next-line react-hooks/exhaustive-deps
937 []
938 );
939 const removeToast = reactExports.useCallback((id) => {
940 setToasts((prev) => prev.filter((toast) => toast.id !== id));
941 }, []);
942 return /* @__PURE__ */ jsxRuntimeExports.jsxs(ToastContext.Provider, { value: { showToast, removeToast }, children: [
943 children,
944 /* @__PURE__ */ jsxRuntimeExports.jsx(ToastContainer, { toasts, onRemove: removeToast })
945 ] });
946 };
947 const ToastContainer = ({
948 toasts,
949 onRemove
950 }) => {
951 const topOffset = React.useMemo(() => {
952 if (typeof document === "undefined") return 16;
953 if (!document.body.classList.contains("admin-bar")) return 16;
954 const small = typeof window !== "undefined" && window.innerWidth <= 782;
955 return (small ? 46 : 32) + 16;
956 }, []);
957 if (toasts.length === 0) return null;
958 return /* @__PURE__ */ jsxRuntimeExports.jsx(
959 "div",
960 {
961 style: { top: topOffset },
962 className: "fixed right-4 z-[100000] flex flex-col gap-2 pointer-events-none",
963 children: toasts.map((toast) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToastItem, { toast, onRemove }, toast.id))
964 }
965 );
966 };
967 const ToastItem = ({ toast, onRemove }) => {
968 const [isVisible, setIsVisible] = reactExports.useState(false);
969 reactExports.useEffect(() => {
970 setTimeout(() => setIsVisible(true), 10);
971 }, []);
972 const handleRemove = () => {
973 setIsVisible(false);
974 setTimeout(() => onRemove(toast.id), 300);
975 };
976 const getIcon = () => {
977 switch (toast.type) {
978 case "success":
979 return /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCircle2, { className: "w-5 h-5 text-green-600" });
980 case "error":
981 return /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-5 h-5 text-red-600" });
982 case "warning":
983 return /* @__PURE__ */ jsxRuntimeExports.jsx(AlertTriangle, { className: "w-5 h-5 text-yellow-600" });
984 case "info":
985 return /* @__PURE__ */ jsxRuntimeExports.jsx(Info, { className: "w-5 h-5 text-blue-600" });
986 default:
987 return /* @__PURE__ */ jsxRuntimeExports.jsx(Info, { className: "w-5 h-5 text-gray-600" });
988 }
989 };
990 const getStyles = () => {
991 switch (toast.type) {
992 case "success":
993 return "bg-green-50 border-green-200 text-green-800 dark:bg-green-900/20 dark:border-green-800 dark:text-green-400";
994 case "error":
995 return "bg-red-50 border-red-200 text-red-800 dark:bg-red-900/20 dark:border-red-800 dark:text-red-400";
996 case "warning":
997 return "bg-yellow-50 border-yellow-200 text-yellow-800 dark:bg-yellow-900/20 dark:border-yellow-800 dark:text-yellow-400";
998 case "info":
999 return "bg-blue-50 border-blue-200 text-blue-800 dark:bg-blue-900/20 dark:border-blue-800 dark:text-blue-400";
1000 default:
1001 return "bg-gray-50 border-gray-200 text-gray-800 dark:bg-gray-900/20 dark:border-gray-800 dark:text-gray-400";
1002 }
1003 };
1004 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1005 "div",
1006 {
1007 className: `
1008 pointer-events-auto
1009 flex items-start gap-3
1010 p-4 rounded-lg border
1011 shadow-lg backdrop-blur-sm
1012 min-w-[320px] max-w-[400px]
1013 transition-all duration-300 ease-out
1014 ${isVisible ? "translate-x-0 opacity-100" : "translate-x-full opacity-0"}
1015 ${getStyles()}
1016 `,
1017 children: [
1018 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 mt-0.5", children: getIcon() }),
1019 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 text-sm font-medium", children: toast.message }),
1020 /* @__PURE__ */ jsxRuntimeExports.jsx(
1021 "button",
1022 {
1023 onClick: handleRemove,
1024 className: "flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors",
1025 "aria-label": __("Close", "yatra"),
1026 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
1027 }
1028 )
1029 ]
1030 }
1031 );
1032 };
1033 const API_ENDPOINTS = {
1034 // Bookings
1035 BOOKINGS: "/bookings",
1036 BOOKING_GET: (id) => `/bookings/${id}`,
1037 BOOKING_STATUS: (id) => `/bookings/${id}/status`,
1038 BOOKING_DELETE: (id) => `/bookings/${id}`,
1039 BOOKINGS_BULK: "/bookings/bulk",
1040 BOOKINGS_STATS: "/bookings/stats",
1041 /** POST body: `{ booking_id }` — returns `{ checkout_url }` in `data`. */
1042 PAYMENT_REMAINING_SESSION: "/payment/remaining/session",
1043 BOOKING_CONSENT_STATUS: (id) => `/bookings/${id}/consent-status`,
1044 // Customers
1045 CUSTOMERS: "/customers",
1046 CUSTOMER_GET: (id) => `/customers/${id}`,
1047 CUSTOMER_DELETE: (id) => `/customers/${id}`,
1048 CUSTOMERS_BULK: "/customers/bulk",
1049 CUSTOMER_STATS: "/customers/stats",
1050 CUSTOMER_BOOKINGS: (id) => `/customers/${id}/bookings`,
1051 CUSTOMER_ME: "/customers/me",
1052 CUSTOMER_CHANGE_PASSWORD: "/customers/me/password",
1053 CUSTOMER_CHANGE_EMAIL: "/customers/me/email",
1054 CUSTOMER_RESEND_EMAIL_CHANGE: "/customers/me/email/resend",
1055 CUSTOMER_MY_BOOKINGS: "/customers/my-bookings",
1056 CUSTOMER_MY_PAYMENTS: "/customers/my-payments",
1057 CUSTOMER_MY_DOCUMENTS: "/customers/my-documents",
1058 CUSTOMER_MY_SUPPORT_TICKETS: "/customers/my-support-tickets",
1059 /** GET single booking for current user (details view). */
1060 CUSTOMER_MY_BOOKING: (id) => `/customers/my-bookings/${id}`,
1061 // Travelers
1062 TRAVELERS: "/travelers",
1063 TRAVELERS_BULK: "/travelers/bulk",
1064 // Reviews
1065 REVIEWS: "/reviews",
1066 REVIEW_DELETE: (id) => `/reviews/${id}`,
1067 REVIEW_STATUS: (id) => `/reviews/${id}/status`,
1068 REVIEWS_BULK: "/reviews/bulk",
1069 // Trips
1070 TRIPS: "/trips",
1071 TRIP_GET: (id) => `/trips/${id}`,
1072 TRIP_DELETE: (id) => `/trips/${id}`,
1073 TRIP_PERMANENT_DELETE: (id) => `/trips/${id}/permanent-delete`,
1074 TRIP_DUPLICATE: (id) => `/trips/${id}/duplicate`,
1075 TRIPS_STATS: "/trips/stats",
1076 TRIP_ATTRIBUTES: (id) => `/trips/${id}/attributes`,
1077 TRIP_AVAILABLE_DATES: (id) => `/trips/${id}/available-dates`,
1078 // Departures
1079 DEPARTURES: "/departures",
1080 TRIP_DEPARTURES: (tripId) => `/trips/${tripId}/departures`,
1081 DEPARTURE_GET: (tripId, id) => `/trips/${tripId}/departures/${id}`,
1082 DEPARTURE_UPDATE: (tripId, id) => `/trips/${tripId}/departures/${id}`,
1083 DEPARTURE_DELETE: (tripId, id) => `/trips/${tripId}/departures/${id}`,
1084 TRIP_DEPARTURES_PAST: (tripId) => `/trips/${tripId}/departures/past`,
1085 // Recurring Rules
1086 RECURRING_RULES: (tripId) => `/trips/${tripId}/recurring-rules`,
1087 RECURRING_RULE_GET: (tripId, ruleId) => `/trips/${tripId}/recurring-rules/${ruleId}`,
1088 // Payments
1089 PAYMENTS: "/payments",
1090 PAYMENTS_STATS: "/payments/stats",
1091 PAYMENT_GET: (id) => `/payments/${id}`,
1092 PAYMENT_DELETE: (id) => `/payments/${id}`,
1093 // Usage tracking (opt-in telemetry)
1094 USAGE_TRACKING_STATUS: "/usage-tracking/status",
1095 USAGE_TRACKING_SETTINGS: "/usage-tracking/settings",
1096 USAGE_TRACKING_SEND: "/usage-tracking/send",
1097 USAGE_TRACKING_PREVIEW: "/usage-tracking/preview",
1098 USAGE_TRACKING_CLEAR_CACHE: "/usage-tracking/clear-cache",
1099 USAGE_TRACKING_DELETE_SNAPSHOTS: "/usage-tracking/delete-snapshots",
1100 // Settings
1101 SETTINGS: "/settings",
1102 SETTINGS_GROUP: (group) => `/settings?group=${group}`,
1103 // Booking form config, optionally resolved for one trip (Pro form conditions)
1104 SETTINGS_BOOKING_FORM: "/settings/booking-form",
1105 SETTINGS_PAGES: "/settings/pages",
1106 SETTINGS_FLUSH_REWRITE_RULES: "/settings/flush-rewrite-rules",
1107 SETTINGS_CHECK_SHORTCODE: (pageId) => `/settings/check-shortcode/${pageId}`,
1108 SETTINGS_INSERT_SHORTCODE: (pageId) => `/settings/insert-shortcode/${pageId}`,
1109 SETTINGS_EMAIL_TEMPLATE_PREVIEW: "/settings/email-template-preview",
1110 // Payment (definitions for admin Settings UI)
1111 PAYMENT_GATEWAY_DEFINITIONS: "/payment/gateways/definitions",
1112 // Enquiries
1113 ENQUIRIES: "/enquiries",
1114 ENQUIRY_GET: (id) => `/enquiries/${id}`,
1115 ENQUIRY_DELETE: (id) => `/enquiries/${id}`,
1116 ENQUIRIES_BULK: "/enquiries/bulk",
1117 ENQUIRY_STATS: "/enquiries/stats",
1118 ENQUIRY_RESPOND: (id) => `/enquiries/${id}/respond`,
1119 // Scheduled balance payments (Yatra Pro — Scheduled Payments module).
1120 // These routes only exist while that module is enabled; the UI is gated on
1121 // the same `scheduledPaymentsEnabled` flag the module localizes.
1122 SCHEDULED_PAYMENTS: "/scheduled-payments",
1123 SCHEDULED_PAYMENTS_STATS: "/scheduled-payments/stats",
1124 SCHEDULED_PAYMENT_CANCEL: (id) => `/scheduled-payments/${id}/cancel`,
1125 SCHEDULED_PAYMENTS_OUTSTANDING: "/scheduled-payments/outstanding",
1126 SCHEDULED_PAYMENT_SEND_LINK: (bookingId) => `/scheduled-payments/outstanding/${bookingId}/send-link`,
1127 // Reports
1128 REPORTS: "/reports",
1129 REPORTS_EXPORT: (type) => `/reports/export?type=${type}`,
1130 // Modules
1131 MODULES: "/modules",
1132 // Facebook Pixel
1133 FACEBOOK_PIXEL_SETTINGS: "/facebook-pixel/settings",
1134 FACEBOOK_PIXEL_TEST: "/facebook-pixel/test",
1135 FACEBOOK_PIXEL_TEST_TOKEN: "/facebook-pixel/test-token",
1136 FACEBOOK_PIXEL_EVENTS: "/facebook-pixel/events",
1137 FACEBOOK_PIXEL_EVENT_LOGS: "/facebook-pixel/event-logs",
1138 // Google Analytics 4
1139 GOOGLE_ANALYTICS_SETTINGS: "/google-analytics/settings",
1140 GOOGLE_ANALYTICS_TEST: "/google-analytics/test",
1141 GOOGLE_ANALYTICS_VALIDATE_MEASUREMENT_ID: "/google-analytics/validate/measurement-id",
1142 GOOGLE_ANALYTICS_VALIDATE_API_SECRET: "/google-analytics/validate/api-secret",
1143 GOOGLE_ANALYTICS_EVENTS: "/google-analytics/events",
1144 GOOGLE_ANALYTICS_EVENT_LOGS: "/google-analytics/logs",
1145 // Abandoned Bookings
1146 ABANDONED_BOOKINGS: "/abandoned-bookings",
1147 ABANDONED_BOOKING_GET: (id) => `/abandoned-bookings/${id}`,
1148 ABANDONED_BOOKING_DELETE: (id) => `/abandoned-bookings/${id}`,
1149 ABANDONED_BOOKINGS_SETTINGS: "/abandoned-bookings/settings",
1150 ABANDONED_BOOKINGS_STATISTICS: "/abandoned-bookings/statistics",
1151 ABANDONED_BOOKING_SEND_EMAIL: (id) => `/abandoned-bookings/${id}/send-email`,
1152 ABANDONED_BOOKINGS_CAMPAIGNS: "/abandoned-bookings/campaigns",
1153 ABANDONED_BOOKINGS_CAMPAIGN_GET: (id) => `/abandoned-bookings/campaigns/${id}`,
1154 // Google Calendar
1155 GOOGLE_CALENDAR_SETTINGS: "/google-calendar/settings",
1156 GOOGLE_CALENDAR_CONNECT: "/google-calendar/connect",
1157 GOOGLE_CALENDAR_DISCONNECT: "/google-calendar/disconnect",
1158 GOOGLE_CALENDAR_SYNC_ALL: "/google-calendar/sync-all",
1159 GOOGLE_CALENDAR_RESYNC: "/google-calendar/resync",
1160 // Tools
1161 TOOLS_SYSTEM_STATUS: "/tools/system-status",
1162 TOOLS_ACTIVE_JOBS: "/tools/active-jobs",
1163 TOOLS_LOGS: (type, page) => `/tools/logs/${type}?page=${page}`,
1164 TOOLS_LOGS_CLEAR: (type) => `/tools/logs/${type}/clear`,
1165 TOOLS_EXPORT_JOB: "/tools/export-job",
1166 TOOLS_JOB_ACTION: (endpoint, jobId) => `/tools/${endpoint}/${jobId}`,
1167 TOOLS_EXPORT_DOWNLOAD: (jobId) => `/tools/export-job/${jobId}/download`,
1168 TOOLS_EXPORT_DELETE: (jobId) => `/tools/export-job/${jobId}`,
1169 TOOLS_EXPORT_STATUS: (jobId) => `/tools/export-job/${jobId}`,
1170 TOOLS_IMPORT_JOB: "/tools/import-job",
1171 TOOLS_IMPORT_JOB_GET: (jobId) => `/tools/import-job/${jobId}`,
1172 TOOLS_ALL_JOBS: "/tools/all-jobs",
1173 TOOLS_CRON_JOBS: "/tools/cron-jobs",
1174 TOOLS_CRON_RUN: (hook) => `/tools/cron-jobs/${hook}/run`,
1175 TOOLS_CLEAR_CACHE: "/tools/clear-cache",
1176 TOOLS_CACHE_VIEW: "/cache/view",
1177 TOOLS_CACHE_CLEAR_ITEM: "/cache/clear-item",
1178 // Migration
1179 MIGRATION_STATUS: "/migration/status",
1180 MIGRATION_CLEAR: "/migration/clear",
1181 MIGRATION_PROGRESS: "/migration/progress",
1182 MIGRATION_MIGRATE_ALL: "/migration/migrate-all",
1183 MIGRATION_CANCEL: "/migration/cancel",
1184 // Payment Gateways
1185 PAYMENT_GATEWAYS: "/payment/gateways",
1186 // Signed Consents
1187 SIGNED_CONSENTS: "/signed-consents",
1188 SIGNED_CONSENT_GET: (id) => `/signed-consents/${id}`,
1189 SIGNED_CONSENT_PDF: (id) => `/signed-consents/${id}/pdf`,
1190 SIGNED_CONSENTS_PREVIEW: "/signed-consents/preview",
1191 // Dynamic Pricing
1192 DYNAMIC_PRICING_SETTINGS: "/dynamic-pricing/settings",
1193 // Availability
1194 AVAILABILITY: (tripId) => `/trips/${tripId}/availability`,
1195 // Itinerary
1196 ITINERARY: "/itinerary",
1197 ITINERARY_GET: (id, mode) => mode ? `/itinerary/${id}?mode=${mode}` : `/itinerary/${id}`,
1198 ITINERARY_DELETE: (id, mode) => mode ? `/itinerary/${id}?mode=${mode}` : `/itinerary/${id}`,
1199 ITINERARY_BY_TRIP: (tripId) => `/itinerary?trip_id=${tripId}`,
1200 ITINERARY_DAY_ENTRY_BY_DAY_ID: (dayId) => `/itinerary/day-entry-by-day-id/${dayId}`,
1201 // One-shot save of every activity for a single day. Replaces N sequential
1202 // PUTs (one per activity) with a single batch request — the controller
1203 // dispatches each row to update/create and returns per-row results.
1204 ITINERARY_DAY_ACTIVITIES_BULK: (dayId) => `/itinerary/day/${dayId}/activities/bulk`,
1205 // Saved Trips
1206 SAVED_TRIPS: "/saved-trips",
1207 // Email automation (Yatra Pro module — routes registered when module is active)
1208 EMAIL_TEMPLATES: "/email-templates",
1209 EMAIL_TEMPLATE_GET: (id) => `/email-templates/${id}`,
1210 EMAIL_TEMPLATE_PREVIEW: (id) => `/email-templates/${id}/preview`,
1211 EMAIL_TEMPLATE_TEST: (id) => `/email-templates/${id}/test`,
1212 EMAIL_TEMPLATE_DUPLICATE: (id) => `/email-templates/${id}/duplicate`,
1213 EMAIL_TEMPLATE_VARIABLES: "/email-templates/variables",
1214 // Trip-specific overrides of a global template (Pro Email Automation)
1215 EMAIL_TEMPLATE_OVERRIDE: (id) => `/email-templates/${id}/override`,
1216 EMAIL_TEMPLATE_OVERRIDES_REORDER: "/email-templates/overrides/reorder",
1217 EMAIL_TEMPLATE_RESOLVE: "/email-templates/resolve",
1218 EMAIL_TEMPLATE_EVENTS: "/email-templates/events",
1219 EMAIL_SEQUENCES: "/email-sequences",
1220 EMAIL_SEQUENCE_GET: (id) => `/email-sequences/${id}`,
1221 EMAIL_LOGS: "/email-logs",
1222 // Notices (Admin UI + WP notices)
1223 NOTICES: "/notices",
1224 NOTICE_DISMISS: (id) => `/notices/${id}/dismiss`
1225 };
1226 const serializePayload = (body) => {
1227 if (!body) {
1228 return void 0;
1229 }
1230 if (typeof body === "string") {
1231 return body;
1232 }
1233 if (body instanceof URLSearchParams) {
1234 return body.toString();
1235 }
1236 if (typeof FormData !== "undefined" && body instanceof FormData) {
1237 const entries = {};
1238 body.forEach((value, key) => {
1239 entries[key] = value;
1240 });
1241 try {
1242 return JSON.stringify(entries, null, 2);
1243 } catch {
1244 return "[FormData]";
1245 }
1246 }
1247 if (typeof body === "object") {
1248 try {
1249 return JSON.stringify(body, null, 2);
1250 } catch {
1251 return String(body);
1252 }
1253 }
1254 return String(body);
1255 };
1256 const formatRequestUrl = (rawUrl) => {
1257 try {
1258 const parsed = new URL(rawUrl, window.location.origin);
1259 const params = new URLSearchParams(parsed.search);
1260 const restRoute = params.get("rest_route");
1261 if (restRoute) {
1262 params.delete("rest_route");
1263 const decodedRoute = decodeURIComponent(restRoute);
1264 const normalizedRoute = decodedRoute.startsWith("/") ? decodedRoute : `/${decodedRoute}`;
1265 const remainingParams = params.toString();
1266 return `${parsed.origin}${normalizedRoute}${remainingParams ? `?${remainingParams}` : ""}`;
1267 }
1268 return parsed.toString();
1269 } catch {
1270 return rawUrl;
1271 }
1272 };
1273 class ApiError extends Error {
1274 constructor(message, response, requestInfo) {
1275 super(message);
1276 this.name = "ApiError";
1277 this.response = response;
1278 this.requestInfo = requestInfo;
1279 }
1280 }
1281 class ApiClient {
1282 /** Public account page uses `yatraAccountPage`; admin uses `yatraAdmin`. Resolve per request so module load order never leaves an empty nonce. */
1283 resolveBaseUrl() {
1284 var _a, _b;
1285 if (typeof window === "undefined") {
1286 return "/wp-json/yatra/v1";
1287 }
1288 const w = window;
1289 const raw = ((_a = w.yatraAccountPage) == null ? void 0 : _a.apiUrl) || ((_b = w.yatraAdmin) == null ? void 0 : _b.apiUrl) || "/wp-json/yatra/v1";
1290 return raw.endsWith("/") ? raw.slice(0, -1) : raw;
1291 }
1292 resolveNonce() {
1293 var _a, _b;
1294 if (typeof window === "undefined") {
1295 return "";
1296 }
1297 const w = window;
1298 return ((_a = w.yatraAccountPage) == null ? void 0 : _a.nonce) || ((_b = w.yatraAdmin) == null ? void 0 : _b.nonce) || "";
1299 }
1300 async request(endpoint, options = {}, queryParams) {
1301 const [endpointPath, endpointQuery] = endpoint.split("?");
1302 const cleanEndpoint = endpointPath.startsWith("/") ? endpointPath : `/${endpointPath}`;
1303 let url;
1304 const baseUrl = this.resolveBaseUrl();
1305 if (baseUrl.includes("?rest_route=")) {
1306 const [base, queryString] = baseUrl.split("?");
1307 const params = new URLSearchParams(queryString);
1308 const restRoute = params.get("rest_route") || "";
1309 params.set("rest_route", restRoute + cleanEndpoint);
1310 if (endpointQuery) {
1311 const endpointParams = new URLSearchParams(endpointQuery);
1312 endpointParams.forEach((value, key) => {
1313 params.append(key, value);
1314 });
1315 }
1316 if (queryParams) {
1317 queryParams.forEach((value, key) => {
1318 params.append(key, value);
1319 });
1320 }
1321 url = `${base}?${params.toString()}`;
1322 } else {
1323 url = `${baseUrl}${cleanEndpoint}`;
1324 if (endpointQuery || queryParams) {
1325 const params = new URLSearchParams();
1326 if (endpointQuery) {
1327 const endpointParams = new URLSearchParams(endpointQuery);
1328 endpointParams.forEach((value, key) => {
1329 params.append(key, value);
1330 });
1331 }
1332 if (queryParams) {
1333 queryParams.forEach((value, key) => {
1334 params.append(key, value);
1335 });
1336 }
1337 url += `?${params.toString()}`;
1338 }
1339 }
1340 const isFormDataBody = typeof FormData !== "undefined" && options.body instanceof FormData;
1341 const headers = {
1342 "X-WP-Nonce": this.resolveNonce(),
1343 ...options.headers
1344 };
1345 if (!isFormDataBody) {
1346 const hasContentTypeHeader = headers instanceof Headers && headers.has("Content-Type") || !(headers instanceof Headers) && Object.keys(headers).some(
1347 (k) => k.toLowerCase() === "content-type"
1348 );
1349 if (!hasContentTypeHeader) {
1350 headers["Content-Type"] = "application/json";
1351 }
1352 }
1353 const method = (options.method || "GET").toUpperCase();
1354 const serializedPayload = serializePayload(options.body);
1355 const response = await fetch(url, {
1356 ...options,
1357 headers,
1358 credentials: "include"
1359 });
1360 if (!response.ok) {
1361 const raw = await response.text();
1362 let data = null;
1363 if (raw) {
1364 try {
1365 data = JSON.parse(raw);
1366 } catch {
1367 data = raw;
1368 }
1369 }
1370 const message = typeof data === "object" && (data == null ? void 0 : data.message) || typeof data === "string" && data || response.statusText || `HTTP error! status: ${response.status}`;
1371 throw new ApiError(
1372 message,
1373 {
1374 status: response.status,
1375 statusText: response.statusText,
1376 data
1377 },
1378 {
1379 url: formatRequestUrl(url),
1380 method,
1381 payload: serializedPayload
1382 }
1383 );
1384 }
1385 if (response.status === 204) {
1386 return null;
1387 }
1388 const text = await response.text();
1389 if (!text) {
1390 return null;
1391 }
1392 try {
1393 return JSON.parse(text);
1394 } catch {
1395 return text;
1396 }
1397 }
1398 async requestBlob(endpoint, options = {}, queryParams) {
1399 const [endpointPath, endpointQuery] = endpoint.split("?");
1400 const cleanEndpoint = endpointPath.startsWith("/") ? endpointPath : `/${endpointPath}`;
1401 let url;
1402 const baseUrl = this.resolveBaseUrl();
1403 if (baseUrl.includes("?rest_route=")) {
1404 const [base, queryString] = baseUrl.split("?");
1405 const params = new URLSearchParams(queryString);
1406 const restRoute = params.get("rest_route") || "";
1407 params.set("rest_route", restRoute + cleanEndpoint);
1408 if (endpointQuery) {
1409 const endpointParams = new URLSearchParams(endpointQuery);
1410 endpointParams.forEach((value, key) => {
1411 params.append(key, value);
1412 });
1413 }
1414 if (queryParams) {
1415 queryParams.forEach((value, key) => {
1416 params.append(key, value);
1417 });
1418 }
1419 url = `${base}?${params.toString()}`;
1420 } else {
1421 url = `${baseUrl}${cleanEndpoint}`;
1422 if (endpointQuery || queryParams) {
1423 const params = new URLSearchParams();
1424 if (endpointQuery) {
1425 const endpointParams = new URLSearchParams(endpointQuery);
1426 endpointParams.forEach((value, key) => {
1427 params.append(key, value);
1428 });
1429 }
1430 if (queryParams) {
1431 queryParams.forEach((value, key) => {
1432 params.append(key, value);
1433 });
1434 }
1435 url += `?${params.toString()}`;
1436 }
1437 }
1438 const isFormDataBody = typeof FormData !== "undefined" && options.body instanceof FormData;
1439 const headers = {
1440 "X-WP-Nonce": this.resolveNonce(),
1441 ...options.headers
1442 };
1443 if (!isFormDataBody) {
1444 const hasContentTypeHeader = headers instanceof Headers && headers.has("Content-Type") || !(headers instanceof Headers) && Object.keys(headers).some(
1445 (k) => k.toLowerCase() === "content-type"
1446 );
1447 if (!hasContentTypeHeader) {
1448 headers["Content-Type"] = "application/json";
1449 }
1450 }
1451 const response = await fetch(url, {
1452 ...options,
1453 headers,
1454 credentials: "include"
1455 });
1456 if (!response.ok) {
1457 const error = await response.json().catch(() => ({ message: "An error occurred" }));
1458 throw new Error(
1459 error.message || `HTTP error! status: ${response.status}`
1460 );
1461 }
1462 return response.blob();
1463 }
1464 async get(endpoint, config) {
1465 let queryParams;
1466 if (config == null ? void 0 : config.params) {
1467 queryParams = new URLSearchParams();
1468 Object.entries(config.params).forEach(([key, value]) => {
1469 if (value !== void 0 && value !== null) {
1470 queryParams.append(key, String(value));
1471 }
1472 });
1473 }
1474 return this.request(
1475 endpoint,
1476 {
1477 method: "GET"
1478 },
1479 queryParams
1480 );
1481 }
1482 async getBlob(endpoint, config) {
1483 let queryParams;
1484 if (config == null ? void 0 : config.params) {
1485 queryParams = new URLSearchParams();
1486 Object.entries(config.params).forEach(([key, value]) => {
1487 if (value !== void 0 && value !== null) {
1488 queryParams.append(key, String(value));
1489 }
1490 });
1491 }
1492 return this.requestBlob(endpoint, { method: "GET" }, queryParams);
1493 }
1494 async post(endpoint, data) {
1495 return this.request(endpoint, {
1496 method: "POST",
1497 body: data instanceof FormData ? data : JSON.stringify(data)
1498 });
1499 }
1500 async put(endpoint, data) {
1501 return this.request(endpoint, {
1502 method: "PUT",
1503 body: data instanceof FormData ? data : JSON.stringify(data)
1504 });
1505 }
1506 async patch(endpoint, data) {
1507 return this.request(endpoint, {
1508 method: "PATCH",
1509 body: data instanceof FormData ? data : JSON.stringify(data)
1510 });
1511 }
1512 async delete(endpoint, config) {
1513 return this.request(endpoint, {
1514 method: "DELETE",
1515 body: (config == null ? void 0 : config.data) ? JSON.stringify(config.data) : void 0
1516 });
1517 }
1518 }
1519 const apiClient = new ApiClient();
1520 async function fetchPaymentNormalized(id) {
1521 const raw = await apiClient.get(API_ENDPOINTS.PAYMENT_GET(id));
1522 if (raw == null) {
1523 return null;
1524 }
1525 if (typeof raw !== "object") {
1526 return null;
1527 }
1528 const r = raw;
1529 if (r.success === true && r.data != null && typeof r.data === "object") {
1530 return { success: true, data: r.data };
1531 }
1532 if (r.id !== void 0 && r.id !== null) {
1533 return { success: true, data: r };
1534 }
1535 return {
1536 success: false,
1537 message: String(r.message ?? "Payment not found")
1538 };
1539 }
1540 class WpApiClient {
1541 constructor() {
1542 var _a, _b;
1543 const rawUrl = ((_a = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a.restUrl) || "/wp-json";
1544 this.baseUrl = rawUrl.endsWith("/") ? rawUrl.slice(0, -1) : rawUrl;
1545 this.nonce = ((_b = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _b.nonce) || "";
1546 }
1547 async get(endpoint) {
1548 const cleanEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
1549 const url = `${this.baseUrl}${cleanEndpoint}`;
1550 const response = await fetch(url, {
1551 method: "GET",
1552 headers: {
1553 "X-WP-Nonce": this.nonce
1554 },
1555 credentials: "include"
1556 });
1557 if (!response.ok) {
1558 const error = await response.json().catch(() => ({ message: "An error occurred" }));
1559 throw new Error(
1560 error.message || `HTTP error! status: ${response.status}`
1561 );
1562 }
1563 return response.json();
1564 }
1565 }
1566 const wpClient = new WpApiClient();
1567 const wpService = {
1568 getMedia: (id) => wpClient.get(`/wp/v2/media/${id}`)
1569 };
1570 const ajaxService = {
1571 post: async (action, data) => {
1572 var _a;
1573 const siteUrl = ((_a = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a.siteUrl) || "";
1574 const url = `${siteUrl}/wp-admin/admin-ajax.php`;
1575 const body = new URLSearchParams({
1576 action,
1577 ...Object.fromEntries(
1578 Object.entries(data).map(([k, v]) => [k, v == null ? "" : String(v)])
1579 )
1580 });
1581 const response = await fetch(url, {
1582 method: "POST",
1583 headers: {
1584 "Content-Type": "application/x-www-form-urlencoded"
1585 },
1586 body,
1587 credentials: "include"
1588 });
1589 return response.json();
1590 }
1591 };
1592 const apiService = {
1593 // Bookings
1594 getBookings: (params) => apiClient.get(API_ENDPOINTS.BOOKINGS, { params }),
1595 getBooking: (id) => apiClient.get(API_ENDPOINTS.BOOKING_GET(id)),
1596 getTripAvailableDates: (id) => apiClient.get(API_ENDPOINTS.TRIP_AVAILABLE_DATES(id)),
1597 createBooking: (data) => apiClient.post(API_ENDPOINTS.BOOKINGS, data),
1598 updateBooking: (id, data) => apiClient.put(API_ENDPOINTS.BOOKING_GET(id), data),
1599 updateBookingStatus: (id, status) => apiClient.put(API_ENDPOINTS.BOOKING_STATUS(id), { status }),
1600 deleteBooking: (id) => apiClient.delete(API_ENDPOINTS.BOOKING_DELETE(id)),
1601 getBookingsStats: () => apiClient.get(API_ENDPOINTS.BOOKINGS_STATS),
1602 // Customers
1603 getCustomers: (params) => apiClient.get(API_ENDPOINTS.CUSTOMERS, { params }),
1604 getCustomer: (id) => apiClient.get(API_ENDPOINTS.CUSTOMER_GET(id)),
1605 deleteCustomer: (id) => apiClient.delete(API_ENDPOINTS.CUSTOMER_DELETE(id)),
1606 createCustomer: (data) => apiClient.post(API_ENDPOINTS.CUSTOMERS, data),
1607 updateCustomer: (id, data) => apiClient.put(API_ENDPOINTS.CUSTOMER_GET(id), data),
1608 updateCustomerStatus: (id, status) => apiClient.put(API_ENDPOINTS.CUSTOMER_GET(id), { status }),
1609 getCustomerBookings: (id) => apiClient.get(API_ENDPOINTS.CUSTOMER_BOOKINGS(id)),
1610 getCustomerStats: () => apiClient.get(API_ENDPOINTS.CUSTOMER_STATS),
1611 // Travelers
1612 getTravelers: (params) => apiClient.get(API_ENDPOINTS.TRAVELERS, { params }),
1613 bulkTravelersAction: (action, ids) => apiClient.put(API_ENDPOINTS.TRAVELERS_BULK, { action, ids }),
1614 // Reviews
1615 getReviews: (params) => apiClient.get(API_ENDPOINTS.REVIEWS, { params }),
1616 deleteReview: (id) => apiClient.delete(API_ENDPOINTS.REVIEW_DELETE(id)),
1617 updateReviewStatus: (id, status) => apiClient.put(API_ENDPOINTS.REVIEW_STATUS(id), { status }),
1618 bulkReviewsAction: (action, ids) => apiClient.put(API_ENDPOINTS.REVIEWS_BULK, { action, ids }),
1619 // Trips
1620 getTrips: (params) => apiClient.get(API_ENDPOINTS.TRIPS, { params }),
1621 getTrip: (id) => apiClient.get(API_ENDPOINTS.TRIP_GET(id)),
1622 deleteTrip: (id) => apiClient.delete(API_ENDPOINTS.TRIP_DELETE(id)),
1623 duplicateTrip: (id) => apiClient.post(API_ENDPOINTS.TRIP_DUPLICATE(id)),
1624 // Settings
1625 getSettings: (group) => apiClient.get(
1626 group ? API_ENDPOINTS.SETTINGS_GROUP(group) : API_ENDPOINTS.SETTINGS
1627 ),
1628 // Booking form config as a trip's checkout renders it (per-trip conditions
1629 // resolved). Without tripId: the global config, conditions included.
1630 getBookingFormConfig: (tripId) => apiClient.get(API_ENDPOINTS.SETTINGS_BOOKING_FORM, {
1631 params: tripId ? { trip_id: tripId } : void 0
1632 }),
1633 // Notices
1634 getNotices: () => apiClient.get(API_ENDPOINTS.NOTICES),
1635 dismissNotice: (id) => apiClient.post(API_ENDPOINTS.NOTICE_DISMISS(id), {}),
1636 // Payments
1637 getPayment: (id) => fetchPaymentNormalized(id),
1638 deletePayment: (id) => apiClient.delete(API_ENDPOINTS.PAYMENT_DELETE(id)),
1639 getPayments: (params) => apiClient.get(API_ENDPOINTS.PAYMENTS, { params }),
1640 getPaymentsStats: () => apiClient.get(API_ENDPOINTS.PAYMENTS_STATS),
1641 createPayment: (data) => apiClient.post(API_ENDPOINTS.PAYMENTS, data),
1642 updatePayment: (id, data) => apiClient.put(API_ENDPOINTS.PAYMENT_GET(id), data),
1643 updatePaymentStatus: (id, status) => apiClient.put(API_ENDPOINTS.PAYMENT_GET(id), { status }),
1644 bulkPaymentsAction: (action, ids) => Promise.all(
1645 ids.map((id) => {
1646 if (action === "delete") {
1647 return apiClient.delete(API_ENDPOINTS.PAYMENT_DELETE(id));
1648 } else {
1649 return apiClient.put(API_ENDPOINTS.PAYMENT_GET(id), {
1650 status: action
1651 });
1652 }
1653 })
1654 ),
1655 // Modules
1656 getModules: () => apiClient.get(API_ENDPOINTS.MODULES),
1657 // Facebook Pixel
1658 getFacebookPixelSettings: () => apiClient.get(API_ENDPOINTS.FACEBOOK_PIXEL_SETTINGS),
1659 testFacebookPixel: (pixelId) => apiClient.post(API_ENDPOINTS.FACEBOOK_PIXEL_TEST, { pixel_id: pixelId }),
1660 testFacebookPixelToken: (accessToken) => apiClient.post(API_ENDPOINTS.FACEBOOK_PIXEL_TEST_TOKEN, {
1661 access_token: accessToken
1662 }),
1663 getFacebookPixelEvents: () => apiClient.get(API_ENDPOINTS.FACEBOOK_PIXEL_EVENTS),
1664 getFacebookPixelEventLogs: () => apiClient.get(API_ENDPOINTS.FACEBOOK_PIXEL_EVENT_LOGS),
1665 clearFacebookPixelEventLogs: () => apiClient.delete(API_ENDPOINTS.FACEBOOK_PIXEL_EVENT_LOGS),
1666 // Google Analytics 4
1667 getGoogleAnalyticsSettings: () => apiClient.get(API_ENDPOINTS.GOOGLE_ANALYTICS_SETTINGS),
1668 testGoogleAnalytics: (measurementId) => apiClient.post(API_ENDPOINTS.GOOGLE_ANALYTICS_TEST, {
1669 measurement_id: measurementId
1670 }),
1671 validateGoogleAnalyticsMeasurementId: (measurementId) => apiClient.post(API_ENDPOINTS.GOOGLE_ANALYTICS_VALIDATE_MEASUREMENT_ID, {
1672 measurement_id: measurementId
1673 }),
1674 validateGoogleAnalyticsApiSecret: (measurementId, apiSecret) => apiClient.post(API_ENDPOINTS.GOOGLE_ANALYTICS_VALIDATE_API_SECRET, {
1675 measurement_id: measurementId,
1676 api_secret: apiSecret
1677 }),
1678 getGoogleAnalyticsEvents: () => apiClient.get(API_ENDPOINTS.GOOGLE_ANALYTICS_EVENTS),
1679 getGoogleAnalyticsEventLogs: () => apiClient.get(API_ENDPOINTS.GOOGLE_ANALYTICS_EVENT_LOGS),
1680 clearGoogleAnalyticsEventLogs: () => apiClient.delete(API_ENDPOINTS.GOOGLE_ANALYTICS_EVENT_LOGS),
1681 // Payment Gateways
1682 getPaymentGateways: () => apiClient.get(API_ENDPOINTS.PAYMENT_GATEWAYS),
1683 // Abandoned Bookings
1684 getAbandonedBookings: (params) => apiClient.get(API_ENDPOINTS.ABANDONED_BOOKINGS, { params }),
1685 getAbandonedBooking: (id) => apiClient.get(API_ENDPOINTS.ABANDONED_BOOKING_GET(id)),
1686 deleteAbandonedBooking: (id) => apiClient.delete(API_ENDPOINTS.ABANDONED_BOOKING_DELETE(id)),
1687 getAbandonedBookingsSettings: () => apiClient.get(API_ENDPOINTS.ABANDONED_BOOKINGS_SETTINGS),
1688 saveAbandonedBookingsSettings: (data) => apiClient.post(API_ENDPOINTS.ABANDONED_BOOKINGS_SETTINGS, data),
1689 getAbandonedBookingsStatistics: () => apiClient.get(API_ENDPOINTS.ABANDONED_BOOKINGS_STATISTICS),
1690 sendAbandonedBookingEmail: (id) => apiClient.post(API_ENDPOINTS.ABANDONED_BOOKING_SEND_EMAIL(id)),
1691 getAbandonedBookingCampaigns: () => apiClient.get(API_ENDPOINTS.ABANDONED_BOOKINGS_CAMPAIGNS),
1692 getAbandonedBookingCampaign: (id) => apiClient.get(API_ENDPOINTS.ABANDONED_BOOKINGS_CAMPAIGN_GET(id)),
1693 createAbandonedBookingCampaign: (data) => apiClient.post(API_ENDPOINTS.ABANDONED_BOOKINGS_CAMPAIGNS, data),
1694 updateAbandonedBookingCampaign: (id, data) => apiClient.put(API_ENDPOINTS.ABANDONED_BOOKINGS_CAMPAIGN_GET(id), data),
1695 // Enquiries
1696 getEnquiries: (params) => apiClient.get(API_ENDPOINTS.ENQUIRIES, { params }),
1697 getEnquiry: (id) => apiClient.get(API_ENDPOINTS.ENQUIRY_GET(id)),
1698 deleteEnquiry: (id) => apiClient.delete(API_ENDPOINTS.ENQUIRY_DELETE(id)),
1699 createEnquiry: (data) => apiClient.post(API_ENDPOINTS.ENQUIRIES, data),
1700 updateEnquiry: (id, data) => apiClient.put(API_ENDPOINTS.ENQUIRY_GET(id), data),
1701 getEnquiriesStats: () => apiClient.get(API_ENDPOINTS.ENQUIRY_STATS),
1702 bulkEnquiriesAction: (action, ids) => apiClient.put(API_ENDPOINTS.ENQUIRIES_BULK, { action, ids }),
1703 respondToEnquiry: (id, data) => apiClient.post(API_ENDPOINTS.ENQUIRY_RESPOND(id), data),
1704 // Scheduled balance payments (Pro module)
1705 getScheduledPayments: (params) => apiClient.get(API_ENDPOINTS.SCHEDULED_PAYMENTS, { params }),
1706 getScheduledPaymentsStats: () => apiClient.get(API_ENDPOINTS.SCHEDULED_PAYMENTS_STATS),
1707 cancelScheduledPayment: (id) => apiClient.post(API_ENDPOINTS.SCHEDULED_PAYMENT_CANCEL(id), {}),
1708 getOutstandingBalances: (params) => apiClient.get(API_ENDPOINTS.SCHEDULED_PAYMENTS_OUTSTANDING, { params }),
1709 sendBalancePaymentLink: (bookingId) => apiClient.post(API_ENDPOINTS.SCHEDULED_PAYMENT_SEND_LINK(bookingId), {}),
1710 // Google Calendar
1711 getGoogleCalendarSettings: () => apiClient.get(API_ENDPOINTS.GOOGLE_CALENDAR_SETTINGS),
1712 connectGoogleCalendar: () => apiClient.post(API_ENDPOINTS.GOOGLE_CALENDAR_CONNECT),
1713 disconnectGoogleCalendar: () => apiClient.post(API_ENDPOINTS.GOOGLE_CALENDAR_DISCONNECT),
1714 syncAllGoogleCalendar: () => apiClient.post(API_ENDPOINTS.GOOGLE_CALENDAR_SYNC_ALL),
1715 /**
1716 * One batch of a full resync. Repeat with the returned `next_cursor` until
1717 * `done` is true — the server processes a slice per call so a large calendar
1718 * can't time out and the UI can show progress.
1719 */
1720 resyncGoogleCalendar: (cursor = 0, limit = 25) => apiClient.post(API_ENDPOINTS.GOOGLE_CALENDAR_RESYNC, { cursor, limit }),
1721 updateGoogleCalendarSettings: (data) => apiClient.post(API_ENDPOINTS.GOOGLE_CALENDAR_SETTINGS, data),
1722 // Signed Consents
1723 getSignedConsents: (params) => apiClient.get(API_ENDPOINTS.SIGNED_CONSENTS, { params }),
1724 getSignedConsent: (id) => apiClient.get(API_ENDPOINTS.SIGNED_CONSENT_GET(id)),
1725 downloadSignedConsentPdf: (id) => apiClient.get(API_ENDPOINTS.SIGNED_CONSENT_PDF(id)),
1726 previewSignedConsent: () => apiClient.get(API_ENDPOINTS.SIGNED_CONSENTS_PREVIEW),
1727 // Tools
1728 getSystemStatus: () => apiClient.get(API_ENDPOINTS.TOOLS_SYSTEM_STATUS),
1729 getActiveJobs: () => apiClient.get(API_ENDPOINTS.TOOLS_ACTIVE_JOBS),
1730 getLogs: (type, page) => apiClient.get(API_ENDPOINTS.TOOLS_LOGS(type, page)),
1731 clearLogs: (type) => apiClient.delete(API_ENDPOINTS.TOOLS_LOGS_CLEAR(type)),
1732 createExportJob: (data) => apiClient.post(API_ENDPOINTS.TOOLS_EXPORT_JOB, data),
1733 performJobAction: (endpoint, jobId) => apiClient.get(API_ENDPOINTS.TOOLS_JOB_ACTION(endpoint, jobId)),
1734 downloadExportJob: (jobId) => apiClient.get(API_ENDPOINTS.TOOLS_EXPORT_DOWNLOAD(jobId)),
1735 downloadExportJobBlob: (jobId) => apiClient.getBlob(API_ENDPOINTS.TOOLS_EXPORT_DOWNLOAD(jobId)),
1736 deleteExportJob: (jobId) => apiClient.delete(API_ENDPOINTS.TOOLS_EXPORT_DELETE(jobId)),
1737 getExportJobStatus: (jobId) => apiClient.get(API_ENDPOINTS.TOOLS_EXPORT_STATUS(jobId)),
1738 createImportJob: (data) => apiClient.post(API_ENDPOINTS.TOOLS_IMPORT_JOB, data),
1739 getImportJob: (jobId) => apiClient.get(API_ENDPOINTS.TOOLS_IMPORT_JOB_GET(jobId)),
1740 deleteImportJob: (jobId) => apiClient.delete(API_ENDPOINTS.TOOLS_IMPORT_JOB_GET(jobId)),
1741 getAllJobs: () => apiClient.get(API_ENDPOINTS.TOOLS_ALL_JOBS),
1742 getCronJobs: () => apiClient.get(API_ENDPOINTS.TOOLS_CRON_JOBS),
1743 runCronJob: (hook) => apiClient.post(API_ENDPOINTS.TOOLS_CRON_RUN(hook)),
1744 clearCache: () => apiClient.delete(API_ENDPOINTS.TOOLS_CLEAR_CACHE),
1745 getCacheView: () => apiClient.get(API_ENDPOINTS.TOOLS_CACHE_VIEW),
1746 clearCacheItem: (key, type) => apiClient.delete(
1747 `${API_ENDPOINTS.TOOLS_CACHE_CLEAR_ITEM}?key=${encodeURIComponent(key)}&type=${encodeURIComponent(type)}`
1748 ),
1749 // Migration
1750 getMigrationStatus: () => apiClient.get(API_ENDPOINTS.MIGRATION_STATUS),
1751 clearMigration: () => apiClient.post(API_ENDPOINTS.MIGRATION_CLEAR),
1752 getMigrationProgress: () => apiClient.get(API_ENDPOINTS.MIGRATION_PROGRESS),
1753 runMigrationAll: (data) => apiClient.post(API_ENDPOINTS.MIGRATION_MIGRATE_ALL, data),
1754 cancelMigration: () => apiClient.post(API_ENDPOINTS.MIGRATION_CANCEL),
1755 // Sample Data
1756 importSampleData: (data) => apiClient.post("/sample-data/import", data),
1757 getSampleDataStatus: () => apiClient.get("/sample-data/status"),
1758 cleanupSampleData: () => apiClient.delete("/sample-data/cleanup"),
1759 // Common bulk operations
1760 bulkDelete: (endpoint, ids) => Promise.all(ids.map((id) => apiClient.delete(`${endpoint}/${id}`))),
1761 bulkUpdateStatus: (endpoint, ids, status) => Promise.all(
1762 ids.map((id) => apiClient.put(`${endpoint}/${id}/status`, { status }))
1763 )
1764 };
1765 function getDateFormat() {
1766 var _a, _b, _c;
1767 const w = window;
1768 return ((_a = w == null ? void 0 : w.yatraAdmin) == null ? void 0 : _a.date_format) || ((_b = w == null ? void 0 : w.yatraAdmin) == null ? void 0 : _b.dateFormat) || // Customer account pages localize their settings under yatraAccountPage.
1769 ((_c = w == null ? void 0 : w.yatraAccountPage) == null ? void 0 : _c.date_format) || "Y-m-d";
1770 }
1771 function getTimeFormat() {
1772 var _a, _b, _c;
1773 const w = window;
1774 return ((_a = w == null ? void 0 : w.yatraAdmin) == null ? void 0 : _a.time_format) || ((_b = w == null ? void 0 : w.yatraAdmin) == null ? void 0 : _b.timeFormat) || ((_c = w == null ? void 0 : w.yatraAccountPage) == null ? void 0 : _c.time_format) || "H:i";
1775 }
1776 function toDateValue(value) {
1777 if (value === null || value === void 0) return /* @__PURE__ */ new Date(NaN);
1778 if (value instanceof Date) return value;
1779 if (typeof value !== "string") return /* @__PURE__ */ new Date(NaN);
1780 const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
1781 if (dateOnly) {
1782 return new Date(
1783 Number(dateOnly[1]),
1784 Number(dateOnly[2]) - 1,
1785 Number(dateOnly[3])
1786 );
1787 }
1788 return new Date(value);
1789 }
1790 function formatDate(dateString, includeTime = false) {
1791 if (!dateString) return "-";
1792 try {
1793 const date = toDateValue(dateString);
1794 if (isNaN(date.getTime())) {
1795 return String(dateString);
1796 }
1797 const phpDateFormat = getDateFormat();
1798 const phpTimeFormat = getTimeFormat();
1799 const formattedDate = formatDatePart(date, phpDateFormat);
1800 if (includeTime) {
1801 const formattedTime = formatTimePart(date, phpTimeFormat);
1802 return `${formattedDate} ${formattedTime}`;
1803 }
1804 return formattedDate;
1805 } catch (e) {
1806 return String(dateString);
1807 }
1808 }
1809 function formatDatePart(date, phpFormat) {
1810 const year = date.getFullYear();
1811 const month = date.getMonth();
1812 const day = date.getDate();
1813 const monthNames = [
1814 "January",
1815 "February",
1816 "March",
1817 "April",
1818 "May",
1819 "June",
1820 "July",
1821 "August",
1822 "September",
1823 "October",
1824 "November",
1825 "December"
1826 ];
1827 const monthShort = [
1828 "Jan",
1829 "Feb",
1830 "Mar",
1831 "Apr",
1832 "May",
1833 "Jun",
1834 "Jul",
1835 "Aug",
1836 "Sep",
1837 "Oct",
1838 "Nov",
1839 "Dec"
1840 ];
1841 const pad = (n) => n.toString().padStart(2, "0");
1842 const dayNames = [
1843 "Sunday",
1844 "Monday",
1845 "Tuesday",
1846 "Wednesday",
1847 "Thursday",
1848 "Friday",
1849 "Saturday"
1850 ];
1851 const dayShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
1852 const dayOfWeek = date.getDay();
1853 switch (phpFormat) {
1854 case "Y-m-d":
1855 return `${year}-${pad(month + 1)}-${pad(day)}`;
1856 case "Y/m/d":
1857 return `${year}/${pad(month + 1)}/${pad(day)}`;
1858 case "m/d/Y":
1859 return `${pad(month + 1)}/${pad(day)}/${year}`;
1860 case "d/m/Y":
1861 return `${pad(day)}/${pad(month + 1)}/${year}`;
1862 case "d-m-Y":
1863 return `${pad(day)}-${pad(month + 1)}-${year}`;
1864 case "d.m.Y":
1865 return `${pad(day)}.${pad(month + 1)}.${year}`;
1866 case "M d, Y":
1867 return `${monthShort[month]} ${pad(day)}, ${year}`;
1868 case "F d, Y":
1869 return `${monthNames[month]} ${pad(day)}, ${year}`;
1870 case "d M Y":
1871 return `${pad(day)} ${monthShort[month]} ${year}`;
1872 case "d F Y":
1873 return `${pad(day)} ${monthNames[month]} ${year}`;
1874 case "M j, Y":
1875 return `${monthShort[month]} ${day}, ${year}`;
1876 case "F j, Y":
1877 return `${monthNames[month]} ${day}, ${year}`;
1878 case "j M Y":
1879 return `${day} ${monthShort[month]} ${year}`;
1880 case "j F Y":
1881 return `${day} ${monthNames[month]} ${year}`;
1882 case "Y M j":
1883 return `${year} ${monthShort[month]} ${day}`;
1884 case "Y F j":
1885 return `${year} ${monthNames[month]} ${day}`;
1886 case "l, F j, Y":
1887 return `${dayNames[dayOfWeek]}, ${monthNames[month]} ${day}, ${year}`;
1888 case "D, M j, Y":
1889 return `${dayShort[dayOfWeek]}, ${monthShort[month]} ${day}, ${year}`;
1890 default:
1891 return `${year}-${pad(month + 1)}-${pad(day)}`;
1892 }
1893 }
1894 function formatTimePart(date, phpFormat) {
1895 const hours = date.getHours();
1896 const minutes = date.getMinutes();
1897 const seconds = date.getSeconds();
1898 const pad = (n) => n.toString().padStart(2, "0");
1899 const hours12 = hours % 12 || 12;
1900 const ampm = hours >= 12 ? "PM" : "AM";
1901 switch (phpFormat) {
1902 case "H:i":
1903 return `${pad(hours)}:${pad(minutes)}`;
1904 case "h:i A":
1905 return `${pad(hours12)}:${pad(minutes)} ${ampm}`;
1906 case "h:i a":
1907 return `${pad(hours12)}:${pad(minutes)} ${ampm.toLowerCase()}`;
1908 case "H:i:s":
1909 return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
1910 case "h:i:s A":
1911 return `${pad(hours12)}:${pad(minutes)}:${pad(seconds)} ${ampm}`;
1912 default:
1913 return `${pad(hours)}:${pad(minutes)}`;
1914 }
1915 }
1916 function formatDateTime(dateString) {
1917 return formatDate(dateString, true);
1918 }
1919 function parseDate(dateString) {
1920 if (!dateString) return null;
1921 try {
1922 const date = toDateValue(dateString);
1923 return isNaN(date.getTime()) ? null : date;
1924 } catch (e) {
1925 return null;
1926 }
1927 }
1928 function todayYmd() {
1929 return formatDateForInput(/* @__PURE__ */ new Date());
1930 }
1931 function formatDateForInput(dateString) {
1932 if (!dateString) return "";
1933 try {
1934 const date = toDateValue(dateString);
1935 if (isNaN(date.getTime())) {
1936 return "";
1937 }
1938 const year = date.getFullYear();
1939 const month = (date.getMonth() + 1).toString().padStart(2, "0");
1940 const day = date.getDate().toString().padStart(2, "0");
1941 return `${year}-${month}-${day}`;
1942 } catch (e) {
1943 return "";
1944 }
1945 }
1946 const CURRENCIES = {
1947 // Major Currencies
1948 USD: { code: "USD", name: "US Dollar", symbol: "$", decimalDigits: 2 },
1949 EUR: { code: "EUR", name: "Euro", symbol: "€", decimalDigits: 2 },
1950 GBP: { code: "GBP", name: "British Pound", symbol: "£", decimalDigits: 2 },
1951 JPY: { code: "JPY", name: "Japanese Yen", symbol: "¥", decimalDigits: 0 },
1952 CNY: { code: "CNY", name: "Chinese Yuan", symbol: "¥", decimalDigits: 2 },
1953 CHF: { code: "CHF", name: "Swiss Franc", symbol: "CHF", decimalDigits: 2 },
1954 CAD: { code: "CAD", name: "Canadian Dollar", symbol: "C$", decimalDigits: 2 },
1955 AUD: {
1956 code: "AUD",
1957 name: "Australian Dollar",
1958 symbol: "A$",
1959 decimalDigits: 2
1960 },
1961 NZD: {
1962 code: "NZD",
1963 name: "New Zealand Dollar",
1964 symbol: "NZ$",
1965 decimalDigits: 2
1966 },
1967 // Asian Currencies
1968 INR: { code: "INR", name: "Indian Rupee", symbol: "₹", decimalDigits: 2 },
1969 NPR: { code: "NPR", name: "Nepalese Rupee", symbol: "Rs", decimalDigits: 2 },
1970 PKR: { code: "PKR", name: "Pakistani Rupee", symbol: "₨", decimalDigits: 2 },
1971 BDT: { code: "BDT", name: "Bangladeshi Taka", symbol: "৳", decimalDigits: 2 },
1972 LKR: {
1973 code: "LKR",
1974 name: "Sri Lankan Rupee",
1975 symbol: "Rs",
1976 decimalDigits: 2
1977 },
1978 MMK: { code: "MMK", name: "Myanmar Kyat", symbol: "K", decimalDigits: 2 },
1979 THB: { code: "THB", name: "Thai Baht", symbol: "฿", decimalDigits: 2 },
1980 VND: { code: "VND", name: "Vietnamese Dong", symbol: "₫", decimalDigits: 0 },
1981 IDR: {
1982 code: "IDR",
1983 name: "Indonesian Rupiah",
1984 symbol: "Rp",
1985 decimalDigits: 2
1986 },
1987 MYR: {
1988 code: "MYR",
1989 name: "Malaysian Ringgit",
1990 symbol: "RM",
1991 decimalDigits: 2
1992 },
1993 SGD: {
1994 code: "SGD",
1995 name: "Singapore Dollar",
1996 symbol: "S$",
1997 decimalDigits: 2
1998 },
1999 PHP: { code: "PHP", name: "Philippine Peso", symbol: "₱", decimalDigits: 2 },
2000 KRW: { code: "KRW", name: "South Korean Won", symbol: "₩", decimalDigits: 0 },
2001 TWD: { code: "TWD", name: "Taiwan Dollar", symbol: "NT$", decimalDigits: 2 },
2002 HKD: {
2003 code: "HKD",
2004 name: "Hong Kong Dollar",
2005 symbol: "HK$",
2006 decimalDigits: 2
2007 },
2008 MOP: {
2009 code: "MOP",
2010 name: "Macanese Pataca",
2011 symbol: "MOP$",
2012 decimalDigits: 2
2013 },
2014 KHR: { code: "KHR", name: "Cambodian Riel", symbol: "៛", decimalDigits: 2 },
2015 LAK: { code: "LAK", name: "Lao Kip", symbol: "₭", decimalDigits: 2 },
2016 BND: { code: "BND", name: "Brunei Dollar", symbol: "B$", decimalDigits: 2 },
2017 MNT: { code: "MNT", name: "Mongolian Tugrik", symbol: "₮", decimalDigits: 2 },
2018 KZT: {
2019 code: "KZT",
2020 name: "Kazakhstani Tenge",
2021 symbol: "₸",
2022 decimalDigits: 2
2023 },
2024 UZS: {
2025 code: "UZS",
2026 name: "Uzbekistani Som",
2027 symbol: "сўм",
2028 decimalDigits: 2
2029 },
2030 KGS: {
2031 code: "KGS",
2032 name: "Kyrgyzstani Som",
2033 symbol: "сом",
2034 decimalDigits: 2
2035 },
2036 TJS: {
2037 code: "TJS",
2038 name: "Tajikistani Somoni",
2039 symbol: "�
2040 М",
2041 decimalDigits: 2
2042 },
2043 TMT: {
2044 code: "TMT",
2045 name: "Turkmenistani Manat",
2046 symbol: "m",
2047 decimalDigits: 2
2048 },
2049 AFN: { code: "AFN", name: "Afghan Afghani", symbol: "؋", decimalDigits: 2 },
2050 // Middle Eastern Currencies
2051 AED: { code: "AED", name: "UAE Dirham", symbol: "د.إ", decimalDigits: 2 },
2052 SAR: { code: "SAR", name: "Saudi Riyal", symbol: "﷼", decimalDigits: 2 },
2053 QAR: { code: "QAR", name: "Qatari Riyal", symbol: "﷼", decimalDigits: 2 },
2054 KWD: { code: "KWD", name: "Kuwaiti Dinar", symbol: "د.ك", decimalDigits: 3 },
2055 BHD: {
2056 code: "BHD",
2057 name: "Bahraini Dinar",
2058 symbol: ".د.ب",
2059 decimalDigits: 3
2060 },
2061 OMR: { code: "OMR", name: "Omani Rial", symbol: "﷼", decimalDigits: 3 },
2062 JOD: {
2063 code: "JOD",
2064 name: "Jordanian Dinar",
2065 symbol: "د.ا",
2066 decimalDigits: 3
2067 },
2068 ILS: { code: "ILS", name: "Israeli Shekel", symbol: "₪", decimalDigits: 2 },
2069 LBP: { code: "LBP", name: "Lebanese Pound", symbol: "ل.ل", decimalDigits: 2 },
2070 SYP: { code: "SYP", name: "Syrian Pound", symbol: "£S", decimalDigits: 2 },
2071 IQD: { code: "IQD", name: "Iraqi Dinar", symbol: "ع.د", decimalDigits: 3 },
2072 IRR: { code: "IRR", name: "Iranian Rial", symbol: "﷼", decimalDigits: 2 },
2073 YER: { code: "YER", name: "Yemeni Rial", symbol: "﷼", decimalDigits: 2 },
2074 EGP: { code: "EGP", name: "Egyptian Pound", symbol: "E£", decimalDigits: 2 },
2075 TRY: { code: "TRY", name: "Turkish Lira", symbol: "₺", decimalDigits: 2 },
2076 // European Currencies
2077 SEK: { code: "SEK", name: "Swedish Krona", symbol: "kr", decimalDigits: 2 },
2078 NOK: { code: "NOK", name: "Norwegian Krone", symbol: "kr", decimalDigits: 2 },
2079 DKK: { code: "DKK", name: "Danish Krone", symbol: "kr", decimalDigits: 2 },
2080 ISK: { code: "ISK", name: "Icelandic Króna", symbol: "kr", decimalDigits: 0 },
2081 PLN: { code: "PLN", name: "Polish Zloty", symbol: "zł", decimalDigits: 2 },
2082 CZK: { code: "CZK", name: "Czech Koruna", symbol: "Kč", decimalDigits: 2 },
2083 HUF: {
2084 code: "HUF",
2085 name: "Hungarian Forint",
2086 symbol: "Ft",
2087 decimalDigits: 2
2088 },
2089 RON: { code: "RON", name: "Romanian Leu", symbol: "lei", decimalDigits: 2 },
2090 BGN: { code: "BGN", name: "Bulgarian Lev", symbol: "лв", decimalDigits: 2 },
2091 HRK: { code: "HRK", name: "Croatian Kuna", symbol: "kn", decimalDigits: 2 },
2092 RSD: { code: "RSD", name: "Serbian Dinar", symbol: "дин.", decimalDigits: 2 },
2093 MKD: {
2094 code: "MKD",
2095 name: "Macedonian Denar",
2096 symbol: "ден",
2097 decimalDigits: 2
2098 },
2099 BAM: {
2100 code: "BAM",
2101 name: "Bosnia-Herzegovina Mark",
2102 symbol: "KM",
2103 decimalDigits: 2
2104 },
2105 ALL: { code: "ALL", name: "Albanian Lek", symbol: "L", decimalDigits: 2 },
2106 MDL: { code: "MDL", name: "Moldovan Leu", symbol: "L", decimalDigits: 2 },
2107 UAH: {
2108 code: "UAH",
2109 name: "Ukrainian Hryvnia",
2110 symbol: "₴",
2111 decimalDigits: 2
2112 },
2113 BYN: {
2114 code: "BYN",
2115 name: "Belarusian Ruble",
2116 symbol: "Br",
2117 decimalDigits: 2
2118 },
2119 RUB: { code: "RUB", name: "Russian Ruble", symbol: "₽", decimalDigits: 2 },
2120 GEL: { code: "GEL", name: "Georgian Lari", symbol: "₾", decimalDigits: 2 },
2121 AMD: { code: "AMD", name: "Armenian Dram", symbol: "֏", decimalDigits: 2 },
2122 AZN: {
2123 code: "AZN",
2124 name: "Azerbaijani Manat",
2125 symbol: "₼",
2126 decimalDigits: 2
2127 },
2128 // African Currencies
2129 ZAR: {
2130 code: "ZAR",
2131 name: "South African Rand",
2132 symbol: "R",
2133 decimalDigits: 2
2134 },
2135 NGN: { code: "NGN", name: "Nigerian Naira", symbol: "₦", decimalDigits: 2 },
2136 KES: {
2137 code: "KES",
2138 name: "Kenyan Shilling",
2139 symbol: "KSh",
2140 decimalDigits: 2
2141 },
2142 GHS: { code: "GHS", name: "Ghanaian Cedi", symbol: "₵", decimalDigits: 2 },
2143 TZS: {
2144 code: "TZS",
2145 name: "Tanzanian Shilling",
2146 symbol: "TSh",
2147 decimalDigits: 2
2148 },
2149 UGX: {
2150 code: "UGX",
2151 name: "Ugandan Shilling",
2152 symbol: "USh",
2153 decimalDigits: 0
2154 },
2155 RWF: { code: "RWF", name: "Rwandan Franc", symbol: "FRw", decimalDigits: 0 },
2156 ETB: { code: "ETB", name: "Ethiopian Birr", symbol: "Br", decimalDigits: 2 },
2157 MAD: {
2158 code: "MAD",
2159 name: "Moroccan Dirham",
2160 symbol: "د.�
2161 .",
2162 decimalDigits: 2
2163 },
2164 TND: { code: "TND", name: "Tunisian Dinar", symbol: "د.ت", decimalDigits: 3 },
2165 DZD: { code: "DZD", name: "Algerian Dinar", symbol: "د.ج", decimalDigits: 2 },
2166 LYD: { code: "LYD", name: "Libyan Dinar", symbol: "ل.د", decimalDigits: 3 },
2167 SDG: {
2168 code: "SDG",
2169 name: "Sudanese Pound",
2170 symbol: "ج.س.",
2171 decimalDigits: 2
2172 },
2173 XOF: {
2174 code: "XOF",
2175 name: "West African CFA Franc",
2176 symbol: "CFA",
2177 decimalDigits: 0
2178 },
2179 XAF: {
2180 code: "XAF",
2181 name: "Central African CFA Franc",
2182 symbol: "FCFA",
2183 decimalDigits: 0
2184 },
2185 MUR: { code: "MUR", name: "Mauritian Rupee", symbol: "₨", decimalDigits: 2 },
2186 SCR: {
2187 code: "SCR",
2188 name: "Seychellois Rupee",
2189 symbol: "₨",
2190 decimalDigits: 2
2191 },
2192 MGA: { code: "MGA", name: "Malagasy Ariary", symbol: "Ar", decimalDigits: 2 },
2193 MZN: {
2194 code: "MZN",
2195 name: "Mozambican Metical",
2196 symbol: "MT",
2197 decimalDigits: 2
2198 },
2199 ZMW: { code: "ZMW", name: "Zambian Kwacha", symbol: "ZK", decimalDigits: 2 },
2200 BWP: { code: "BWP", name: "Botswana Pula", symbol: "P", decimalDigits: 2 },
2201 NAD: { code: "NAD", name: "Namibian Dollar", symbol: "N$", decimalDigits: 2 },
2202 AOA: { code: "AOA", name: "Angolan Kwanza", symbol: "Kz", decimalDigits: 2 },
2203 CDF: { code: "CDF", name: "Congolese Franc", symbol: "FC", decimalDigits: 2 },
2204 // Americas Currencies
2205 BRL: { code: "BRL", name: "Brazilian Real", symbol: "R$", decimalDigits: 2 },
2206 MXN: { code: "MXN", name: "Mexican Peso", symbol: "$", decimalDigits: 2 },
2207 ARS: { code: "ARS", name: "Argentine Peso", symbol: "$", decimalDigits: 2 },
2208 CLP: { code: "CLP", name: "Chilean Peso", symbol: "$", decimalDigits: 0 },
2209 COP: { code: "COP", name: "Colombian Peso", symbol: "$", decimalDigits: 2 },
2210 PEN: { code: "PEN", name: "Peruvian Sol", symbol: "S/", decimalDigits: 2 },
2211 UYU: { code: "UYU", name: "Uruguayan Peso", symbol: "$U", decimalDigits: 2 },
2212 PYG: {
2213 code: "PYG",
2214 name: "Paraguayan Guarani",
2215 symbol: "₲",
2216 decimalDigits: 0
2217 },
2218 BOB: {
2219 code: "BOB",
2220 name: "Bolivian Boliviano",
2221 symbol: "Bs.",
2222 decimalDigits: 2
2223 },
2224 VES: {
2225 code: "VES",
2226 name: "Venezuelan Bolívar",
2227 symbol: "Bs.S",
2228 decimalDigits: 2
2229 },
2230 CRC: {
2231 code: "CRC",
2232 name: "Costa Rican Colón",
2233 symbol: "₡",
2234 decimalDigits: 2
2235 },
2236 PAB: {
2237 code: "PAB",
2238 name: "Panamanian Balboa",
2239 symbol: "B/.",
2240 decimalDigits: 2
2241 },
2242 GTQ: {
2243 code: "GTQ",
2244 name: "Guatemalan Quetzal",
2245 symbol: "Q",
2246 decimalDigits: 2
2247 },
2248 HNL: { code: "HNL", name: "Honduran Lempira", symbol: "L", decimalDigits: 2 },
2249 NIO: {
2250 code: "NIO",
2251 name: "Nicaraguan Córdoba",
2252 symbol: "C$",
2253 decimalDigits: 2
2254 },
2255 SVC: { code: "SVC", name: "Salvadoran Colón", symbol: "₡", decimalDigits: 2 },
2256 DOP: { code: "DOP", name: "Dominican Peso", symbol: "RD$", decimalDigits: 2 },
2257 CUP: { code: "CUP", name: "Cuban Peso", symbol: "₱", decimalDigits: 2 },
2258 HTG: { code: "HTG", name: "Haitian Gourde", symbol: "G", decimalDigits: 2 },
2259 JMD: { code: "JMD", name: "Jamaican Dollar", symbol: "J$", decimalDigits: 2 },
2260 TTD: {
2261 code: "TTD",
2262 name: "Trinidad & Tobago Dollar",
2263 symbol: "TT$",
2264 decimalDigits: 2
2265 },
2266 BBD: {
2267 code: "BBD",
2268 name: "Barbadian Dollar",
2269 symbol: "Bds$",
2270 decimalDigits: 2
2271 },
2272 BSD: { code: "BSD", name: "Bahamian Dollar", symbol: "B$", decimalDigits: 2 },
2273 BZD: { code: "BZD", name: "Belize Dollar", symbol: "BZ$", decimalDigits: 2 },
2274 GYD: { code: "GYD", name: "Guyanese Dollar", symbol: "G$", decimalDigits: 2 },
2275 SRD: {
2276 code: "SRD",
2277 name: "Surinamese Dollar",
2278 symbol: "$",
2279 decimalDigits: 2
2280 },
2281 XCD: {
2282 code: "XCD",
2283 name: "East Caribbean Dollar",
2284 symbol: "EC$",
2285 decimalDigits: 2
2286 },
2287 AWG: { code: "AWG", name: "Aruban Florin", symbol: "ƒ", decimalDigits: 2 },
2288 ANG: {
2289 code: "ANG",
2290 name: "Netherlands Antillean Guilder",
2291 symbol: "ƒ",
2292 decimalDigits: 2
2293 },
2294 KYD: {
2295 code: "KYD",
2296 name: "Cayman Islands Dollar",
2297 symbol: "CI$",
2298 decimalDigits: 2
2299 },
2300 BMD: { code: "BMD", name: "Bermudian Dollar", symbol: "$", decimalDigits: 2 },
2301 // Oceania Currencies
2302 FJD: { code: "FJD", name: "Fijian Dollar", symbol: "FJ$", decimalDigits: 2 },
2303 PGK: {
2304 code: "PGK",
2305 name: "Papua New Guinean Kina",
2306 symbol: "K",
2307 decimalDigits: 2
2308 },
2309 SBD: {
2310 code: "SBD",
2311 name: "Solomon Islands Dollar",
2312 symbol: "SI$",
2313 decimalDigits: 2
2314 },
2315 VUV: { code: "VUV", name: "Vanuatu Vatu", symbol: "VT", decimalDigits: 0 },
2316 WST: { code: "WST", name: "Samoan Tala", symbol: "WS$", decimalDigits: 2 },
2317 TOP: { code: "TOP", name: "Tongan Paʻanga", symbol: "T$", decimalDigits: 2 },
2318 XPF: { code: "XPF", name: "CFP Franc", symbol: "₣", decimalDigits: 0 },
2319 // Crypto
2320 BTC: { code: "BTC", name: "Bitcoin", symbol: "₿", decimalDigits: 8 },
2321 ETH: { code: "ETH", name: "Ethereum", symbol: "Ξ", decimalDigits: 8 }
2322 };
2323 const getCurrencyOptions = () => {
2324 return Object.values(CURRENCIES).map((currency) => ({
2325 value: currency.code,
2326 label: `${currency.code} - ${currency.name} (${currency.symbol})`
2327 }));
2328 };
2329 const getCurrency = (code) => {
2330 return CURRENCIES[code.toUpperCase()];
2331 };
2332 const getCurrencySymbol = (code) => {
2333 var _a;
2334 return ((_a = CURRENCIES[code.toUpperCase()]) == null ? void 0 : _a.symbol) || code;
2335 };
2336 function normalizeCurrencyPosition(raw) {
2337 const p = (raw ?? "before").toString().toLowerCase().trim();
2338 if (p === "before") {
2339 return "left_space";
2340 }
2341 if (p === "after") {
2342 return "right_space";
2343 }
2344 if (p === "right" || p === "right_space" || p === "left" || p === "left_space") {
2345 return p;
2346 }
2347 return "left_space";
2348 }
2349 function applyCurrencyPosition(formattedAmount, currencySymbol, rawPosition) {
2350 const mode = normalizeCurrencyPosition(rawPosition);
2351 switch (mode) {
2352 case "right":
2353 return `${formattedAmount}${currencySymbol}`;
2354 case "right_space":
2355 return `${formattedAmount} ${currencySymbol}`;
2356 case "left":
2357 return `${currencySymbol}${formattedAmount}`;
2358 case "left_space":
2359 default:
2360 return `${currencySymbol} ${formattedAmount}`;
2361 }
2362 }
2363 function readYatraCurrencyPositionFromWindow() {
2364 if (typeof window === "undefined") {
2365 return "before";
2366 }
2367 const w = window;
2368 const pick = (o) => {
2369 if (!o) {
2370 return void 0;
2371 }
2372 const a = o.currencyPosition;
2373 const b = o.currency_position;
2374 if (typeof a === "string" && a !== "") {
2375 return a;
2376 }
2377 if (typeof b === "string" && b !== "") {
2378 return b;
2379 }
2380 return void 0;
2381 };
2382 return pick(w.yatraAdmin) ?? pick(w.yatraBookingData) ?? pick(w.yatraTripData) ?? pick(w.yatraAccountPage) ?? "before";
2383 }
2384 function readYatraNumberFormatConfig() {
2385 const fallback = {
2386 decimalPlaces: 2,
2387 thousandSeparator: ",",
2388 decimalSeparator: "."
2389 };
2390 if (typeof window === "undefined") {
2391 return fallback;
2392 }
2393 const w = window;
2394 const sources = [
2395 w.yatraAdmin,
2396 w.yatraBookingData,
2397 w.yatraTripData,
2398 w.yatraAccountPage
2399 ];
2400 const pickString = (field) => {
2401 for (const o of sources) {
2402 const v = o == null ? void 0 : o[field];
2403 if (typeof v === "string" && v !== "") {
2404 return v;
2405 }
2406 }
2407 return void 0;
2408 };
2409 const pickNumber = (...fields) => {
2410 for (const o of sources) {
2411 if (!o) {
2412 continue;
2413 }
2414 for (const field of fields) {
2415 const v = o[field];
2416 if (v !== void 0 && v !== null && v !== "" && !Number.isNaN(Number(v))) {
2417 return Number(v);
2418 }
2419 }
2420 }
2421 return void 0;
2422 };
2423 const decimals = pickNumber("decimalPlaces", "currency_decimals") ?? 2;
2424 return {
2425 decimalPlaces: Math.max(0, Math.min(4, decimals)),
2426 thousandSeparator: pickString("thousandSeparator") ?? ",",
2427 decimalSeparator: pickString("decimalSeparator") ?? "."
2428 };
2429 }
2430 function formatYatraMoney(amount, currencyCode, options) {
2431 const zeroAsUnknown = (options == null ? void 0 : options.zeroAsUnknown) === true;
2432 const num = Number(amount) || 0;
2433 if (zeroAsUnknown && num === 0) {
2434 return __("Contact for pricing", "yatra");
2435 }
2436 const { decimalPlaces, thousandSeparator, decimalSeparator } = readYatraNumberFormatConfig();
2437 const currencyData = getCurrency(currencyCode);
2438 const decimals = (currencyData == null ? void 0 : currencyData.decimalDigits) !== void 0 ? Math.max(0, Math.min(4, currencyData.decimalDigits)) : decimalPlaces;
2439 const formattedCore = new Intl.NumberFormat("en-US", {
2440 minimumFractionDigits: decimals,
2441 maximumFractionDigits: decimals
2442 }).format(num).replace(/,/g, "TEMP_THOUSAND").replace(/\./g, "TEMP_DECIMAL").replace(/TEMP_THOUSAND/g, thousandSeparator).replace(/TEMP_DECIMAL/g, decimalSeparator);
2443 const symbol = getCurrencySymbol(currencyCode);
2444 const position = readYatraCurrencyPositionFromWindow();
2445 return applyCurrencyPosition(formattedCore, symbol, position);
2446 }
2447 const Input = reactExports.forwardRef(
2448 ({ className = "", type, ...props }, ref) => {
2449 return /* @__PURE__ */ jsxRuntimeExports.jsx(
2450 "input",
2451 {
2452 type,
2453 className: `flex h-12 w-full rounded-md border-2 border-gray-300 bg-white px-4 py-3 text-base font-normal text-gray-900 ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:ring-offset-gray-900 dark:placeholder:text-gray-500 dark:focus-visible:ring-blue-400 transition-colors ${className}`,
2454 ref,
2455 ...props
2456 }
2457 );
2458 }
2459 );
2460 Input.displayName = "Input";
2461 const SearchableSelect = ({
2462 value,
2463 onChange,
2464 options,
2465 placeholder = __("Select an option...", "yatra"),
2466 searchPlaceholder = __("Search...", "yatra"),
2467 className = "",
2468 error = false,
2469 disabled = false,
2470 showValueId = true
2471 }) => {
2472 const [isOpen, setIsOpen] = reactExports.useState(false);
2473 const [searchTerm, setSearchTerm] = reactExports.useState("");
2474 const containerRef = reactExports.useRef(null);
2475 const searchInputRef = reactExports.useRef(null);
2476 const [menuRect, setMenuRect] = reactExports.useState(null);
2477 const filteredOptions = options.filter(
2478 (option) => option.label.toLowerCase().includes(searchTerm.toLowerCase()) || option.value.toLowerCase().includes(searchTerm.toLowerCase())
2479 );
2480 const selectedOption = options.find((opt) => opt.value === value);
2481 reactExports.useEffect(() => {
2482 const handleClickOutside = (event) => {
2483 const target = event.target;
2484 if (containerRef.current && containerRef.current.contains(target)) {
2485 return;
2486 }
2487 const portalRoot = document.getElementById(
2488 "yatra-searchable-select-portal"
2489 );
2490 if (portalRoot && portalRoot.contains(target)) {
2491 return;
2492 }
2493 setIsOpen(false);
2494 setSearchTerm("");
2495 };
2496 if (isOpen) {
2497 document.addEventListener("mousedown", handleClickOutside);
2498 setTimeout(() => {
2499 var _a;
2500 (_a = searchInputRef.current) == null ? void 0 : _a.focus();
2501 }, 100);
2502 }
2503 return () => {
2504 document.removeEventListener("mousedown", handleClickOutside);
2505 };
2506 }, [isOpen]);
2507 reactExports.useLayoutEffect(() => {
2508 if (!isOpen) {
2509 setMenuRect(null);
2510 return;
2511 }
2512 const measure = () => {
2513 const el = containerRef.current;
2514 if (!el) return;
2515 const rect = el.getBoundingClientRect();
2516 setMenuRect({
2517 top: rect.bottom + 4,
2518 left: rect.left,
2519 width: rect.width
2520 });
2521 };
2522 measure();
2523 window.addEventListener("scroll", measure, true);
2524 window.addEventListener("resize", measure);
2525 return () => {
2526 window.removeEventListener("scroll", measure, true);
2527 window.removeEventListener("resize", measure);
2528 };
2529 }, [isOpen]);
2530 const handleSelect = (optionValue) => {
2531 onChange(optionValue);
2532 setIsOpen(false);
2533 setSearchTerm("");
2534 };
2535 const handleClear = (e) => {
2536 e.stopPropagation();
2537 onChange("");
2538 setSearchTerm("");
2539 };
2540 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
2541 "div",
2542 {
2543 ref: containerRef,
2544 className: `relative ${className}`,
2545 style: { zIndex: isOpen ? 9999 : "auto" },
2546 children: [
2547 /* @__PURE__ */ jsxRuntimeExports.jsx(
2548 "div",
2549 {
2550 className: `flex h-11 w-full rounded-md border-2 ${error ? "border-red-500" : "border-gray-300 dark:border-gray-600"} bg-white dark:bg-gray-800 px-4 py-2.5 text-base ring-offset-white focus-within:outline-none focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:ring-offset-gray-900 dark:focus-within:ring-blue-400 transition-colors`,
2551 children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
2552 "div",
2553 {
2554 onClick: () => !disabled && setIsOpen(!isOpen),
2555 className: `flex-1 flex items-center justify-between text-left ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"}`,
2556 children: [
2557 /* @__PURE__ */ jsxRuntimeExports.jsx(
2558 "span",
2559 {
2560 className: selectedOption ? "text-gray-900 dark:text-white" : "text-gray-500 dark:text-gray-400",
2561 children: selectedOption ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between w-full", children: [
2562 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-2 min-w-0", children: [
2563 selectedOption.icon && /* @__PURE__ */ jsxRuntimeExports.jsx(
2564 "img",
2565 {
2566 src: selectedOption.icon,
2567 alt: "",
2568 width: 22,
2569 height: 16,
2570 className: "flex-shrink-0 rounded-[2px] object-cover ring-1 ring-black/10"
2571 }
2572 ),
2573 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: selectedOption.label })
2574 ] }),
2575 showValueId && selectedOption.value && selectedOption.value !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400 ml-2 font-medium", children: [
2576 "ID: ",
2577 selectedOption.value
2578 ] })
2579 ] }) : placeholder
2580 }
2581 ),
2582 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
2583 value && !disabled && /* @__PURE__ */ jsxRuntimeExports.jsx(
2584 "button",
2585 {
2586 type: "button",
2587 onClick: handleClear,
2588 className: "p-0.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded",
2589 "aria-label": __("Clear selection", "yatra"),
2590 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4 text-gray-400" })
2591 }
2592 ),
2593 /* @__PURE__ */ jsxRuntimeExports.jsx(
2594 ChevronDown,
2595 {
2596 className: `w-4 h-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
2597 }
2598 )
2599 ] })
2600 ]
2601 }
2602 )
2603 }
2604 ),
2605 isOpen && menuRect && reactDomExports.createPortal(
2606 /* @__PURE__ */ jsxRuntimeExports.jsxs(
2607 "div",
2608 {
2609 id: "yatra-searchable-select-portal",
2610 style: {
2611 position: "fixed",
2612 top: menuRect.top,
2613 left: menuRect.left,
2614 width: menuRect.width,
2615 zIndex: 999999
2616 },
2617 className: "bg-white dark:bg-gray-800 border-2 border-gray-300 dark:border-gray-600 rounded-md shadow-lg max-h-60 overflow-visible",
2618 children: [
2619 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
2620 /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-2.5 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" }),
2621 /* @__PURE__ */ jsxRuntimeExports.jsx(
2622 Input,
2623 {
2624 ref: searchInputRef,
2625 type: "text",
2626 placeholder: searchPlaceholder,
2627 value: searchTerm,
2628 onChange: (e) => setSearchTerm(e.target.value),
2629 className: "pl-8 h-8",
2630 onClick: (e) => e.stopPropagation()
2631 }
2632 )
2633 ] }) }),
2634 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-48 overflow-y-auto overflow-x-visible", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-2 text-sm text-gray-500 dark:text-gray-400 text-center", children: __("No options found", "yatra") }) : filteredOptions.map((option) => /* @__PURE__ */ jsxRuntimeExports.jsx(
2635 "button",
2636 {
2637 type: "button",
2638 onClick: () => handleSelect(option.value),
2639 className: `w-full px-3 py-2 text-left text-sm hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors ${value === option.value ? "bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-400" : "text-gray-900 dark:text-white"}`,
2640 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
2641 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-2 min-w-0", children: [
2642 option.icon && /* @__PURE__ */ jsxRuntimeExports.jsx(
2643 "img",
2644 {
2645 src: option.icon,
2646 alt: "",
2647 loading: "lazy",
2648 width: 22,
2649 height: 16,
2650 className: "flex-shrink-0 rounded-[2px] object-cover ring-1 ring-black/10"
2651 }
2652 ),
2653 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: option.label })
2654 ] }),
2655 showValueId && option.value && option.value !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400 ml-2 font-medium", children: [
2656 "ID: ",
2657 option.value
2658 ] })
2659 ] })
2660 },
2661 option.value
2662 )) })
2663 ]
2664 }
2665 ),
2666 document.body
2667 )
2668 ]
2669 }
2670 );
2671 };
2672 const FALLBACK_COUNTRIES = {
2673 US: "United States",
2674 GB: "United Kingdom",
2675 CA: "Canada",
2676 AU: "Australia",
2677 IN: "India",
2678 NP: "Nepal"
2679 };
2680 function getCountryMap() {
2681 var _a, _b;
2682 const w = window;
2683 const sources = [(_a = w == null ? void 0 : w.yatraAdmin) == null ? void 0 : _a.countries, (_b = w == null ? void 0 : w.yatraAccountPage) == null ? void 0 : _b.countries];
2684 for (const raw of sources) {
2685 if (raw && typeof raw === "object" && !Array.isArray(raw)) {
2686 const map = raw;
2687 if (Object.keys(map).length > 0) return map;
2688 }
2689 }
2690 return FALLBACK_COUNTRIES;
2691 }
2692 function getCountryOptions() {
2693 const map = getCountryMap();
2694 return Object.entries(map).map(([code, name]) => ({ code, name }));
2695 }
2696 function getCountrySelectOptions() {
2697 var _a;
2698 const base = ((_a = window.yatraAdmin) == null ? void 0 : _a.flagBase) || "";
2699 return getCountryOptions().map((c) => ({
2700 value: c.code,
2701 label: c.name,
2702 icon: base ? base + c.code.toLowerCase() + ".svg" : void 0
2703 }));
2704 }
2705 function getCountryName(code) {
2706 if (!code) return "";
2707 const map = getCountryMap();
2708 return map[code.toUpperCase()] ?? code;
2709 }
2710 class ErrorBoundary extends React.Component {
2711 constructor(props) {
2712 super(props);
2713 this.handleReload = () => {
2714 window.location.reload();
2715 };
2716 this.state = { hasError: false };
2717 }
2718 static getDerivedStateFromError() {
2719 return { hasError: true };
2720 }
2721 componentDidCatch(error, info) {
2722 console.error("Yatra admin caught a rendering error:", error, info);
2723 }
2724 render() {
2725 if (!this.state.hasError) {
2726 return this.props.children;
2727 }
2728 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center min-h-[50vh] p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-md text-center", children: [
2729 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold text-gray-900 dark:text-white mb-2", children: __("Something went wrong", "yatra") }),
2730 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-5", children: __(
2731 "The page hit an unexpected error and needs to reload. Your data is safe.",
2732 "yatra"
2733 ) }),
2734 /* @__PURE__ */ jsxRuntimeExports.jsx(
2735 "button",
2736 {
2737 type: "button",
2738 onClick: this.handleReload,
2739 className: "inline-flex items-center justify-center px-4 py-2 rounded-md bg-blue-600 text-white text-sm font-medium hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
2740 children: __("Reload page", "yatra")
2741 }
2742 )
2743 ] }) });
2744 }
2745 }
2746 export {
2747 API_ENDPOINTS as A,
2748 ErrorBoundary as E,
2749 Input as I,
2750 SearchableSelect as S,
2751 ToastProvider as T,
2752 __ as _,
2753 apiClient as a,
2754 apiService as b,
2755 brandName as c,
2756 formatDateForInput as d,
2757 formatDate as e,
2758 formatYatraMoney as f,
2759 todayYmd as g,
2760 getCurrencySymbol as h,
2761 getCountryName as i,
2762 ajaxService as j,
2763 applyCurrencyPosition as k,
2764 getCountrySelectOptions as l,
2765 getCurrencyOptions as m,
2766 normalizeCurrencyPosition as n,
2767 __$1 as o,
2768 parseDate as p,
2769 formatDateTime as q,
2770 readYatraCurrencyPositionFromWindow as r,
2771 sprintf as s,
2772 toDateValue as t,
2773 useToast as u,
2774 wpService as w
2775 };
2776 //# sourceMappingURL=index-Dec_weLB.js.map
2777