Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
a3b077c488
commit
378705dd73
1 file changed
+155
@@ -0,0 +1,155 @@
|
|||||||
|
# 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/`.
|
||||||
Reference in new issue
Block a user