diff --git a/webui/src/features/addressbook/AddressBookPage.tsx b/webui/src/features/addressbook/AddressBookPage.tsx index 05ddc4b..d02a294 100644 --- a/webui/src/features/addressbook/AddressBookPage.tsx +++ b/webui/src/features/addressbook/AddressBookPage.tsx @@ -8,6 +8,7 @@ import { DismissibleAlert, ExplorerTree, fetchAuthGroups, + formatDateTime, FormField, LoadingFrame, PasswordField, @@ -19,7 +20,8 @@ import { hasScope, type ApiSettings, type AuthInfo, - type AuthUpdate + type AuthUpdate, + type FormatDateTimeOptions } from "@govoplan/core-webui"; import { createAddressBook, @@ -291,14 +293,17 @@ function syncSourceLabel(source: AddressSyncSource): string { return source.display_name || source.external_address_book_ref || source.connector_type; } -function formatDateTime(value?: string | null): string { - if (!value) return "Never"; - try { - return new Intl.DateTimeFormat(undefined, { dateStyle: "short", timeStyle: "short" }).format(new Date(value)); - } catch { - return value; - } -} +const ADDRESS_DATE_TIME_OPTIONS: FormatDateTimeOptions = { + fallback: "Never", + year: undefined, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + timeZoneName: undefined, + dateStyle: "short", + timeStyle: "short" +}; function planSummary(plan: AddressSyncPlan | null): string { if (!plan) return "No preview loaded."; @@ -1740,7 +1745,7 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props) {selectedBookSyncSources.map((source) => (
{syncSourceLabel(source)} · {source.connector_type} · {source.status} - {source.last_success_at ? ` · last success ${formatDateTime(source.last_success_at)}` : ""} + {source.last_success_at ? ` · last success ${formatDateTime(source.last_success_at, ADDRESS_DATE_TIME_OPTIONS)}` : ""} {source.last_error ? ` · ${source.last_error}` : ""}
))} @@ -2314,7 +2319,7 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)Last attempt: {formatDateTime(syncInspector.source.last_attempted_at)} · Last success: {formatDateTime(syncInspector.source.last_success_at)}
+Last attempt: {formatDateTime(syncInspector.source.last_attempted_at, ADDRESS_DATE_TIME_OPTIONS)} · Last success: {formatDateTime(syncInspector.source.last_success_at, ADDRESS_DATE_TIME_OPTIONS)}
{syncInspector.source.last_error &&