Skip to main content

Phase 3 – Admin Dashboard Redesign + Functional Audit

Branch: feat/admin-dashboard-redesign-phase-3 Scope: All retained /admin/* nav pages (Dashboard, Locations, Activity, Subscriptions, Prospecting). /admin/internal/* pages (processing, funding-queue, invoices, automations) are Phase 2 territory and out of scope here. Goal: Not just a visual refresh. Consolidate duplication, surface actionable attention items, and make the admin panel functional first, pretty second. Data layer untouched. This document is the planning artifact. Review and approve before any component code is written.

1. Context recap — design language inherited

From Phase 1 (PR #463) and Phase 2 (PR #480):
  • Summary bar replaces gradient headers.
  • MetricCard (4-corner, gradient accent) replaces ad-hoc KPI Cards.
  • SectionLabel (small-caps + gradient hairline) replaces <h2> / CardTitle.
  • AnimatedSection for staggered reveals.
  • StatusBadge (variant pill) replaces inline colored spans.
  • NextActionCard = “here’s what matters right now” surface.
Phase 3 inherits everything AND applies the 5 Steps framework (requirements → delete → simplify → accelerate → automate).

2. Functional audit — what’s actually wrong

2.1 Page-level redundancy map

PageWhat it shows todayOverlap with
/adminAttention Queue + KPI grid + 4 charts/admin/metrics overview tab, /admin/reports
/admin/metrics4 tabs (Overview/Locations/Subs/Activity) — each a mini-version of the sibling page/admin, /admin/locations, /admin/subscriptions, /admin/activity (ALL of them)
/admin/reports4 charts identical to /admin + an extra “Top Locations by Underwriting”/admin
/admin/locationsInstallations table + a helper hint cardLocations tab in /admin/metrics
/admin/activityActivity table onlyActivity tab in /admin/metrics
/admin/subscriptionsInline KPIs + 2 charts + top-locations listSubscriptions tab in /admin/metrics
The verdict: 5 pages show overlapping data. Nobody knows which to open.

2.2 Attention Queue is passive

AdminAttentionQueue identifies:
  • At-risk partners (this-week drop vs. last-week)
  • Incomplete mappings (missing pipelines / custom fields)
  • Billing issues
But it’s collapsible-only. No deep links, no “fix this” CTA, no dismiss/snooze. It’s a read-only dashboard widget when it should be a to-do queue.

2.3 Location scope is scattered

AdminLocationContext filters every page. Currently exposed as:
  • SubAccountSwitcher in shell (top-right)
  • An “All Locations / Selected” badge re-implemented on each page
No single visible “you are scoped to X” row with a clear reset affordance.

2.4 Time range is also scattered

useAuthenticatedAdminTimeRange persists time range across pages but only /admin and /admin/reports expose the Select. Other pages silently inherit whatever you last set without surfacing it.

2.5 Dead wrappers

  • /admin/locations has a helper-hint Card at the bottom that should be a Tooltip on the table header.

2.6 Export is inconsistent

Only /admin has Export. /admin/metrics, /admin/reports, /admin/subscriptions, /admin/activity all should (same shape, same data).

3. 5 Steps framework applied

Step 1 — Make requirements less dumb

What does the admin panel need to be? Three jobs, in priority order:
  1. Triage: “What needs my attention right now?” — at-risk partners, broken mappings, billing. Action-oriented.
  2. Monitor: “Are we healthy?” — KPIs, trends, charts.
  3. Investigate: “Show me everything for location X” — drill-down.
Today’s panel buries #1 (tiny collapsible), bloats #2 (across 5 overlapping pages), and barely does #3 (click location in table → filter scope → hope the right chart updates).

Step 2 — Delete parts

Pages to delete:
  • /admin/metrics — completely redundant with /admin + siblings. Redirect to /admin.
  • /admin/reports — redundant with /admin. Keep the extra “Top Locations by Underwriting” chart but fold it into /admin.
Components to delete:
  • AdminHeader (the last gradient holdover) — replaced by AdminSummaryBar.
  • /admin/locations helper-hint Card → becomes tooltip on table header.
Nav items to update: drop “Reports” from shell nav. 7 nav items → retained core admin nav items (Dashboard, Locations, Activity, Subscriptions, Prospecting).

Step 3 — Simplify

New IA:
  1. /admin (Dashboard) — the triage + monitor home. Summary bar + NextActionQueue + KPIs + 4 charts.
  2. /admin/locations — sub-account directory + drill-down.
  3. /admin/activity — full activity log (cross-location).
  4. /admin/subscriptions — subscription + MRR analytics.
Every page uses the same AdminSummaryBar with:
  • Small “ADMIN” eyebrow
  • Scope chip (clickable → opens location switcher, reset affordance included)
  • Export button (appears on every page with exportable data)
  • Refresh icon

Step 4 — Accelerate (after 1-3)

AdminAttentionQueueAdminNextActionQueue:
  • Pinned at top of /admin, not collapsible-by-default (always visible, chips expand inline)
  • Each item gets a primary action: “Open” (deep link to scoped page), “Dismiss” (snooze 24h), “Assign” (future)
  • Severity color-coded via StatusBadge primitive
  • Count chip shows total pending in shell nav (“Dashboard” nav item gets a Badge with count)
Global search (AdminGlobalSearch): audit behavior. Should support:
  • Type location name → jump to /admin/locations/[locationId]
  • Type contact email → jump to /contact/[id] with admin override
  • Type PR/ticket id → jump (future)

Step 5 — Automate (last)

Out of scope for this PR. Candidates for later:
  • Auto-remediation bots for common attention items (e.g., “incomplete mapping — run sync”)
  • Weekly auto-summary digest to Brock’s Telegram
  • Scheduled exports

4. Target structure — page by page

4.1 /admin (Dashboard)

<AnimatedSection>
  <AdminSummaryBar scope={...} timeRange={...} onExport={...} />
</AnimatedSection>

<AnimatedSection delay={100}>
  <AdminNextActionQueue items={...} onAction={...} />
</AnimatedSection>

<AnimatedSection delay={200}>
  <SectionLabel>Overview</SectionLabel>
  <AdminKPIGrid data={aggregateKPIs} />  {/* internals → MetricCard */}
