This commit is contained in:
Iliyan Angelov
2025-11-17 18:26:30 +02:00
parent 48353cde9c
commit 0c59fe1173
2535 changed files with 278997 additions and 2480 deletions

View File

@@ -25,6 +25,7 @@ export const STORAGE_KEYS = {
GUEST_FAVORITES: 'guestFavorites',
THEME: 'theme',
LANGUAGE: 'language',
CURRENCY: 'currency',
} as const;
export const ROUTES = {

View File

@@ -2,18 +2,86 @@
* Utility functions for formatting data
*/
// Cache for currency to avoid repeated localStorage reads
let cachedCurrency: string | null = null;
// Listen for currency changes
if (typeof window !== 'undefined') {
window.addEventListener('currencyChanged', ((e: CustomEvent) => {
cachedCurrency = e.detail?.currency || null;
}) as EventListener);
// Also listen to storage events (in case currency is changed in another tab)
window.addEventListener('storage', (e) => {
if (e.key === 'currency') {
cachedCurrency = e.newValue;
window.dispatchEvent(new CustomEvent('currencyChanged', {
detail: { currency: e.newValue }
}));
}
});
}
/**
* Get currency symbol dynamically
*/
export const getCurrencySymbol = (currencyCode: string): string => {
try {
// Use Intl.NumberFormat to get the currency symbol
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currencyCode,
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
// Format 0 to get the symbol
const parts = formatter.formatToParts(0);
const symbolPart = parts.find(part => part.type === 'currency');
return symbolPart?.value || currencyCode;
} catch {
return currencyCode;
}
};
/**
* Format currency
* If currency is not provided, it will try to use the currency from localStorage (set by CurrencyContext)
* For components that have access to CurrencyContext, use the useFormatCurrency hook instead
*/
export const formatCurrency = (
amount: number | string,
currency: string = 'VND'
currency?: string
): string => {
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
if (isNaN(numAmount)) return '0 ₫';
if (isNaN(numAmount)) {
// Return default based on currency
if (currency === 'VND') return '0 ₫';
return `0 ${currency || 'VND'}`;
}
if (currency === 'VND') {
// Use provided currency or try to get from localStorage (set by CurrencyContext)
let currencyToUse = currency;
if (!currencyToUse && typeof window !== 'undefined') {
try {
// Use cached currency if available, otherwise read from localStorage
if (cachedCurrency) {
currencyToUse = cachedCurrency;
} else {
const storedCurrency = localStorage.getItem('currency');
if (storedCurrency) {
cachedCurrency = storedCurrency;
currencyToUse = storedCurrency;
}
}
} catch (e) {
// localStorage not available, use default
}
}
currencyToUse = currencyToUse || 'VND';
if (currencyToUse === 'VND') {
return new Intl.NumberFormat('vi-VN', {
style: 'currency',
currency: 'VND',
@@ -22,9 +90,27 @@ export const formatCurrency = (
}).format(numAmount);
}
return new Intl.NumberFormat('en-US', {
// For other currencies, use appropriate locale
const localeMap: Record<string, string> = {
'USD': 'en-US',
'EUR': 'de-DE',
'GBP': 'en-GB',
'JPY': 'ja-JP',
'CNY': 'zh-CN',
'KRW': 'ko-KR',
'SGD': 'en-SG',
'THB': 'th-TH',
'AUD': 'en-AU',
'CAD': 'en-CA',
};
const locale = localeMap[currencyToUse] || 'en-US';
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency,
currency: currencyToUse,
minimumFractionDigits: currencyToUse === 'JPY' ? 0 : 2,
maximumFractionDigits: currencyToUse === 'JPY' ? 0 : 2,
}).format(numAmount);
};