mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 13:38:20 +00:00
feat(ui-common): shared currency formatting + DJF in CurrencySelector
New lib/currency.ts is the single source of truth for currency display across both freight web apps: symbol, name and decimals per code (DJF is zero-decimal by convention, unlike ETB/USD). Portal's own currency lib and backoffice's ad-hoc formatters are rewired onto this in the next two commits instead of each guessing decimals. CurrencySelector gets an allowDjf prop mirroring the existing allowUsd gate, so import-shipment currency pickers can offer DJF the same way they offer USD. Claude-Session: https://claude.ai/code/session_01CZy77vCWhka3pnmVF9NDkL
This commit is contained in:
43
packages/ui-common/src/lib/currency.ts
Normal file
43
packages/ui-common/src/lib/currency.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* The currency codes the freight apps support, and how each one displays —
|
||||
* symbol, full name, decimal places. USD/ETB are conventional 2-decimal
|
||||
* currencies; DJF (Djibouti Franc) is a zero-decimal currency by convention.
|
||||
*
|
||||
* Single source of truth for currency display across both freight web apps —
|
||||
* import this instead of re-declaring a symbol map or a decimals rule.
|
||||
*/
|
||||
export const CURRENCY_META = {
|
||||
ETB: { symbol: "Br", name: "Ethiopian Birr", decimals: 2 },
|
||||
USD: { symbol: "$", name: "US Dollar", decimals: 2 },
|
||||
DJF: { symbol: "Fdj", name: "Djibouti Franc", decimals: 0 },
|
||||
} as const;
|
||||
|
||||
export type SupportedCurrency = keyof typeof CURRENCY_META;
|
||||
|
||||
export const CURRENCY_CODES = Object.keys(CURRENCY_META) as SupportedCurrency[];
|
||||
|
||||
/** Decimal places to render an amount in `code` with. Defaults to 2 for an unknown code. */
|
||||
export function currencyDecimals(code?: string | null): number {
|
||||
const meta = code ? CURRENCY_META[code as SupportedCurrency] : undefined;
|
||||
return meta?.decimals ?? 2;
|
||||
}
|
||||
|
||||
/** Display symbol for `code`. Falls back to printing the raw code. */
|
||||
export function currencySymbol(code?: string | null): string {
|
||||
const meta = code ? CURRENCY_META[code as SupportedCurrency] : undefined;
|
||||
return meta?.symbol ?? code ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a money amount with its currency symbol, e.g. `Br 12,500.00` or
|
||||
* `Fdj 2,194,318`. Unknown currency codes fall back to printing the raw code
|
||||
* with 2 decimals.
|
||||
*/
|
||||
export function formatCurrency(amount: number, currency?: string | null): string {
|
||||
const symbol = currencySymbol(currency);
|
||||
const decimals = currencyDecimals(currency);
|
||||
return `${symbol} ${Number(amount ?? 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: decimals,
|
||||
maximumFractionDigits: decimals,
|
||||
})}`;
|
||||
}
|
||||
Reference in New Issue
Block a user