feat: Complete high-priority i18n localization with date/time support
This commit implements comprehensive localization for high-priority components: ## Tracking Pages (4 files) - Localized feeding, sleep, diaper, and medicine tracking pages - Replaced hardcoded strings with translation keys from tracking namespace - Added useTranslation hook integration - All form labels, buttons, and messages now support multiple languages ## Child Dialog Components (2 files) - Localized ChildDialog (add/edit child form) - Localized DeleteConfirmDialog - Added new translation keys to children.json for dialog content - Includes validation messages and action buttons ## Date/Time Localization (14 files + new hook) - Created useLocalizedDate hook wrapping date-fns with locale support - Supports 5 languages: English, Spanish, French, Portuguese, Chinese - Updated all date formatting across: * Tracking pages (feeding, sleep, diaper, medicine) * Activity pages (activities, history, track activity) * Settings components (sessions, biometric, device trust) * Analytics components (insights, growth, sleep chart, feeding graph) - Date displays automatically adapt to user's language (e.g., "2 hours ago" → "hace 2 horas") ## Translation Updates - Enhanced children.json with dialog section containing: * Form field labels (name, birthDate, gender, photoUrl) * Action buttons (add, update, delete, cancel, saving, deleting) * Delete confirmation messages * Validation error messages Files changed: 17 files (+164, -113) Languages supported: en, es, fr, pt-BR, zh-CN 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
92
maternal-web/hooks/useLocalizedDate.ts
Normal file
92
maternal-web/hooks/useLocalizedDate.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { useTranslation } from './useTranslation';
|
||||
import {
|
||||
format as dateFnsFormat,
|
||||
formatDistanceToNow as dateFnsFormatDistanceToNow,
|
||||
formatDistance as dateFnsFormatDistance,
|
||||
formatRelative as dateFnsFormatRelative,
|
||||
} from 'date-fns';
|
||||
import { enUS, es, fr, ptBR, zhCN } from 'date-fns/locale';
|
||||
|
||||
/**
|
||||
* Map of i18next language codes to date-fns locales
|
||||
*/
|
||||
const localeMap: Record<string, Locale> = {
|
||||
'en': enUS,
|
||||
'en-US': enUS,
|
||||
'es': es,
|
||||
'es-ES': es,
|
||||
'fr': fr,
|
||||
'fr-FR': fr,
|
||||
'pt': ptBR,
|
||||
'pt-BR': ptBR,
|
||||
'zh': zhCN,
|
||||
'zh-CN': zhCN,
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom hook for localized date formatting using date-fns
|
||||
* Automatically applies the correct locale based on the current i18n language
|
||||
*/
|
||||
export function useLocalizedDate() {
|
||||
const { language } = useTranslation();
|
||||
|
||||
// Get the locale for the current language, fallback to enUS
|
||||
const locale = localeMap[language] || enUS;
|
||||
|
||||
/**
|
||||
* Format a date using date-fns with the current locale
|
||||
* @param date - The date to format
|
||||
* @param formatStr - The format string (e.g., 'PPP', 'MM/dd/yyyy')
|
||||
*/
|
||||
const format = (date: Date | number | string, formatStr: string): string => {
|
||||
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
||||
return dateFnsFormat(dateObj, formatStr, { locale });
|
||||
};
|
||||
|
||||
/**
|
||||
* Format a date as a distance to now (e.g., "2 hours ago")
|
||||
* @param date - The date to format
|
||||
* @param options - Optional options for formatDistanceToNow
|
||||
*/
|
||||
const formatDistanceToNow = (
|
||||
date: Date | number | string,
|
||||
options?: { addSuffix?: boolean; includeSeconds?: boolean }
|
||||
): string => {
|
||||
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
||||
return dateFnsFormatDistanceToNow(dateObj, { ...options, locale });
|
||||
};
|
||||
|
||||
/**
|
||||
* Format the distance between two dates
|
||||
* @param date - The later date
|
||||
* @param baseDate - The earlier date
|
||||
* @param options - Optional options for formatDistance
|
||||
*/
|
||||
const formatDistance = (
|
||||
date: Date | number,
|
||||
baseDate: Date | number,
|
||||
options?: { addSuffix?: boolean; includeSeconds?: boolean }
|
||||
): string => {
|
||||
return dateFnsFormatDistance(date, baseDate, { ...options, locale });
|
||||
};
|
||||
|
||||
/**
|
||||
* Format a date relative to now (e.g., "today at 5:00 PM")
|
||||
* @param date - The date to format
|
||||
* @param baseDate - Optional base date (defaults to now)
|
||||
*/
|
||||
const formatRelative = (
|
||||
date: Date | number,
|
||||
baseDate?: Date | number
|
||||
): string => {
|
||||
return dateFnsFormatRelative(date, baseDate || new Date(), { locale });
|
||||
};
|
||||
|
||||
return {
|
||||
format,
|
||||
formatDistanceToNow,
|
||||
formatDistance,
|
||||
formatRelative,
|
||||
locale,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user