();
-
-const formatCurrency = (amount: number, currency?: string) => {
- const code = (currency || "JPY").toUpperCase();
- const formatter =
- currencyFormatterCache.get(code) ||
- (() => {
- try {
- const intl = new Intl.NumberFormat("en-US", {
- style: "currency",
- currency: code,
- });
- currencyFormatterCache.set(code, intl);
- return intl;
- } catch {
- return null;
- }
- })();
-
- if (!formatter) {
- return `${code} ${amount.toLocaleString()}`;
- }
-
- return formatter.format(amount);
-};
-
export function formatActivityDescription(activity: Activity): string {
switch (activity.type) {
case "invoice_created":
case "invoice_paid": {
const parsed = invoiceActivityMetadataSchema.safeParse(activity.metadata ?? {});
if (parsed.success && typeof parsed.data.amount === "number") {
- const formattedAmount = formatCurrency(parsed.data.amount, parsed.data.currency);
+ const formattedAmount = formatCurrencyUtil(parsed.data.amount, parsed.data.currency);
if (formattedAmount) {
return activity.type === "invoice_paid"
? `${formattedAmount} payment completed`
diff --git a/apps/portal/src/features/dashboard/views/DashboardView.tsx b/apps/portal/src/features/dashboard/views/DashboardView.tsx
index de00ef60..6222cef8 100644
--- a/apps/portal/src/features/dashboard/views/DashboardView.tsx
+++ b/apps/portal/src/features/dashboard/views/DashboardView.tsx
@@ -193,7 +193,9 @@ export function DashboardView() {
- {formatCurrency(upcomingInvoice.amount)}
+ {formatCurrency(upcomingInvoice.amount, {
+ currency: upcomingInvoice.currency,
+ })}
Exact due date: {format(new Date(upcomingInvoice.dueDate), "MMMM d, yyyy")}
diff --git a/apps/portal/src/lib/hooks/useCurrency.ts b/apps/portal/src/lib/hooks/useCurrency.ts
index 467d9615..402c3746 100644
--- a/apps/portal/src/lib/hooks/useCurrency.ts
+++ b/apps/portal/src/lib/hooks/useCurrency.ts
@@ -19,7 +19,7 @@ export function useCurrency() {
retry: 2,
});
- const resolvedCurrency = data ?? null;
+ const resolvedCurrency = data ?? (isError ? FALLBACK_CURRENCY : null);
const currencyCode = resolvedCurrency?.code ?? FALLBACK_CURRENCY.code;
const currencySymbol = resolvedCurrency?.prefix ?? FALLBACK_CURRENCY.prefix;
diff --git a/apps/portal/src/lib/hooks/useFormatCurrency.ts b/apps/portal/src/lib/hooks/useFormatCurrency.ts
index 2de5027c..340e9f4f 100644
--- a/apps/portal/src/lib/hooks/useFormatCurrency.ts
+++ b/apps/portal/src/lib/hooks/useFormatCurrency.ts
@@ -11,17 +11,43 @@ export type FormatCurrencyOptions = {
showSymbol?: boolean;
};
+const isOptions = (
+ value: string | FormatCurrencyOptions | undefined
+): value is FormatCurrencyOptions => {
+ return typeof value === "object" && value !== null;
+};
+
export function useFormatCurrency() {
const { currencyCode, currencySymbol, loading, error } = useCurrency();
- const formatCurrency = (amount: number, options?: FormatCurrencyOptions) => {
- const resolvedCurrency = options?.currency ?? currencyCode ?? FALLBACK_CURRENCY.code;
- const resolvedSymbol = options?.currencySymbol ?? currencySymbol ?? FALLBACK_CURRENCY.prefix;
+ const formatCurrency = (
+ amount: number,
+ currencyOrOptions?: string | FormatCurrencyOptions,
+ options?: FormatCurrencyOptions
+ ) => {
+ const fallbackCurrency = currencyCode ?? FALLBACK_CURRENCY.code;
+ const fallbackSymbol = currencySymbol ?? FALLBACK_CURRENCY.prefix;
- return baseFormatCurrency(amount, resolvedCurrency, {
- currencySymbol: resolvedSymbol,
- locale: options?.locale,
- showSymbol: options?.showSymbol,
+ const overrideCurrency =
+ (typeof currencyOrOptions === "string" && currencyOrOptions) ||
+ (isOptions(currencyOrOptions) ? currencyOrOptions.currency : undefined) ||
+ options?.currency;
+
+ const overrideSymbol =
+ (isOptions(currencyOrOptions) ? currencyOrOptions.currencySymbol : undefined) ||
+ options?.currencySymbol;
+
+ const locale =
+ (isOptions(currencyOrOptions) ? currencyOrOptions.locale : undefined) || options?.locale;
+ const showSymbol =
+ (isOptions(currencyOrOptions) && typeof currencyOrOptions.showSymbol === "boolean"
+ ? currencyOrOptions.showSymbol
+ : undefined) ?? options?.showSymbol;
+
+ return baseFormatCurrency(amount, overrideCurrency ?? fallbackCurrency, {
+ currencySymbol: overrideSymbol ?? fallbackSymbol,
+ locale,
+ showSymbol,
});
};