feat(v1.4): admin page redesign — status-first card grid + per-section extraction#133
Merged
feat(v1.4): admin page redesign — status-first card grid + per-section extraction#133
Conversation
Replaces the implicit, fluid status of the legacy admin monolith with a 6-card grid at the top of /admin per ui-guidelines.md §3.4. Each card pairs a §2.6 colored dot with a text label so state never relies on color alone (WCAG 1.4.1). - New aggregator endpoint /api/admin/status-overview returns a single batched Promise.all (no N+1) covering Users, Integrations, Monitoring, Backups, Maintenance, Audit log — with severity precomputed server-side. - New <StatusCardGrid> + reusable <StatusBadge> component in src/components/admin/. Pure buildCards() function makes severity mapping unit-testable. - Tests: 14 new (8 aggregator severity/shape, 6 grid badge + a11y). - Wires the grid above the existing admin sections; per-section extraction will land in follow-ups. Co-Authored-By: Marc-André Bombeck <noreply@anthropic.com>
4 tasks
MBombeck
added a commit
that referenced
this pull request
May 8, 2026
…145) The admin page was a single 2,702-line client component with nineteen inline functions covering everything from system status to feedback inbox. The status-card grid foundation in #133 already moved the at-a-glance dashboard out; this commit moves the inner panels. Split into one file per logical section in src/components/admin/: _shared.tsx 276 LOC shared types, hooks, primitives (PasswordInput, StatusItem, SettingsToggle, useAdminSettings, useUpdateSettings, useSystemStatus, getApiErrorMessage) system-status-section.tsx 155 general-settings-section.tsx 54 services-section.tsx 68 umami-section.tsx 173 glitchtip-section.tsx 172 web-push-vapid-section.tsx 148 bug-report-section.tsx 109 reminders-section.tsx 318 user-management-section.tsx 341 api-token-overview-section.tsx 144 login-overview-section.tsx 181 danger-zone-section.tsx 118 feedback-inbox-section.tsx 511 (inbox + category badge + detail dialog) src/app/admin/page.tsx is now a 77-line shell that imports the 14 sections and the existing status-card-grid.tsx. No behavior change — every section keeps the same DOM, the same query keys, the same i18n keys, the same id="…" anchors so deep-links from the sidebar still scroll into place. UserManagementSection no longer takes a queryClient prop; it grabs its own via useQueryClient() like every other section does.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the implicit, fluid status surface of the legacy 2699-LOC
/adminmonolith with a status-first 6-card grid perdocs/ui-guidelines.md§3.4. Each card pairs the §2.6 colored dot with a text label so state never relies on color alone (WCAG 1.4.1).This PR lands the foundation:
/api/admin/status-overview— a single batchedPromise.all(no N+1) that computes severity server-side for: Users, Integrations, Monitoring, Backups, Maintenance, Audit log.<StatusCardGrid>+ reusable<StatusBadge>insrc/components/admin/. PurebuildCards()function makes severity mapping unit-testable.Aggregator endpoint shape
Severity rules: backups alert >14d / caution 8–14d / good ≤8d; monitoring alert on error <24h, good when both enabled; maintenance alert when worker stopped.
LOC table (was vs now)
src/app/admin/page.tsxsrc/components/admin/status-card-grid.tsxsrc/components/admin/__tests__/status-card-grid.test.tsxsrc/app/api/admin/status-overview/route.tssrc/app/api/admin/status-overview/__tests__/route.test.tsThe page LOC reduction comes in the per-section extraction follow-ups — this PR is the structural foundation: aggregator + grid + tests.
Multi-agent review
Self-review against the §3.4 requirements:
Senior Dev pass
Promise.allof 16 prisma calls — verified by the route test assertingdataBackup.findManyis called exactly once anduser.countexactly 5 times (no loops).requireAdmin()runs first; route annotated withadmin.status-overview.<StatusBadge>carriesaria-label="Status: <text>", the dot isaria-hidden, and the label text is always rendered (not color-only).Product Lead pass
Out of scope (medium follow-ups)
src/components/admin/<section>.tsx(Users → Integrations → Monitoring → Backups → Maintenance → Audit log) — each as its own commit. Tracking branch retains/adminas a sidebar shell once extraction lands.system.cleanup.*) — the aggregator already reads them but the cleanup jobs would need to write the entries.Test plan
pnpm test— 424 tests green (verified locally).pnpm typecheck— clean (verified locally).pnpm exec prettier --checkon touched files (verified locally)./adminas admin → 6 cards render with skeletons → load → severity badges visible./adminas non-admin → grid 401s gracefully.🤖 Generated with Claude Code