import dayjs, { type Dayjs } from "dayjs" import localizedFormat from "dayjs/plugin/localizedFormat" import relativeTime from "dayjs/plugin/relativeTime" import "dayjs/locale/fr" import "dayjs/locale/en" dayjs.extend(localizedFormat) dayjs.extend(relativeTime) const SUPPORTED_LOCALES = new Set(["fr", "en", "de", "es", "it", "pt", "nl", "pl", "ja", "zh"]) let activeLocale: string | null = null /** Browser locale for dayjs (client); stable fallback on server. */ export function resolveMailDateLocale(): string { if (typeof navigator === "undefined") return "fr" const base = navigator.language.split("-")[0]?.toLowerCase() ?? "fr" return SUPPORTED_LOCALES.has(base) ? base : "en" } export function ensureMailDateLocale(): void { const next = resolveMailDateLocale() if (activeLocale === next) return dayjs.locale(next) activeLocale = next } export function parseMailDate(iso: string): Dayjs | null { if (!iso?.trim()) return null const d = dayjs(iso) return d.isValid() ? d : null } export type MailDateDisplayVariant = "list" | "preview" | "detail" const TWO_WEEKS_MS = 14 * 24 * 60 * 60 * 1000 function relativeSuffix(d: Dayjs, now: Dayjs): string { if (d.isAfter(now)) return "" return ` (${d.fromNow()})` } /** Colonne date de la liste (fuseau navigateur). */ export function formatMailListDate(iso: string, now: Dayjs = dayjs()): string { ensureMailDateLocale() const d = parseMailDate(iso) if (!d) return "—" if (d.isSame(now, "day")) { return d.format("LT") } if (d.isSame(now, "year")) { return d.format("D MMM") } return d.format("L") } /** En-tête / aperçu d’un message (fuseau navigateur). */ export function formatMailPreviewDate(iso: string, now: Dayjs = dayjs()): string { ensureMailDateLocale() const d = parseMailDate(iso) if (!d) return "—" const time = d.format("LT") if (d.isSame(now, "day")) { return `${time}${relativeSuffix(d, now)}` } const msAgo = now.valueOf() - d.valueOf() const withinTwoWeeks = msAgo >= 0 && msAgo < TWO_WEEKS_MS const datePart = d.format("ddd D MMM") if (withinTwoWeeks) { return `${datePart} ${time}${relativeSuffix(d, now)}` } if (d.isSame(now, "year")) { return `${datePart} ${time}` } return `${d.format("ddd D MMM YYYY")} ${time}` } /** Citations, impression, panneau « détails » (sans relatif). */ export function formatMailDetailDate(iso: string, now: Dayjs = dayjs()): string { ensureMailDateLocale() const d = parseMailDate(iso) if (!d) return "—" const time = d.format("LT") const datePart = d.format("ddd D MMM") if (d.isSame(now, "year")) { return `${datePart} ${time}` } return `${d.format("ddd D MMM YYYY")} ${time}` } export function formatMailDate(iso: string, variant: MailDateDisplayVariant): string { switch (variant) { case "list": return formatMailListDate(iso) case "preview": return formatMailPreviewDate(iso) case "detail": return formatMailDetailDate(iso) } }