Admin dashboard restructure — audit
Source of truth: ~/joyos-labs/src/views/AdminView.vue (8,033 LOC).
Last touched 2026-05-14 to add the Founding-Member badge grant UI.
1. Current state — inventory
Every tab declared in AdminView.vue:48, in source order:
| # | Label | Slug | Purpose | Complexity | Recent activity |
|---|---|---|---|---|---|
| 1 | Overview | members | 4-stat-card summary (total users + per-tier counts). PWA-install metrics loaded here too. | Tiny | Stable |
| 2 | Feedback | feedback | Feedback inbox + the AI daemon status bar, agent config modal, deploy banner, feedback-detail editing. | Huge (~2,000 LOC) | Active — last touch 2026-05 |
| 3 | Invites | invites | Magic-link invite list + bulk-grant tier UI. | Medium | Stable |
| 4 | Stripe | stripe | Three internal sub-tabs: Products / Agent / History. The only tab with its own nested navigation. | Large | Active |
| 5 | Members | users | Search + filter the users table; inline tier edit; impersonation; badge grant. | Large (~1,500 LOC) | Active — 2026-05-14 badge grant |
| 6 | Flags | flags | Feature-flag CRUD. Most flag editing happens via the per-nav-item cog now, so this is read-mostly. | Medium | Stable |
| 7 | Events | events | Events table (founding-member hub call, etc.). | Small | New (2026-05-13) |
| 8 | Pairs | pairs | Connection-Pair matching admin (legacy feature). | Medium | Cold |
| 9 | Trials | trials | Active trial sessions + grant-trial form. | Medium | Stable |
| 10 | Backups | backups | Backup status display. | Tiny | Stable |
| 11 | Tiers | tiers | Tier-display configuration. Overlaps heavily with Stripe products. | Small | Cold |
| 12 | Notes | notes | Markdown admin notes (built-in + user-created). Effectively a wiki page. | Medium | Active |
| 13 | Media | media | R2 / MinIO media library. | Medium | Stable |
| 14 | Experiments | experiments | Experiment editor (Space Audit etc.) — also has its own route /app/admin/experiments. | Large | Active |
| 15 | Integrations | integrations | External integration config (Airtable, Resend, etc.). | Medium | Stable |
| 16 | Previews | previews | PR preview environments list — redirects from /app/admin/previews. | Small | Stable |
Plus the standalone admin routes: /app/admin/tour, /app/admin/experiments[/:slug], /app/admin/storage-settings — discoverable today only by typing the URL.
2. Problems
Overcrowded primary nav
- 16 top-level tabs on a single horizontal strip is well past Miller's law (~7 ± 2). The strip already scrolls and the active-tab auto-centering logic in
AdminView.vue:115is a band-aid for the deeper IA problem. - Stripe needed its own internal tab strip — proof that a flat strip can't carry the load.
Redundant / overlapping concerns
- Overview / Members / Invites are three views of the same noun (users): counts, list, pending invites. They should be one People surface with three views, not three top-level destinations.
- Stripe / Tiers both touch monetization config. Tiers is essentially "what we sell"; Stripe is "how we charge for it" — collapse into Billing.
- Trials / Invites / Tiers are all grant-something-to-a-user flows. Today they live in three different tabs; user has to remember which.
Misnamed labels
- The tab labeled Overview has slug
members; the tab labeled Members has slugusers. The disconnect bites every time you read URL state.
Hidden admin surfaces
AdminTourEditor,AdminStorageSettingsexist as routes but are not in the tab strip — only reachable by direct URL or buried links.
Mobile
- 16-item horizontal scroll on a 375px phone is a guessing game. No section labels, no overflow menu, no search.
Dashboard ≠ admin distinction is muddied
- Per
feedback_dashboard_central_hub_philosophy:/appis the member-facing hub./app/adminshould be operator surface only — but Notes (a wiki) and Backups (read-only status) blur the line.
3. Principles applied to the restructure
- One noun per surface. If two tabs operate on the same noun (users, money, content), they collapse into one surface with sub-views.
- Frequency drives placement. The two tabs Kristin actually opens daily — Feedback and Members — get pole position. Tabs that haven't been touched in 30+ days get demoted.
- ≤ 7 top-level destinations. Anything beyond that nests one level deeper, behind a label that names the workflow.
- Workflow-first labels. "Grant a trial" is what an admin does; "Trials" is what the data is called. Labels should describe verbs where reasonable.
- Survives mobile. The structure must work in a vertical drawer, not just a horizontal strip.
- Search as escape hatch. When IA can't be perfect, ⌘K should reach any admin surface in two keystrokes.
4. Proposals
Three distinct restructures, varying along the axes of hierarchy, discovery mechanism, and mental model:
Proposal 1 — Grouped sidebar (4 collapsible sections)
"Stripe Dashboard for admin." Tabs become a left sub-nav, organized into 4 groups by domain. Familiar pattern, biggest visual change, lowest cognitive change.
Pros
16→4 top-level groups. Familiar SaaS pattern. Surfaces previously-hidden admin routes. Mobile-friendly (sections collapse cleanly).Cons
Two clicks to reach anything. Doesn't address the "I want to grant trial X for user Y" cross-tab workflow.Risks
Grouping is opinionated — Notes could equally belong in Operations. Easy to argue forever.Proposal 2 — Command palette + recents
The 16 tabs collapse to one surface called "All admin." ⌘K reaches anything in two keystrokes; a left-rail of recents covers the 80% case.
Pros
Future-proof (17th tab is free). Two keystrokes beats two clicks for power users. Recents = de-facto frequency-based nav without curation. Verb-search is the killer feature.Cons
Discovery via search means new admins need onboarding. No visual hierarchy = no domain landmarks. Requires building a real palette component.Risks
Kristin doesn't share Ethan's keyboard-first reflex; she may bounce off the empty-state palette.Proposal 3 — Role-based home cards
The admin landing is three role cards — Member success, Money & growth, Build & operate — each showing live counts and the 2-3 actions that role actually performs. Existing tabs survive as drill-downs.
Pros
Landing answers "what needs my attention right now?" not "where do I click?" — strongest fit with the dashboard-central-hub philosophy. Surfaces underused tabs by showing live counters. Same nav structure, new entry point.Cons
Requires live data fetches on the admin landing. Role boundaries blur (whose job is the failed webhook?). Existing tab strip likely still needed as a fallback.Risks
"Role" doesn't map cleanly when there are only 2 admins. May feel like extra ceremony for someone who knows exactly what tab they want.5. Recommendation
The least-risky path is Proposal 1 (grouped sidebar) — it preserves every existing surface, demotes nothing destructively, and matches a pattern Kristin sees daily in Stripe / GitHub / Linear.
The highest-leverage path is Proposal 3 (role cards) — it directly addresses the dashboard-as-hub philosophy Ethan reinforced last week, and replaces "did I check the right tab?" with "what needs me right now?"
A reasonable ship sequence is Proposal 1 first (a structural cleanup that ships in days), then Proposal 3's role-card landing added on top as a richer admin home that drills into the new grouped sidebar.
Reply with which direction resonates and I'll cut a real PR.