Add a Date & Time setting and fix inconsistent date formats app-wide

Different tables used different date formats: Servers & Tasks used a
fixed "YYYY-MM-DD HH:mm:ss" (24h), while Audit Log, DNS, Integrations
(Tailscale/Semaphore), and Users called plain .toLocaleString() with
no options, which renders using the browser's own locale — different
per browser/OS, and inconsistent with the other pages' fixed format.

- New Settings -> Date & Time page: pick date order (YYYY-MM-DD,
  DD/MM/YYYY, MM/DD/YYYY) and 12h vs 24h clock, with a live preview.
- utils/date.ts's formatDateTime() now reads these settings instead of
  being hardcoded to sv-SE/24h; the setting is fetched once at app
  startup (alongside /api/me) via a new non-secret GET
  /api/settings/display (any signed-in user, same rationale as the
  badge-color endpoints) and applied immediately on save too, without
  needing a page reload.
- Switched every remaining raw new Date(...).toLocaleString() call
  (Audit Log, DNS zone sync time, Tailscale/Semaphore last-seen,
  Users' last login) over to the shared formatter, so every table now
  renders dates identically.

Verified the formatter's date-order x 12h logic against all six
combinations plus the midnight/noon 12h edge cases, and the settings
endpoints end-to-end (defaults, partial updates, validation
rejection, audit logging) against the real dev server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
bobbanandClaude Sonnet 5 committed 2026-09-15 22:17:06 +02:00
1 parent f7357141eb
commit f92f8de96e
12 files changed
+206 -17

No files matched your search

+4
View File
@@ -14,8 +14,10 @@ import Integrations from "./pages/Integrations";
import Settings from "./pages/Settings";
import NotificationSettings from "./pages/settings/NotificationSettings";
import BadgeSettings from "./pages/settings/BadgeSettings";
import DateTimeSettings from "./pages/settings/DateTimeSettings";
import CacheSettings from "./pages/settings/CacheSettings";
import AppShell from "./layout/AppShell";
import { setDateTimeSettings } from "./utils/date";
const roleRank: Record<UserRole, number> = { viewer: 0, operator: 1, admin: 2 };
@@ -49,6 +51,7 @@ export default function App() {
setUser(null);
},
);
api.settings.display().then((res) => setDateTimeSettings(res.display)).catch(() => {});
}, []);
if (user === undefined) {
@@ -96,6 +99,7 @@ export default function App() {
<Route index element={<Navigate to="notifications" replace />} />
<Route path="notifications" element={<NotificationSettings />} />
<Route path="badges" element={<BadgeSettings />} />
<Route path="date-time" element={<DateTimeSettings />} />
<Route path="cache" element={<CacheSettings />} />
</Route>
</Routes>