diff --git a/src/components/admin/__tests__/status-card-grid.test.tsx b/src/components/admin/__tests__/status-card-grid.test.tsx index 104dcac48..168bb3046 100644 --- a/src/components/admin/__tests__/status-card-grid.test.tsx +++ b/src/components/admin/__tests__/status-card-grid.test.tsx @@ -99,11 +99,36 @@ describe("buildCards()", () => { expect(cards[5].severity).toBe("info"); // audit log }); - it("links each card to a manageable destination", () => { + it("links each card to a real anchor on the admin page", () => { + // Source-of-truth list of section IDs rendered by `src/app/admin/page.tsx`. + // If you add a new section to the admin page, add the ID here. The test + // proves every status-card href can actually scroll to something — + // `startsWith("/admin")` was too lax and let the v1.4.5 regression slip + // (every CTA bounced to `/admin#integrations` which does not exist). + const realAnchorIds = new Set([ + "section-system-status", + "section-admin-general", + "section-admin-services", + "section-admin-umami", + "section-admin-glitchtip", + "section-admin-webpush", + "section-admin-bugreport", + "section-admin-feedback", + "section-admin-reminders", + "section-user-management", + "section-api-tokens", + "section-login-overview", + "section-danger-zone", + ]); + const cards = buildCards(mockOverview); for (const card of cards) { - expect(card.href.startsWith("/admin")).toBe(true); expect(card.cta.length).toBeGreaterThan(0); + // Hrefs must be `/admin#section-...` — sub-routes like `/admin/users` + // do not exist as of v1.4.6 and were the original regression. + expect(card.href).toMatch(/^\/admin#section-/); + const anchor = card.href.replace(/^\/admin#/, ""); + expect(realAnchorIds.has(anchor)).toBe(true); } }); diff --git a/src/components/admin/status-card-grid.tsx b/src/components/admin/status-card-grid.tsx index fa226575d..edc819b15 100644 --- a/src/components/admin/status-card-grid.tsx +++ b/src/components/admin/status-card-grid.tsx @@ -144,7 +144,7 @@ export function buildCards(data: StatusOverview): StatusCardProps[] { { label: "Admins", value: data.users.admins }, { label: "New 7d", value: data.users.newThisWeek }, ], - href: "/admin/users", + href: "/admin#section-user-management", cta: "Manage users", }, { @@ -156,7 +156,7 @@ export function buildCards(data: StatusOverview): StatusCardProps[] { { label: "moodLog", value: data.integrations.moodLog }, { label: "Push", value: data.integrations.webPush }, ], - href: "/admin#integrations", + href: "/admin#section-admin-umami", cta: "Configure", }, { @@ -174,7 +174,7 @@ export function buildCards(data: StatusOverview): StatusCardProps[] { }, { label: "Last err", value: fmtRelative(data.monitoring.lastErrorAt) }, ], - href: "/admin#monitoring", + href: "/admin#section-admin-glitchtip", cta: "View monitoring", }, { @@ -186,7 +186,7 @@ export function buildCards(data: StatusOverview): StatusCardProps[] { { label: "Users", value: data.backups.backedUpUsers }, { label: "Retain", value: `${data.backups.retentionDays}d` }, ], - href: "/admin#backups", + href: "/admin#section-system-status", cta: "View backups", }, { @@ -207,7 +207,7 @@ export function buildCards(data: StatusOverview): StatusCardProps[] { value: fmtRelative(data.maintenance.lastIdempotencyCleanup), }, ], - href: "/admin#maintenance", + href: "/admin#section-admin-reminders", cta: "View jobs", }, { @@ -219,7 +219,7 @@ export function buildCards(data: StatusOverview): StatusCardProps[] { { label: "Last login", value: fmtRelative(data.auditLog.lastLoginAt) }, { label: "—", value: "" }, ], - href: "/admin/audit-log", + href: "/admin#section-login-overview", cta: "Open viewer", }, ];