</AnimatedSection>

<AnimatedSection delay={300}>
  <SectionLabel>Performance</SectionLabel>
  <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
    <ChartFrame title="Credit Reports"><AdminCreditReportsChart /></ChartFrame>
    <ChartFrame title="Underwriting"><AdminUnderwritingChart /></ChartFrame>
  </div>
</AnimatedSection>

<AnimatedSection delay={400}>
  <SectionLabel>Distribution</SectionLabel>
  <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
    <ChartFrame title="Credit Score Distribution"><AdminScoreDistributionChart /></ChartFrame>
    <ChartFrame title="Top Locations by Credit Reports"><AdminTopLocationsChart /></ChartFrame>
  </div>

  {/* folded in from /admin/reports */}
  <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
    <ChartFrame title="Top Locations by Underwriting"><AdminTopLocationsChart variant="underwriting" /></ChartFrame>
  </div>
</AnimatedSection>

4.2 /admin/locations

  • Summary bar with scope chip + Export
  • SectionLabel “All Sub-Accounts”
  • AdminInstallationsTable (same, but hint-text moves to tooltip)
  • Row click → /admin/locations/[locationId] (already exists, 1061 LOC — out of scope for this PR)

4.3 /admin/activity

  • Summary bar
  • SectionLabel “Recent Activity”
  • AdminActivityTable
  • New: filter chips above the table (type: install/credit_pull/underwriting/support) — enhances functionality

4.4 /admin/subscriptions

  • Summary bar
  • SectionLabel “Subscription Health” + KPI grid (refactor inline KPIs → MetricCard)
  • SectionLabel “Trends” + 2 charts in ChartFrame
  • SectionLabel “Top Locations by MRR” + existing list (styled as proper rows, not mock-table)
  • Summary bar (no time range)
  • Summary bar
  • Audit the existing page (275 LOC) — likely needs MetricCard + ChartFrame treatment

4.7 Deleted / redirected

  • /admin/metrics → 301 redirect to /admin
  • /admin/reports → 301 redirect to /admin

