Files
EpicNext-Cms/docs/superpowers/specs/2026-07-17-admin-ux-cleanup-design.md
T
SimoandCursor 378705dd73
Local Build and Deploy / deploy (push) Successful in 55s
Add admin UX cleanup Phase 1 design spec.
Co-authored-by: Cursor <[email protected]>
2026-07-17 17:53:15 +02:00

156 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Admin UX Cleanup — Design Spec
**Date:** 2026-07-17
**Status:** Approved in chat (Phase 1); Phases 2–3 queued after Phase 1 ships
**Scope:** Admin panel (`/admin/*`) — EpicNext-cms
## Context
The admin already has hub chrome (`AdminHubChrome` + `AdminPageShell` + `AdminSectionTabs`), a condensed sidebar, theme/language switchers, and ACL. Remaining pain is inconsistency: double headers, orphan routes, duplicated chrome controls, crowded Radio tabs, and identical icons for Access vs Moderation.
This document covers a **three-phase** program. **Only Phase 1 is in scope for the next implementation plan.**
---
## Goals
1. One clear page hierarchy under each hub (no stacked titles).
2. Every useful admin route reachable from hub tabs (no orphan pages).
3. Theme/language controls in one primary place (no desktop duplicate).
4. Radio hub usable on smaller widths without losing URLs.
5. Access vs Moderation visually distinct in the sidebar.
## Non-goals (Phase 1)
- Full admin i18n (Phase 2).
- Full design-token / shadcn unification (Phase 3).
- New features, new pages, or permission model changes.
- Changing public-site chrome or avatar/imager behavior.
---
## Phase 1 — UX cleanup
### 1.1 Single hub header
**Current:** `AdminHubChrome` renders hub `title` + `subtitle` + tabs; many child pages also render `h1` / intro copy (often `text-3xl font-bold`), producing double titles.
**Rule:**
| Page type | Hub shell title | Page-level `h1` |
|-----------|-----------------|-----------------|
| Hub list / overview (matches a hub tab) | Keep | Remove (or demote to section heading if needed for a11y only when content blocks require it) |
| Nested create / edit / show (`…/new`, `…/[id]`, `…/create`, `…/show/[id]`) | Keep hub title | Keep entity-specific title (e.g. poll name, “Create Event”) |
| Dashboard `/admin` (no hub) | N/A | Keep its own header |
**Implementation approach:**
- Prefer removing redundant page chrome blocks (icon + `h1` + muted description that duplicates hub subtitle).
- Keep action rows (Create buttons, filters, search) that sit next to the old `h1`; restructure to a toolbar without a second page title.
- Do not strip semantic headings inside content cards/tables.
**Acceptance:** Opening any hub tab shows exactly one primary title (from `AdminPageShell`). Detail pages still show the entity/create title below the hub chrome.
### 1.2 Wire orphan routes into hub tabs
Add tabs (English labels for Phase 1; i18n keys in Phase 2):
| Hub | New / adjusted tabs | Hrefs |
|-----|---------------------|-------|
| **Users** | Multi-accounts | `/admin/users/multi-accounts` |
| **Engagement** | Event types, Templates | `/admin/events/types`, `/admin/tickets/templates` |
| **Observability** | Chat, Commands, Trades | `/admin/logs/chat`, `/admin/logs/commands`, `/admin/logs/trades` |
| **Observability** | Activity, Economy (under analytics) | `/admin/analytics/activity`, `/admin/analytics/economy` |
| **Observability** | Errors (under devops) | `/admin/devops/errors` |
**Tab matching notes:**
- Users “Directory” must keep `match` that includes `/admin/users` but **not** steal active state from `/admin/users/multi-accounts` (exact / longest-prefix matching already in `AdminSectionTabs` — verify Directory `match` does not list multi-accounts; multi-accounts gets its own tab with `href` only or explicit `match`).
- Logs “Logs” tab (`/admin/logs`) must not stay active on `/admin/logs/chat` etc. Prefer exact match for the main Logs index, or give sub-log tabs longer prefixes so they win (existing scorer prefers longer / exact — verify).
- Analytics “Analytics” vs Activity/Economy: same longest-match rule.
- Engagement Event types: `/admin/events/types` must win over Events `match: ["/admin/events"]` — longest prefix already favors `/admin/events/types` if that tab is listed.
**Acceptance:** Every orphan page above is one click from its hub tab strip. No new routes required.
### 1.3 Theme / language control placement
**Decision:** Primary controls stay in the **sidebar** (desktop). **Topbar** keeps theme + language only on **mobile** (when the sidebar is not persistently visible), or remove from topbar entirely if `AdminMobileWrapper` already exposes sidebar controls on mobile.
**Preferred behavior:**
- Desktop (`lg+`): switchers **only in sidebar** header row; remove from `Topbar`.
- Mobile: switchers remain reachable via the mobile sidebar drawer (already present). If the drawer is hard to discover, keep a compact pair in the topbar **only below `lg`**.
**Acceptance:** On desktop, theme/language appear once. Mobile users can still change theme and locale without hunting.
### 1.4 Radio hub tab grouping
URLs unchanged. UI presents two rows (or a primary row + overflow “More” row):
**Primary:** Overview, History, Moderation, Monitoring, Settings
**Tools:** Banners, Embed, API keys, Points, Ranks, Auto DJ
**Implementation options (pick one in plan):**
- **A (recommended):** Extend `AdminSectionTabs` / hub definition with optional `group?: "primary" | "tools"` and render two labeled rows for Radio only.
- **B:** Nested “Tools” dropdown tab — less discoverable; avoid unless row A overflows badly.
**Acceptance:** Radio remains fully linked; primary ops are visible without horizontal scroll on a typical laptop width (~1280px).
### 1.5 Distinct Access vs Moderation icons
- **Access & security** sidebar: keep `Ban` (or `Shield`) — already distinct from Users.
- **Moderation** sidebar: change from `Shield` to something like `Gavel` or `ShieldAlert` so it does not match Access.
Hub definition icons for Access vs Moderation should also differ if both appear in chrome.
**Acceptance:** Sidebar icons for Access and Moderation are not the same glyph.
---
## Phase 2 — Admin i18n (queued)
- Move hub `title` / `subtitle` / tab `label` to `labelKey` + `pages.admin.hubs.*` (and tab keys).
- Translate high-traffic pages: Users, Events, Logs, Settings, Moderation.
- i18n theme switcher aria/title strings for `variant="admin"`.
- Do not block Phase 1 on this; Phase 1 may leave English hub strings as today.
## Phase 3 — Design system (queued)
- Standardize list pages on `--admin-*` tokens (`admin-card`, shared empty state, table chrome).
- Optional shared `AdminListToolbar` for actions formerly next to removed `h1`s.
- Gradual migration; no big-bang rewrite of catalog/user detail.
---
## Risks & mitigations
| Risk | Mitigation |
|------|------------|
| Removing `h1` hurts accessibility | Hub shell already exposes one `h1`; detail pages keep entity `h1`. Spot-check with one screen reader pass on Users + Events. |
| Tab active-state regressions | Add/adjust `match` arrays; manually verify Directory vs Multi-accounts, Logs vs Chat. |
| Radio two-row tabs feel heavy | Only Radio uses groups; other hubs stay single row. |
| Mobile loses theme/lang | Keep switchers in sidebar drawer; optional `lg:hidden` topbar pair. |
## Out of scope leftovers
- Calendar under Shop hub (IA smell) — defer unless requested.
- Legacy user route folder split (`show/[id]` vs `[id]`) — defer.
- Avatar `/imaging` proxy — separate track.
## Success criteria (Phase 1)
1. No double hub+page title on representative pages: Articles, Users directory, Events list, Logs index, Radio overview.
2. Orphan routes listed above reachable from tabs.
3. Desktop: single theme/language control location.
4. Radio primary tabs visible without scrolling on 1280px width.
5. Moderation and Access icons differ.
---
## Approval
- Phase 1 approach approved in conversation (2026-07-17).
- Implementation proceeds via a Phase-1 plan under `docs/superpowers/plans/`.