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:
1 parent
f7357141eb
commit
f92f8de96e
12 files changed
+206
-17
No files matched your search
@@ -17,6 +17,7 @@ import {
|
||||
} from "../api/client";
|
||||
import IntegrationForm from "../components/IntegrationForm";
|
||||
import IntegrationEditForm from "../components/IntegrationEditForm";
|
||||
import { formatDateTime } from "../utils/date";
|
||||
|
||||
function proxmoxStatusBadge(status: string) {
|
||||
return status === "running" ? (
|
||||
@@ -547,7 +548,7 @@ export default function Integrations({ user }: { user: CurrentUser }) {
|
||||
)}
|
||||
{!d.authorized && <span className="badge bg-yellow-lt text-yellow">Unauthorized</span>}
|
||||
</td>
|
||||
<td className="text-secondary">{d.lastSeen ? new Date(d.lastSeen).toLocaleString() : "—"}</td>
|
||||
<td className="text-secondary">{d.lastSeen ? formatDateTime(new Date(d.lastSeen)) : "—"}</td>
|
||||
{canEdit && (
|
||||
<td>
|
||||
<div className="btn-list flex-nowrap">
|
||||
@@ -775,7 +776,7 @@ export default function Integrations({ user }: { user: CurrentUser }) {
|
||||
<td className="text-secondary">{t.projectName}</td>
|
||||
<td className="text-secondary">
|
||||
{t.lastTask
|
||||
? new Date(t.lastTask.end ?? t.lastTask.start ?? t.lastTask.created ?? "").toLocaleString()
|
||||
? formatDateTime(new Date(t.lastTask.end ?? t.lastTask.start ?? t.lastTask.created ?? ""))
|
||||
: "—"}
|
||||
</td>
|
||||
<td>{semaphoreStatusBadge(t)}</td>
|
||||
|
||||
Reference in new issue
Block a user