5. Component-level changes

ComponentChange
AdminHeaderDelete. Replaced by components/admin/AdminSummaryBar.tsx.
AdminAttentionQueueRename + enhanceAdminNextActionQueue. Add per-item actions (Open/Dismiss). Not collapsible-by-default.
AdminKPIGridInternals → MetricCard. API unchanged.
AdminCharts.tsx (all 4 charts)Wrap each in ChartFrame.
Shell nav (AdminShell.tsx)Remove Reports nav item. Add attention-count badge on Dashboard nav item.

6. New primitives

  • components/shared/ChartFrame.tsxSectionLabel + Card + consistent padding + loading skeleton. Reusable for Phase 4 (Partner Portal earnings).
  • components/admin/AdminSummaryBar.tsx — admin-specific summary bar with eyebrow + scope chip + time-range pill selector + action toolbar.
  • components/admin/AdminNextActionQueue.tsx — replaces AdminAttentionQueue. Chip-based, action-oriented.

7. File changes

New

  • components/shared/ChartFrame.tsx
  • components/admin/AdminSummaryBar.tsx
  • components/admin/AdminNextActionQueue.tsx
  • docs/phase-3-admin-dashboard-redesign-plan.md (this file)

Edited

  • app/admin/page.tsx
  • app/admin/locations/page.tsx
  • app/admin/activity/page.tsx
  • app/admin/subscriptions/page.tsx
  • components/admin-metrics/AdminKPIGrid.tsx (internals → MetricCard)
  • components/admin-metrics/AdminCharts.tsx (wrap in ChartFrame)
  • components/admin-metrics/index.ts (drop AdminHeader export)
  • components/admin/AdminShell.tsx (remove Reports, add attention badge)

Deleted / redirected

  • components/admin-metrics/AdminHeader.tsx (replaced)
  • app/admin/metrics/page.tsx → redirect to /admin
  • app/admin/reports/page.tsx → redirect to /admin

8. Out of scope

  • /admin/internal/* pages (Phase 2 territory — processing, funding-queue, invoices, automations).
  • /admin/locations/[locationId] detail page (1061 LOC — deserves its own Phase 3.1).
  • Data-layer changes (useAuthenticatedAdminData, hooks).
  • New KPIs / new charts. Same data, better presentation + IA.
  • New search functionality (audit only; implementation deferred).
  • Automation / bots.

9. Acceptance criteria

  1. All pages render with no console errors.
  2. Same data reaches each surface (snapshot KPIs before/after).
  3. /admin/metrics and /admin/reports redirect to /admin with existing deep-links not breaking (e.g., query params preserved).
  4. Attention Queue items are actionable (at least one action link per severity).
  5. Shell nav shows attention count badge on Dashboard when > 0.
  6. Export works on every page with exportable data.
  7. npx tsc --noEmit clean.
  8. Lighthouse accessibility score >= current on /admin.
  9. Visual consistency with Phase 1/2 (spot-check summary bar, MetricCard, SectionLabel usage).

10. Risk register

RiskMitigation
/admin/metrics or /admin/reports is linked from external docs / emails / SlackUse 301 redirects, preserve query params. Add a Telegram note to Brock post-deploy so he knows.
AdminAttentionQueue rename breaks external importsGrep repo before delete; keep deprecated re-export for one release if needed.
Attention badge count causes shell re-render stormsMemoize count query, refresh every 60s, not every focus.

11. Estimated size

  • New primitives (ChartFrame, AdminSummaryBar, AdminNextActionQueue): ~400 LOC
  • Page refactors (6 pages): ~500 LOC diff
  • Redirects + deletes: ~50 LOC
  • Total: ~1,300 LOC across ~15 files.
  • One Claude Code Opus 4.7 xhigh session with frontend-design skill, 1800s ACP timeout.

12. Success metrics (post-ship)

  • Brock opens /admin and can act on the top attention item in < 10 seconds.
  • No “which page should I use” moments.
  • Time to find “Top locations by MRR” < 3 clicks from any starting page.
  • All admin pages pass the “does this page earn its place in the IA?” test.