127 lines
3.2 KiB
TypeScript
127 lines
3.2 KiB
TypeScript
export default defineNuxtPlugin(() => {
|
|
const config = useRuntimeConfig()
|
|
|
|
// Get configuration from environment
|
|
const currency = config.public.appCurrency || 'EUR'
|
|
const locale = config.public.appLocale || 'en-CA'
|
|
const decimalPlaces = parseInt(config.public.appDecimalPlaces || '2')
|
|
|
|
// Create formatters with centralized configuration
|
|
const currencyFormatter = new Intl.NumberFormat(locale, {
|
|
style: 'currency',
|
|
currency: currency,
|
|
minimumFractionDigits: decimalPlaces,
|
|
maximumFractionDigits: decimalPlaces
|
|
})
|
|
|
|
const numberFormatter = new Intl.NumberFormat(locale, {
|
|
minimumFractionDigits: 0,
|
|
maximumFractionDigits: decimalPlaces
|
|
})
|
|
|
|
const percentFormatter = new Intl.NumberFormat(locale, {
|
|
style: 'percent',
|
|
minimumFractionDigits: 0,
|
|
maximumFractionDigits: 1
|
|
})
|
|
|
|
const dateFormatter = new Intl.DateTimeFormat(locale, {
|
|
dateStyle: 'medium'
|
|
})
|
|
|
|
const shortDateFormatter = new Intl.DateTimeFormat(locale, {
|
|
dateStyle: 'short'
|
|
})
|
|
|
|
// Helper functions
|
|
const formatters = {
|
|
/**
|
|
* Format currency amount
|
|
*/
|
|
currency: (amount: number): string => {
|
|
return currencyFormatter.format(amount)
|
|
},
|
|
|
|
/**
|
|
* Format number with locale-specific formatting
|
|
*/
|
|
number: (value: number): string => {
|
|
return numberFormatter.format(value)
|
|
},
|
|
|
|
/**
|
|
* Format percentage (expects decimal, e.g., 0.65 for 65%)
|
|
*/
|
|
percent: (value: number): string => {
|
|
return percentFormatter.format(value)
|
|
},
|
|
|
|
/**
|
|
* Format percentage from whole number (e.g., 65 for 65%)
|
|
*/
|
|
percentFromWhole: (value: number): string => {
|
|
return `${Math.round(value)}%`
|
|
},
|
|
|
|
/**
|
|
* Format date
|
|
*/
|
|
date: (date: Date | string): string => {
|
|
const dateObj = typeof date === 'string' ? new Date(date) : date
|
|
return dateFormatter.format(dateObj)
|
|
},
|
|
|
|
/**
|
|
* Format date in short format
|
|
*/
|
|
shortDate: (date: Date | string): string => {
|
|
const dateObj = typeof date === 'string' ? new Date(date) : date
|
|
return shortDateFormatter.format(dateObj)
|
|
},
|
|
|
|
/**
|
|
* Format compact number for large amounts
|
|
*/
|
|
compact: (value: number): string => {
|
|
return new Intl.NumberFormat(locale, {
|
|
notation: 'compact',
|
|
maximumFractionDigits: 1
|
|
}).format(value)
|
|
},
|
|
|
|
/**
|
|
* Format currency without symbol (for inputs)
|
|
*/
|
|
currencyNumber: (amount: number): string => {
|
|
return numberFormatter.format(amount)
|
|
},
|
|
|
|
/**
|
|
* Get currency symbol
|
|
*/
|
|
getCurrencySymbol: (): string => {
|
|
return currencyFormatter.formatToParts(1)
|
|
.find(part => part.type === 'currency')?.value || currency
|
|
},
|
|
|
|
/**
|
|
* Parse currency string back to number
|
|
*/
|
|
parseCurrency: (value: string): number => {
|
|
// Remove currency symbols and formatting, parse as float
|
|
const cleaned = value.replace(/[^\d.,\-]/g, '')
|
|
.replace(/,/g, '.') // Handle comma as decimal separator
|
|
return parseFloat(cleaned) || 0
|
|
}
|
|
}
|
|
|
|
// Make formatters available globally
|
|
return {
|
|
provide: {
|
|
format: formatters,
|
|
currency,
|
|
locale,
|
|
decimalPlaces
|
|
}
|
|
}
|
|
})
|