updates
This commit is contained in:
@@ -25,6 +25,7 @@ export const STORAGE_KEYS = {
|
||||
GUEST_FAVORITES: 'guestFavorites',
|
||||
THEME: 'theme',
|
||||
LANGUAGE: 'language',
|
||||
CURRENCY: 'currency',
|
||||
} as const;
|
||||
|
||||
export const ROUTES = {
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user