Skip to content

Admin screens on the design kit (#96 part C) - #101

Merged
JOY (JOY) merged 1 commit into
devfrom
claude/96c-admin-ui
Nov 4, 2026
Merged

JOY (JOY) merged 1 commit into
devfrom
claude/96c-admin-ui

Conversation

@JOY

@JOY JOY (JOY) commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Refs #96

Part C of #96: every page under /admin on the #95 design kit. Parts A (public flows) and B (/me) are separate PRs under the same issue.

What changed

  • No behaviour change. Same data calls, server actions, form field names and values, hidden inputs, required/maxLength, confirm texts and role checks on every page (checked line by line against origin/dev by an independent reviewer). The one call removed is the /admin page's isStaff(["admin"]) lookup that only decided whether to show a link to /admin/roles; the new tabs do that now.
  • Admin tabs (admin/layout.tsx, _components/AdminNav.tsx): one row of tabs, built from the visitor's roles: moderators get review, evidence and payment requests; finance gets accounts, account swaps, statements, unmatched and stopped inbound events; admins get all of them plus roles. A signed-out or non-staff visitor sees no tabs (pages still 404 on their own). They replace the per-page button rows and "← back" links. On phones the row scrolls sideways and the current tab is scrolled into view.
  • Shared admin pieces (admin/_components/ui.tsx): page frame (title, action, rules text at a readable width), section heading with a count, item card with the actions under a hairline, label/value grid, and a table in a named, focusable scroll box.
  • States: EmptyState for every empty queue, Notice for blocked actions, "this is your own item" warnings, a stopped payment request, a hidden image and the waiting list that failed to load; admin/loading.tsx (skeleton under the tabs) and admin/error.tsx (retry, tabs stay).
  • Tables for audit trails, resolved statement rows and role changes. Organizers to verify and the staff list stay wrapping lists so their buttons stay on screen at 375 px.
  • Kit: one new file, components/ui/Notice.tsx (info / warning / danger / success, optional title, one text colour per tone). Existing kit files are unchanged. The old rounded-full pill and the btn-secondary text-red-700 double colour are gone (Badge, btn-danger).

Not in this PR: /admin/unmatched still renders the shared components/UnmatchedTransaction.tsx and components/Reconciliation.tsx, which /me/campaigns/[id]/unmatched also uses; part B owns them (noted on #96).

Evidence

  • tsc --noEmit, eslint, prettier --check: clean. vitest run: 72 files, 920 tests passed.
  • Lighthouse accessibility (local, signed in as an admin): 100 on all 9 pages, desktop and mobile.
  • No page scrolls sideways at 375 px (measured with Playwright).
  • Independent design/a11y review (fresh-context agent): no behaviour regressions; fixed its findings (actions off-screen in two tables on phones, new-tab cues, hint under the right field, empty reason shows "—").

Screenshots

Seeded local stack (DOS.Me dev migrations, the #95 seed plus admin data: campaigns in review, a campaign waiting for an account, organizers and accounts to verify, an account swap, ambiguous statement rows, stopped inbound events, audit entries, reported and hidden evidence, succeeded back campaigns with one stopped). Desktop 1440 px full page; phone 375 px, top of the page. Images live on the assets/pr-96c-screenshots branch.

/admin

/admin review desktop /admin review 375 px

/admin/evidence

/admin evidence desktop /admin evidence 375 px

/admin/payment-requests

/admin payment-requests desktop /admin payment-requests 375 px

/admin/accounts

/admin accounts desktop /admin accounts 375 px

/admin/account-swaps

/admin account-swaps desktop /admin account-swaps 375 px

/admin/statements

/admin statements desktop /admin statements 375 px

/admin/unmatched

/admin unmatched desktop /admin unmatched 375 px

/admin/inbound

/admin inbound desktop /admin inbound 375 px

/admin/roles

/admin roles desktop /admin roles 375 px

🤖 Generated with Claude Code


📌 TL;DR

This PR refactors the admin dashboard to use a new, consistent set of UI primitives (AdminPage, ItemCard, Facts, etc.) and introduces a role-based navigation layout with loading/error states. It significantly improves the visual consistency, accessibility, and mobile responsiveness of the finance and moderation queues.

🎯 Type of Change

  • 🚀 New feature
  • 🐛 Bugfix
  • 🧹 Refactor
  • ⚡ Performance
  • 📚 Documentation
  • ⚙️ CI / Configuration

🔍 Changes Walkthrough

File Summary of Changes
apps/web/src/app/admin/_components/AdminNav.tsx New: Client component for admin tabs. Automatically scrolls the active tab into view on mobile devices.
apps/web/src/app/admin/_components/ui.tsx New: Shared UI primitives for admin pages (AdminPage, AdminSection, ItemCard, Facts, DataTable). Standardizes layout, spacing, and accessibility (ARIA labels).
apps/web/src/app/admin/layout.tsx New: Root layout for the admin section. Fetches user roles to dynamically render the AdminNav tabs.
apps/web/src/app/admin/loading.tsx New: Skeleton loading state for admin pages to improve perceived performance.
apps/web/src/app/admin/error.tsx New: Error boundary UI for admin pages, allowing users to retry failed data fetches.
apps/web/src/app/admin/page.tsx Refactor: Replaced manual layout with AdminPage/AdminSection. Updated campaign review cards to use ItemCard and Facts.
apps/web/src/app/admin/accounts/page.tsx Refactor: Migrated account verification UI to new primitives. Replaced raw HTML labels with Field components and added EmptyState for empty queues.
apps/web/src/app/admin/account-swaps/page.tsx Refactor: Migrated account swap review UI to new primitives. Improved status badges and form layouts using ItemActions and Field.
apps/web/src/app/admin/evidence/page.tsx Refactor: Updated evidence moderation UI. Improved image accessibility (aria-labels) and standardized report lists.
apps/web/src/app/admin/inbound/page.tsx Refactor: Updated parked inbound events UI. Converted the audit trail from a list to a DataTable for better mobile scrolling.

📊 Architectural Flow

flowchart TD
    subgraph AdminLayout["Admin Layout (layout.tsx)"]
        Session[getSession] --> Roles{Check Roles}
        Roles -->|Moderation| ModLinks[Mod Links]
        Roles -->|Finance| FinLinks[Fin Links]
        Roles -->|Admin| AdminLinks[Admin Links]
        ModLinks & FinLinks & AdminLinks --> Nav[AdminNav]
    end

    subgraph AdminPages["Admin Pages"]
        Page[Page Component] --> UI[UI Primitives]
        UI --> AdminPage[AdminPage]
        UI --> AdminSection[AdminSection]
        UI --> ItemCard[ItemCard]
        UI --> Facts[Facts]
        UI --> DataTable[DataTable]
    end

    Nav --> AdminPages
    Loading[loading.tsx] -.-> AdminPages
    Error[error.tsx] -.-> AdminPages
Loading

Moves every page under /admin onto the #95 kit with no behaviour change:
the same data calls, server actions, form fields, confirms and role checks.

- admin/layout.tsx: role-aware tabs for the admin pages (moderator,
  finance, admin), replacing the per-page link rows and back links; a
  non-staff visitor sees no tabs. The current tab scrolls into view on
  phones.
- admin/_components/ui.tsx: page frame, section with count, item card,
  label/value grid and a focusable table that scrolls sideways on phones.
- loading.tsx and error.tsx for the admin section; EmptyState for empty
  queues; Notice for blocked actions, own-item warnings and load errors.
- New kit file components/ui/Notice.tsx (existing kit files unchanged).
- Audit trails, resolved statement rows and role changes are tables;
  organizers to verify and staff stay wrapping lists so their actions
  stay on screen at 375 px.

Refs #96

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8648ca02-7d38-4ac5-8232-009fc36d9b73

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

dos[bot]
dos Bot approved these changes Nov 4, 2026

@dos dos Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱️ Code Review completed (15 eligible files · 124,422 chars · 2 model call(s) · 5 PR unit(s))

Whole diff with bounded context at base 31f0313 / head ef6299f.

✅ CLEAN_PASS: Complete diff reviewed

Context investigation was bounded to the explicitly requested snapshot paths.

@JOY

Copy link
Copy Markdown
Contributor Author

PO acceptance (part C of #96): merge at ef6299f. CI green, DOS Code Review passed, vitest 920, Lighthouse a11y 100 on all 9 admin pages desktop + mobile, independent review found no behaviour change. No file overlap with part A (merged). Follow-ups: fold components/ui/Notice into part A's Callout if they duplicate; wrap isStaff/getSession in React cache().

@JOY
JOY (JOY) merged commit 133fae1 into dev Nov 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant