This commit is contained in:
2026-01-23 20:35:40 +03:00
parent cf3b0e48ec
commit 66c151653e
137 changed files with 41495 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
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
};
}