From 0fc83b693e713ac790e310041b83bbe1e74282e0 Mon Sep 17 00:00:00 2001 From: rustmailer Date: Wed, 3 Dec 2025 09:23:51 +0800 Subject: [PATCH] fix(i18n, dashboard): Internationalize recent activity chart dates --- web/src/features/dashboard/index.tsx | 43 +++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/web/src/features/dashboard/index.tsx b/web/src/features/dashboard/index.tsx index 99ebd31..7b1dcb4 100644 --- a/web/src/features/dashboard/index.tsx +++ b/web/src/features/dashboard/index.tsx @@ -35,18 +35,31 @@ interface DailyActivity { count: number; } -function convertRecentActivity(timeBuckets: TimeBucket[]): DailyActivity[] { +function convertRecentActivity(timeBuckets: TimeBucket[], locale: string): DailyActivity[] { + const dateFormatter = new Intl.DateTimeFormat(locale, { + month: 'short', + day: 'numeric', + }); + return timeBuckets.map(bucket => { const date = new Date(bucket.timestamp_ms); - const mm = String(date.getMonth() + 1).padStart(2, '0'); - const dd = String(date.getDate()).padStart(2, '0'); return { - date: `${mm}-${dd}`, + date: dateFormatter.format(date), count: bucket.count, + timestamp_ms: bucket.timestamp_ms, }; }); } +const formatTooltipDate = (timestamp_ms: number, locale: string): string => { + const date = new Date(timestamp_ms); + return new Intl.DateTimeFormat(locale, { + year: 'numeric', + month: 'long', + day: 'numeric', + }).format(date); +}; + const COLORS = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444']; // Skeleton Components @@ -94,7 +107,10 @@ export default function MailArchiveDashboard() { queryFn: get_dashboard_stats, }); - const { t } = useTranslation(); + const { t, i18n } = useTranslation(); + + const currentLocale = i18n.resolvedLanguage || i18n.language || navigator.language; + const totalAttachments = (stats?.with_attachment_count ?? 0) + (stats?.without_attachment_count ?? 0); const attachmentRatio = totalAttachments > 0 ? (stats?.with_attachment_count ?? 0) / totalAttachments : 0; @@ -253,12 +269,25 @@ export default function MailArchiveDashboard() { {hasRecentActivity ? ( - + - + formatNumber(v as number)} + content={({ payload }) => { + if (payload && payload.length) { + const dataPoint = payload[0].payload; + const fullDate = formatTooltipDate(dataPoint.timestamp_ms, currentLocale); + return ( +
+

{fullDate}

+

{t('dashboard.emails')}: {formatNumber(dataPoint.count)}

+
+ ); + } + return null; + }} contentStyle={{ backgroundColor: 'hsl(var(--background))', border: '1px solid hsl(var(--border))',