PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.7
Yatra – Travel Booking & Tour Operator Software v3.0.2.7
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / resources / js / pages / account / utils.ts

utils.ts in Yatra – Travel Booking & Tour Operator Software 3.0.2.7, at resources/js/pages/account/utils.ts

208 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __ } from "../../lib/i18n";
2 import { getCurrencySymbol, getCurrency } from "../../data/currencies";
3
4 export const formatDate = (value: string | undefined | null) => {
5 if (!value) {
6 return __("N/A", "yatra");
7 }
8
9 try {
10 const date = new Date(value);
11
12 // Check if date is valid
13 if (isNaN(date.getTime())) {
14 return __("Invalid date", "yatra");
15 }
16
17 return date.toLocaleDateString(undefined, {
18 year: "numeric",
19 month: "long",
20 day: "numeric",
21 });
22 } catch (error) {
23 return __("Invalid date", "yatra");
24 }
25 };
26
27 export const getBadge = (status: string | undefined | null) => {
28 const base = "px-2.5 py-0.5 rounded-full text-xs font-medium";
29
30 // Handle undefined/null/empty status
31 if (!status || typeof status !== "string") {
32 return `${base} bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-300`;
33 }
34
35 switch (status.toLowerCase()) {
36 case "paid":
37 case "confirmed":
38 case "resolved":
39 return `${base} bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300`;
40 case "pending":
41 case "partial":
42 case "awaiting_response":
43 return `${base} bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300`;
44 case "failed":
45 case "cancelled":
46 return `${base} bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300`;
47 default:
48 return `${base} bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300`;
49 }
50 };
51
52 type PriceConfigWindow = Window & {
53 yatraAdmin?: Record<string, unknown>;
54 yatraAccountPage?: Record<string, unknown>;
55 };
56
57 function readPriceConfig() {
58 if (typeof window === "undefined") {
59 return {
60 globalCurrency: "USD",
61 currencyPosition: "before",
62 decimalPlaces: 2,
63 thousandSeparator: ",",
64 decimalSeparator: ".",
65 };
66 }
67 const w = window as PriceConfigWindow;
68 const a = (w.yatraAdmin || {}) as Record<string, unknown>;
69 const p = (w.yatraAccountPage || {}) as Record<string, unknown>;
70 return {
71 globalCurrency: (a.currency || p.currency || "USD") as string,
72 currencyPosition: (a.currencyPosition ||
73 p.currencyPosition ||
74 "before") as string,
75 decimalPlaces: Number(a.decimalPlaces ?? p.decimalPlaces ?? 2) || 2,
76 thousandSeparator: (a.thousandSeparator ||
77 p.thousandSeparator ||
78 ",") as string,
79 decimalSeparator: (a.decimalSeparator ||
80 p.decimalSeparator ||
81 ".") as string,
82 };
83 }
84
85 export const formatPrice = (price: number) => {
86 const {
87 globalCurrency,
88 currencyPosition,
89 decimalPlaces,
90 thousandSeparator,
91 decimalSeparator,
92 } = readPriceConfig();
93
94 if (!price || price === 0) {
95 return __("Contact for pricing", "yatra");
96 }
97
98 const formattedAmount = new Intl.NumberFormat(undefined, {
99 minimumFractionDigits: decimalPlaces,
100 maximumFractionDigits: decimalPlaces,
101 })
102 .format(price)
103 .replace(/,/g, "TEMP_THOUSAND")
104 .replace(/\./g, decimalSeparator)
105 .replace(/TEMP_THOUSAND/g, thousandSeparator);
106
107 const currencySymbol = new Intl.NumberFormat(undefined, {
108 style: "currency",
109 currency: globalCurrency,
110 })
111 .format(0)
112 .replace(/[\d\s.,]/g, "")
113 .trim();
114
115 if (currencyPosition === "right" || currencyPosition === "after") {
116 return `${formattedAmount}${currencySymbol}`;
117 }
118
119 return `${currencySymbol}${formattedAmount}`;
120 };
121
122 export const formatPriceForBooking = (price: number, currency?: string) => {
123 const cfg = readPriceConfig();
124 const globalCurrency = currency || cfg.globalCurrency;
125 const {
126 currencyPosition,
127 decimalPlaces,
128 thousandSeparator,
129 decimalSeparator,
130 } = cfg;
131
132 const currencyToUse = globalCurrency;
133
134 // Always format the price, even if 0 - don't show "Contact for pricing" for bookings
135 const numPrice = Number(price) || 0;
136
137 const formattedAmount = new Intl.NumberFormat(undefined, {
138 minimumFractionDigits: decimalPlaces,
139 maximumFractionDigits: decimalPlaces,
140 })
141 .format(numPrice)
142 .replace(/,/g, "TEMP_THOUSAND")
143 .replace(/\./g, decimalSeparator)
144 .replace(/TEMP_THOUSAND/g, thousandSeparator);
145
146 const currencySymbol = new Intl.NumberFormat(undefined, {
147 style: "currency",
148 currency: currencyToUse,
149 })
150 .format(0)
151 .replace(/[\d\s.,]/g, "")
152 .trim();
153
154 if (currencyPosition === "right" || currencyPosition === "after") {
155 return `${formattedAmount}${currencySymbol}`;
156 }
157
158 return `${currencySymbol}${formattedAmount}`;
159 };
160
161 export const currency = (value: number, currencyCode: string = "USD") => {
162 const symbol = getCurrencySymbol(currencyCode);
163 const currencyData = getCurrency(currencyCode);
164 const decimals = currencyData?.decimalDigits ?? 2;
165
166 const formatted = new Intl.NumberFormat(undefined, {
167 minimumFractionDigits: decimals,
168 maximumFractionDigits: decimals,
169 }).format(value);
170
171 return `${symbol}${formatted}`;
172 };
173
174 /** Values from `wp_localize_script(…, 'yatraAccountPage', …)` on the account page. */
175 export function getYatraAccountPageGlobals(): {
176 logoutUrl: string;
177 companyPhone: string;
178 companyName: string;
179 companyEmail: string;
180 } {
181 if (typeof window === "undefined") {
182 return {
183 logoutUrl: "",
184 companyPhone: "",
185 companyName: "",
186 companyEmail: "",
187 };
188 }
189 const p = (window as unknown as { yatraAccountPage?: Record<string, string> })
190 .yatraAccountPage;
191 const raw = p || {};
192 return {
193 logoutUrl: String(raw.logoutUrl || "").trim(),
194 companyPhone: String(raw.companyPhone || "").trim(),
195 companyName: String(raw.companyName || "").trim(),
196 companyEmail: String(raw.companyEmail || "").trim(),
197 };
198 }
199
200 export function phoneToTelHref(phone: string): string {
201 const t = String(phone).trim();
202 if (!t) {
203 return "";
204 }
205 const compact = t.replace(/[^\d+]/g, "");
206 return compact ? `tel:${compact}` : `tel:${encodeURIComponent(t)}`;
207 }
208