car_mms/app/contexts/SettingsContext.tsx
2025-09-11 14:22:27 +03:00

163 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createContext, useContext, type ReactNode } from 'react';
import type { AppSettings } from '~/lib/settings-management.server';
interface SettingsContextType {
settings: AppSettings;
formatNumber: (value: number) => string;
formatCurrency: (value: number) => string;
formatDate: (date: Date | string) => string;
formatDateTime: (date: Date | string) => string;
}
const SettingsContext = createContext<SettingsContextType | null>(null);
interface SettingsProviderProps {
children: ReactNode;
settings: AppSettings;
}
export function SettingsProvider({ children, settings }: SettingsProviderProps) {
// Helper function to convert Western numerals to Arabic numerals
const convertToArabicNumerals = (str: string): string => {
const arabicNumerals = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
return str.replace(/[0-9]/g, (digit) => arabicNumerals[parseInt(digit)]);
};
// Helper function to format date with custom pattern
const formatDateWithPattern = (date: Date, pattern: string): string => {
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
// Format numbers according to locale
const formatNumber = (num: number, padLength: number = 2): string => {
const padded = num.toString().padStart(padLength, '0');
return settings.numberFormat === 'ar-SA'
? convertToArabicNumerals(padded)
: padded;
};
return pattern
.replace(/yyyy/g, formatNumber(year, 4))
.replace(/yy/g, formatNumber(year % 100, 2))
.replace(/MM/g, formatNumber(month, 2))
.replace(/M/g, formatNumber(month, 1))
.replace(/dd/g, formatNumber(day, 2))
.replace(/d/g, formatNumber(day, 1));
};
const formatNumber = (value: number): string => {
return value.toLocaleString(settings.numberFormat);
};
const formatCurrency = (value: number): string => {
const formatted = value.toLocaleString(settings.numberFormat, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
return `${formatted} ${settings.currencySymbol}`;
};
const formatDate = (date: Date | string): string => {
const dateObj = typeof date === 'string' ? new Date(date) : date;
return formatDateWithPattern(dateObj, settings.dateDisplayFormat);
};
const formatDateTime = (date: Date | string): string => {
const dateObj = typeof date === 'string' ? new Date(date) : date;
const datePart = formatDateWithPattern(dateObj, settings.dateDisplayFormat);
const timePart = dateObj.toLocaleTimeString(settings.dateFormat, {
hour: '2-digit',
minute: '2-digit'
});
return `${datePart} ${timePart}`;
};
const contextValue: SettingsContextType = {
settings,
formatNumber,
formatCurrency,
formatDate,
formatDateTime
};
return (
<SettingsContext.Provider value={contextValue}>
{children}
</SettingsContext.Provider>
);
}
export function useSettings(): SettingsContextType {
const context = useContext(SettingsContext);
if (!context) {
throw new Error('useSettings must be used within a SettingsProvider');
}
return context;
}
// Hook for formatting utilities without requiring context
export function useFormatters(settings: AppSettings) {
// Helper function to convert Western numerals to Arabic numerals
const convertToArabicNumerals = (str: string): string => {
const arabicNumerals = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
return str.replace(/[0-9]/g, (digit) => arabicNumerals[parseInt(digit)]);
};
// Helper function to format date with custom pattern
const formatDateWithPattern = (date: Date, pattern: string): string => {
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
// Format numbers according to locale
const formatNumber = (num: number, padLength: number = 2): string => {
const padded = num.toString().padStart(padLength, '0');
return settings.numberFormat === 'ar-SA'
? convertToArabicNumerals(padded)
: padded;
};
return pattern
.replace(/yyyy/g, formatNumber(year, 4))
.replace(/yy/g, formatNumber(year % 100, 2))
.replace(/MM/g, formatNumber(month, 2))
.replace(/M/g, formatNumber(month, 1))
.replace(/dd/g, formatNumber(day, 2))
.replace(/d/g, formatNumber(day, 1));
};
const formatNumber = (value: number): string => {
return value.toLocaleString(settings.numberFormat);
};
const formatCurrency = (value: number): string => {
const formatted = value.toLocaleString(settings.numberFormat, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
return `${formatted} ${settings.currencySymbol}`;
};
const formatDate = (date: Date | string): string => {
const dateObj = typeof date === 'string' ? new Date(date) : date;
return formatDateWithPattern(dateObj, settings.dateDisplayFormat);
};
const formatDateTime = (date: Date | string): string => {
const dateObj = typeof date === 'string' ? new Date(date) : date;
const datePart = formatDateWithPattern(dateObj, settings.dateDisplayFormat);
const timePart = dateObj.toLocaleTimeString(settings.dateFormat, {
hour: '2-digit',
minute: '2-digit'
});
return `${datePart} ${timePart}`;
};
return {
formatNumber,
formatCurrency,
formatDate,
formatDateTime
};
}