48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
/**
|
|
* CurrencyDisplay
|
|
*
|
|
* Deterministic currency formatting for display.
|
|
* Avoids Intl and toLocaleString to prevent SSR/hydration mismatches.
|
|
*/
|
|
|
|
export class CurrencyFormatter {
|
|
/**
|
|
* Formats an amount as currency (e.g., "$10.00" or "€1.000,00").
|
|
* Default currency is USD.
|
|
*/
|
|
static format(amount: number, currency: string = 'USD'): string {
|
|
const symbol = currency === 'USD' ? '$' : currency === 'EUR' ? '€' : currency + ' ';
|
|
const formattedAmount = amount.toFixed(2);
|
|
|
|
// Add thousands separators
|
|
const parts = formattedAmount.split('.');
|
|
|
|
// Use dot as thousands separator for EUR, comma for USD
|
|
if (currency === 'EUR') {
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
|
return `${symbol}${parts[0]},${parts[1]}`;
|
|
} else {
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
return `${symbol}${parts.join('.')}`;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Formats an amount as a compact currency (e.g., "$10" or "€1.000").
|
|
*/
|
|
static formatCompact(amount: number, currency: string = 'USD'): string {
|
|
const symbol = currency === 'USD' ? '$' : currency === 'EUR' ? '€' : currency + ' ';
|
|
const roundedAmount = Math.round(amount);
|
|
|
|
// Add thousands separators
|
|
const formattedAmount = roundedAmount.toString();
|
|
|
|
// Use dot as thousands separator for EUR, comma for USD
|
|
if (currency === 'EUR') {
|
|
return `${symbol}${formattedAmount.replace(/\B(?=(\d{3})+(?!\d))/g, '.')}`;
|
|
} else {
|
|
return `${symbol}${formattedAmount.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`;
|
|
}
|
|
}
|
|
}
|