| @@ -20,8 +20,13 @@ | ||
| 20 | 20 | import { useToast } from "../components/ui/toast"; |
| 21 | 21 | import { apiClient } from "../lib/api-client"; |
| 22 | 22 | import { Button } from "../components/ui/button"; |
| 23 | 23 | import { Input } from "../components/ui/input"; |
| 24 | +import { getCurrencySymbol } from "../data/currencies"; | |
| 25 | +import { | |
| 26 | + normalizeCurrencyPosition, | |
| 27 | + readYatraCurrencyPositionFromWindow, | |
| 28 | +} from "../lib/currency-display"; | |
| 24 | 29 | import { Select } from "../components/ui/select"; |
| 25 | 30 | import { PageHeader } from "../components/common/PageHeader"; |
| 26 | 31 | import { |
| 27 | 32 | Card, |
| @@ -83,8 +88,28 @@ | ||
| 83 | 88 | const DiscountForm: React.FC = () => { |
| 84 | 89 | const queryClient = useQueryClient(); |
| 85 | 90 | const { can, permissions, isPro } = usePermissions(); |
| 86 | 91 | const { showToast } = useToast(); |
| 92 | + | |
| 93 | + // Currency symbol + placement for the amount fields, taken from the operator's | |
| 94 | + // settings (localized into window.yatraAdmin). Previously these inputs | |
| 95 | + // hardcoded "$" on the left, ignoring both the configured symbol and its | |
| 96 | + // position (left / left_space / right / right_space). | |
| 97 | + const currencySymbol = getCurrencySymbol( | |
| 98 | + ((window as unknown as { yatraAdmin?: { currency?: string } })?.yatraAdmin | |
| 99 | + ?.currency as string) || "USD", | |
| 100 | + ); | |
| 101 | + const currencyOnRight = (() => { | |
| 102 | + const pos = normalizeCurrencyPosition(readYatraCurrencyPositionFromWindow()); | |
| 103 | + return pos === "right" || pos === "right_space"; | |
| 104 | + })(); | |
| 105 | + const currencyPad = currencyOnRight | |
| 106 | + ? currencySymbol.length > 1 | |
| 107 | + ? "pr-10" | |
| 108 | + : "pr-7" | |
| 109 | + : currencySymbol.length > 1 | |
| 110 | + ? "pl-10" | |
| 111 | + : "pl-7"; | |
| 87 | 112 | const [showPremiumModal, setShowPremiumModal] = useState(false); |
| 88 | 113 | // Get initial discount_mode from URL at initialization time |
| 89 | 114 | const getInitialState = (): DiscountFormData => { |
| 90 | 115 | const params = new URLSearchParams(window.location.search); |
| @@ -1348,11 +1373,10 @@ | ||
| 1348 | 1373 | required |
| 1349 | 1374 | /> |
| 1350 | 1375 | ) : ( |
| 1351 | 1376 | <div className="relative"> |
| 1352 | - <span className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> | |
| 1353 | - $ | |
| 1354 | - </span> | |
| 1377 | + <span className={`absolute ${currencyOnRight ? "right-3" : "left-3"} top-1/2 transform -translate-y-1/2 text-gray-500 text-sm`}> | |
| 1378 | + {currencySymbol} </span> | |
| 1355 | 1379 | <Input |
| 1356 | 1380 | id="amount" |
| 1357 | 1381 | name="amount" |
| 1358 | 1382 | type="number" |
| @@ -1362,9 +1386,9 @@ | ||
| 1362 | 1386 | onChange={(e) => |
| 1363 | 1387 | handleFieldChange("amount", e.target.value) |
| 1364 | 1388 | } |
| 1365 | 1389 | placeholder={__("e.g., 50", "yatra")} |
| 1366 | - className={`pl-7 ${errors.amount ? "border-red-500" : ""}`} | |
| 1390 | + className={`${currencyPad} ${errors.amount ? "border-red-500" : ""}`} | |
| 1367 | 1391 | required |
| 1368 | 1392 | /> |
| 1369 | 1393 | </div> |
| 1370 | 1394 | )} |
| @@ -1400,11 +1424,10 @@ | ||
| 1400 | 1424 | )} |
| 1401 | 1425 | className="mb-2" |
| 1402 | 1426 | /> |
| 1403 | 1427 | <div className="relative"> |
| 1404 | - <span className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> | |
| 1405 | - $ | |
| 1406 | - </span> | |
| 1428 | + <span className={`absolute ${currencyOnRight ? "right-3" : "left-3"} top-1/2 transform -translate-y-1/2 text-gray-500 text-sm`}> | |
| 1429 | + {currencySymbol} </span> | |
| 1407 | 1430 | <Input |
| 1408 | 1431 | id="max_discount_amount" |
| 1409 | 1432 | type="number" |
| 1410 | 1433 | min="0" |
| @@ -1416,9 +1439,9 @@ | ||
| 1416 | 1439 | e.target.value, |
| 1417 | 1440 | ) |
| 1418 | 1441 | } |
| 1419 | 1442 | placeholder={__("e.g., 500 (optional)", "yatra")} |
| 1420 | - className={`pl-7 ${errors.max_discount_amount ? "border-red-500" : ""}`} | |
| 1443 | + className={`${currencyPad} ${errors.max_discount_amount ? "border-red-500" : ""}`} | |
| 1421 | 1444 | /> |
| 1422 | 1445 | </div> |
| 1423 | 1446 | {errors.max_discount_amount && ( |
| 1424 | 1447 | <p className="mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1"> |
| @@ -1554,11 +1577,10 @@ | ||
| 1554 | 1577 | )} |
| 1555 | 1578 | className="mb-2" |
| 1556 | 1579 | /> |
| 1557 | 1580 | <div className="relative"> |
| 1558 | - <span className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> | |
| 1559 | - $ | |
| 1560 | - </span> | |
| 1581 | + <span className={`absolute ${currencyOnRight ? "right-3" : "left-3"} top-1/2 transform -translate-y-1/2 text-gray-500 text-sm`}> | |
| 1582 | + {currencySymbol} </span> | |
| 1561 | 1583 | <Input |
| 1562 | 1584 | id="min_amount" |
| 1563 | 1585 | type="number" |
| 1564 | 1586 | min="0" |
| @@ -1567,9 +1589,9 @@ | ||
| 1567 | 1589 | onChange={(e) => |
| 1568 | 1590 | handleFieldChange("min_amount", e.target.value) |
| 1569 | 1591 | } |
| 1570 | 1592 | placeholder={__("e.g., 100", "yatra")} |
| 1571 | - className={`pl-7 ${errors.min_amount ? "border-red-500" : ""}`} | |
| 1593 | + className={`${currencyPad} ${errors.min_amount ? "border-red-500" : ""}`} | |
| 1572 | 1594 | /> |
| 1573 | 1595 | </div> |
| 1574 | 1596 | {errors.min_amount && ( |
| 1575 | 1597 | <p className="mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1"> |
| @@ -1931,11 +1953,10 @@ | ||
| 1931 | 1953 | </label> |
| 1932 | 1954 | <div className="relative"> |
| 1933 | 1955 | {range.discount_type === |
| 1934 | 1956 | "fixed" && ( |
| 1935 | - <span className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> | |
| 1936 | - $ | |
| 1937 | - </span> | |
| 1957 | + <span className={`absolute ${currencyOnRight ? "right-3" : "left-3"} top-1/2 transform -translate-y-1/2 text-gray-500 text-sm`}> | |
| 1958 | + {currencySymbol} </span> | |
| 1938 | 1959 | )} |
| 1939 | 1960 | <Input |
| 1940 | 1961 | type="number" |
| 1941 | 1962 | min="0" |
| @@ -1960,9 +1981,9 @@ | ||
| 1960 | 1981 | "percentage" |
| 1961 | 1982 | ? __("e.g., 10", "yatra") |
| 1962 | 1983 | : __("e.g., 50", "yatra") |
| 1963 | 1984 | } |
| 1964 | - className={`${range.discount_type === "fixed" ? "pl-7" : ""} ${errors[`group_discount_ranges_${idx}_amount`] ? "border-red-500" : ""}`} | |
| 1985 | + className={`${range.discount_type === "fixed" ? currencyPad : ""} ${errors[`group_discount_ranges_${idx}_amount`] ? "border-red-500" : ""}`} | |
| 1965 | 1986 | /> |
| 1966 | 1987 | {range.discount_type === |
| 1967 | 1988 | "percentage" && ( |
| 1968 | 1989 | <span className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> |
| @@ -2497,11 +2518,10 @@ | ||
| 2497 | 2518 | </label> |
| 2498 | 2519 | <div className="relative"> |
| 2499 | 2520 | {range.discount_type === |
| 2500 | 2521 | "fixed" && ( |
| 2501 | - <span className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> | |
| 2502 | - $ | |
| 2503 | - </span> | |
| 2522 | + <span className={`absolute ${currencyOnRight ? "right-3" : "left-3"} top-1/2 transform -translate-y-1/2 text-gray-500 text-sm`}> | |
| 2523 | + {currencySymbol} </span> | |
| 2504 | 2524 | )} |
| 2505 | 2525 | <Input |
| 2506 | 2526 | type="number" |
| 2507 | 2527 | min="0" |
| @@ -2538,9 +2558,9 @@ | ||
| 2538 | 2558 | "e.g., 50", |
| 2539 | 2559 | "yatra", |
| 2540 | 2560 | ) |
| 2541 | 2561 | } |
| 2542 | - className={`${range.discount_type === "fixed" ? "pl-7" : ""} ${errors[`category_discounts_${catIdx}_ranges_${rIdx}_amount`] ? "border-red-500" : ""}`} | |
| 2562 | + className={`${range.discount_type === "fixed" ? currencyPad : ""} ${errors[`category_discounts_${catIdx}_ranges_${rIdx}_amount`] ? "border-red-500" : ""}`} | |
| 2543 | 2563 | /> |
| 2544 | 2564 | {range.discount_type === |
| 2545 | 2565 | "percentage" && ( |
| 2546 | 2566 | <span className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm"> |