PageSourceSearch

https://joshcohen.ai/assets/2026-05-06-dashboard-redesign-ukFYKhMX.js

js joshcohen.ai collected 2026-10-05 13:40:33 UTC 12,886 bytes, 256 lines download raw bytes

1const e=`# Dashboard redesign — single-shell v3, sidebar-only nav, deduped surface
2
3**Branch:** \`claude/2026-05-06-0422/dashboard-redesign\`
4**Status:** in-progress · 2026-05-06
5**Owner:** Claude (autonomous)
6**Approved decisions** (from cards on 2026-05-05 night):
71. Primary nav = sidebar-only + minimal top bar
82. Drop Work / Inbox top-nav items
93. v3 becomes the only shell — archive v1 + v2
104. Background tests = Playwright local watcher
11
12---
13
14## Why this exists
15
16User report on 2026-05-05:
17
18> "Currently the dashboard has two menu bars. One with Dashboard, Community,
19> Work, Inbox, Billing, Settings. And then another one /dashboard/overview
20> that says Overview, Orders, Messages, Library, Engagement, Support. This
21> is very confusing. There's a side that has a duplicate menu. This dashboard
22> is very ugly."
23
24Verified: the triple-nav stack is **v3-only**. v1 has sidebar only, v2 has top + sidebar. v3 has top + sidebar + a horizontal middle tab bar (\`CategoryTabBarLight\`) that re-renders the sidebar's currently-active group as tabs. That's the literal duplicate the user is seeing.
25
26Plus three top-nav items create ambiguity:
27
28- **Work** → \`/account/orders\` — duped with sidebar "Orders"
29- **Inbox** → \`/account/messages\` — duped with sidebar "Messages"
30- **Community** → \`/community/feed\` — route exists but reportedly non-functional
31
32---
33
34## End state
35
36When this lands on \`v5\`, the dashboard:
37
381. Has **one** primary navigation surface — the left sidebar.
392. Has a minimal top bar: brand · breadcrumb · search · notifications · user menu.
403. Has no horizontal middle tab bar.
414. Has 4 top-bar section pills (admin only sees 5): Dashboard · Community · Admin · Settings.
425. Renders the same way for every user — v1 and v2 shells are archived.
436. Has a Playwright suite that exercises every dashboard route + every primary CTA on file save and refuses to commit when something console-errors.
44
45---
46
47## Scope (4 phases, in order)
48
49### Phase 1 — Surgical de-dup (this PR)
50
51The fixes that directly address the user complaints. Lowest risk. No visual rewrite yet.
52
53- [ ] **Drop \`CategoryTabBarLight\`** from \`AppShell\`. The horizontal tab bar that duplicates the sidebar group is gone. Users navigate via sidebar only.
54- [ ] **Rebuild top nav as minimal**. \`TOP_NAV_ITEMS\` shrinks to: Dashboard, Community, Admin (admin only), Settings. "Work" and "Inbox" removed. Resolver in \`topNavItems.js\` updated; v1 + v2 shells will pick this up too while they exist.
55- [ ] **Audit \`/community/feed\`**. Open it, capture console + network errors. If broken from a missing edge function or DB row, fix or stub the page so it renders an honest empty state.
56- [ ] **Set up Playwright local watcher**. \`npm run test:dashboard\` opens watch mode against \`localhost:5173\` and runs \`tests/dashboard.spec.ts\` covering: every sidebar route renders, no console errors, Generate-now buttons fire, theme toggle works light + dark, admin pages load.
57- [ ] **Smoke test light + dark + mobile** in the preview server. Capture before/after.
58
59### Phase 2 — Visual modernization (next PR)
60
61Reference patterns: Linear (sidebar density), Vercel (top-bar minimalism), Stripe (card spacing), Plausible (typography scale), Notion (collapsible groups).
62
63- [ ] New shell tokens. Tighter spacing, larger typography scale, accent color refinement, soft shadows for cards.
64- [ ] Sidebar visual refresh. Pinned section header, collapsible groups, search at the top, badge-count chips beside items, current page indicator as a left bar (already there) refined.
65- [ ] Top bar visual refresh. Logo · breadcrumb · global search · notifications bell · theme toggle · user menu. ~48px tall instead of 64px.
66- [ ] Page chrome. Standard \`PageHeader\` component with title + actions row, used by every admin page.
67- [ ] Empty-state and loading-state components shared across the dashboard.
68
69### Phase 3 — Archive v1 + v2
70
71- [ ] Move \`src/pages/account/Layout.jsx\`, \`src/components/shell/\`, and \`src/components/shell-v3/\` (rename to \`src/components/shell/\`) accordingly. v1 and v2 → \`archived_code/\` per the project's archive policy.
72- [ ] Delete \`site_settings.layout_template\` switching. Redirect \`getSetting('layout_template', ...)\` to always return \`'v3'\` for one release, then remove the call sites.
73- [ ] Drop the v1 \`Try Light Dashboard\` / v2 \`Switch to Classic\` buttons.
74- [ ] Update STATE.md to remove the "three sidebar configs" gotcha.
75
76### Phase 4 — Background test runner — production tier
77
78- [ ] GitHub Action \`dashboard-health\` runs the same Playwright suite hourly against \`joshuacohen-dev.pages.dev\`, writes a row into a new \`dashboard_health_checks\` table, pings the admin email on failure.
79- [ ] \`/account/admin/development/blog\` gains a "Health" widget reading the latest run status.
80
81---
82
83## Admin dashboard — full breakdown (as of 2026-05-05)
84
85### Top-level shell wrappers
86
87| Shell | File | What it renders | Dark mode |
88|---|---|---|---|
89| v1 (Classic) | \`src/pages/account/Layout.jsx\` | Sidebar only (no top bar) | light only |
90| v2 | \`src/components/shell/DashboardShell.jsx\` | TopNav + Sidebar + Breadcrumb | dark only |
91| v3 (Light, current default) | \`src/components/shell-v3/AppShell.jsx\` | TopNav + Sidebar + Breadcrumb + **CategoryTabBar** ← dup | light + dark (as of 2026-05-05) |
92
93\`src/pages/account/index.jsx:109\` resolves which shell to render from \`site_settings.layout_template\`. After Phase 3 only v3 stays.
94
95### Top nav (current)
96
97\`src/components/shell/config/topNavItems.js\`
98
99| Id | Label | Path | Issue |
100|---|---|---|---|
101| dashboard | Dashboard | \`/account\` | ok |
102| community | Community | \`/community/feed\` | route exists, page reportedly broken |
103| **work** | Work | \`/account/orders\` | **duped with sidebar Orders** |
104| **inbox** | Inbox | \`/account/messages\` | **duped with sidebar Messages** |
105| billing | Billing | \`/account/billing\` | ok |
106| settings | Settings | \`/account/settings\` | ok |
107
108After Phase 1: Dashboard · Community · Admin (admin only) · Settings.
109
110### Sidebar groups (v3)
111
112\`src/components/shell-v3/config/sidebarGroupsV3.js\`
113
114| Group | Items | Items count |
115|---|---|---|
116| ACCOUNT | Overview, Orders, Messages | 3 |
117| LIBRARY | Downloads, My Products, Wishlist | 3 |
118| ENGAGEMENT | Reviews, Rewards, Referrals, Membership | 4 |
119| SUPPORT | Addresses, Alerts, Activity, Support | 4 |
120| COMMUNITY | (links to /community portal) | 7 |
121| PARTNER (NDA holders) | NDA, Ventures | 2 |
122| ADMIN (admin only) | Build · Commerce · Content · CMS · Community Mgmt · Settings · Development | **34** |
123
124Total non-admin: 23 items. Admin: 34 items. The depth justifies a sidebar over horizontal tabs.
125
126### Admin section breakdown (the 34)
127
128**Build:** Roadmap
129
130**Commerce (10):** Leads, Users, Activity, All Orders, Shop, Cart Experience, NDA Queue, Partner Directory, Newsletters, Reviews, Shop Identity, LLM Keys, Tenants
131
132**Content (5):** Landing Pages, Images, Scripts, Analytics, SEO Overrides
133
134**CMS (4):** Navigation, Testimonials, Page Content, Chatbot Widget
135
136**Community Mgmt (6):** Channels, Posts (Mod), Members, Courses, Events, Levels
137
138**Settings (2):** Layout Templates, Dashboard Defaults
139
140**Development (2):** Development, Dev Blog
141
142Redundancies inside admin to flag for Phase 2:
143- "Layout Templates" + "Dashboard Defaults" + the Appearance settings tab. Three places to control look-and-feel. Phase 2 collapses into one.
144- "Activity" (admin) vs "Activity" (user dashboard). Both exist; need a rename pass.
145- "Reviews" (admin) is fine; user-facing "Reviews" lives in Engagement group.
146
147---
148
149## Modernization research — sources + patterns adopted
150
151| Pattern | Source | Adopt where |
152|---|---|---|
153| Sidebar-only primary nav, ~16px row height, collapsible groups | Linear, Notion | Sidebar refresh in Phase 2 |
154| Minimal top bar (logo + search + bell + avatar) | Vercel, Stripe Dashboard | TopNav rewrite in Phase 1 |
155| Cmd-K command palette for jump-to-anywhere | Linear, Vercel, Raycast | Phase 2, optional |
156| Card with subtle shadow + 1px border + 16px radius | Stripe, Plausible | Phase 2 |
157| Inter / SF for body, larger weight scale (400 / 500 / 600) | Stripe, Vercel | Phase 2 |
158| Sticky page header with title + breadcrumb + actions | Vercel | Phase 2 (\`PageHeader\` component) |
159| Single accent color (purple already) used sparingly | Stripe | (already mostly true) |
160| Dark mode tokens that aren't pure black | Linear (#0F1117), GitHub (#0D1117) | (already done — \`#0B0E14\` in DARK_THEME) |
161
162Not adopting:
163- Linear's heavy keyboard-first ethos. The dashboard is operator-managed, not developer-facing — keyboard shortcuts come later.
164- Notion-style command palette inside every block. Overkill.
165- Vercel's project-tab pattern. The admin tree is too deep — would explode into 7+ secondary tabs per section.
166
167---
168
169## Phase 1 — concrete implementation steps
170
171### 1.1 Remove \`CategoryTabBarLight\` from \`AppShell\`
172
173\`src/components/shell-v3/AppShell.jsx:122\`
174
175\`\`\`diff
176- {/* Category tab bar — horizontal tabs for current section */}
177- <CategoryTabBarLight />
178-
179  {/* Page content */}
180\`\`\`
181
182Move \`CategoryTabBarLight.jsx\` to \`archived_code/CategoryTabBarLight_2026-05-06.jsx\` per the archive policy.
183
184### 1.2 Rebuild \`TOP_NAV_ITEMS\`
185
186\`src/components/shell/config/topNavItems.js\`
187
188\`\`\`js
189export const TOP_NAV_ITEMS = [
190  { id: 'dashboard', label: 'Dashboard', path: '/account',           matchPrefix: '/account',           icon: Fi.FiLayout },
191  { id: 'community', label: 'Community', path: '/community/feed',    matchPrefix: '/community',         icon: Fi.FiUsers },
192  { id: 'admin',     label: 'Admin',     path: '/account/admin',     matchPrefix: '/account/admin',     icon: Fi.FiShield, adminOnly: true },
193  { id: 'settings',  label: 'Settings',  path: '/account/settings',  matchPrefix: '/account/settings',  icon: Fi.FiSettings },
194];
195\`\`\`
196
197Update \`resolveActiveTopNav\` so \`/account/admin/*\` resolves to \`admin\`, not \`dashboard\`. v1 + v2 shells pick this up automatically — they share the same config.
198
199### 1.3 \`/community/feed\` audit
200
201Visit \`localhost:5173/community/feed\` while signed in. Capture:
202- console errors
203- network requests that 4xx/5xx
204- the page text (does it render or stay blank?)
205
206Likely culprits:
207- \`community_posts\` table RLS blocking reads (just shipped RLS on 2026-05-05, may have over-blocked)
208- A required edge function not deployed
209- A DB row missing for a default channel
210
211Fix or stub. The bar: page renders, even if empty, with a clear empty-state CTA.
212
213### 1.4 Playwright watcher setup
214
215\`\`\`
216tests/
217  dashboard.spec.ts        ← suite
218  helpers/auth.ts          ← log in as admin via supabase auth API
219  fixtures/                ← test users + reset hooks
220playwright.config.ts
221package.json
222  "test:dashboard": "playwright test --ui",
223  "test:dashboard:run": "playwright test"
224\`\`\`
225
226Suite covers (target ≤ 60s wall clock):
227
2281. **Routes render**: every sidebar route, both light + dark, no console errors.
2292. **Theme toggle**: clicking Switch-to-X-mode in the user menu flips \`<html>.dark\`.
2303. **Sidebar group collapse / expand** — state persists.
2314. **Admin guard**: a non-admin user navigated to \`/account/admin/*\` redirects.
2325. **Generate Now button** on \`/account/admin/development/blog\` calls the edge function and a row appears in \`dev_blog_posts\` (or shows the operator empty state).
2336. **/community/feed** loads without console error.
234
235### 1.5 Smoke + push
236
237\`npm run lint:error\` clean → preview verify → commit per phase → push to \`claude/2026-05-06-0422/dashboard-redesign\`. Open a PR (or merge into \`dev\`) so it deploys to \`joshuacohen-dev.pages.dev\` for review. Do **not** merge to \`v5\` until approval.
238
239---
240
241## Risks + mitigations
242
243| Risk | Mitigation |
244|---|---|
245| Removing top-nav items breaks deep links (e.g., bookmarked /account/orders via Work tab) | Routes still exist. Only the top-bar pill changes. /account/orders still works via the sidebar. |
246| Dropping CategoryTabBarLight breaks layout if any page positioning depended on it | The bar lives in \`AppShell\`, not pages. No page references it. Verified via grep. |
247| /community/feed audit reveals a deeper bug than a stubbable empty state | Phase 1 ships the de-dup; the feed audit becomes its own follow-up. |
248| Playwright suite flaky on slow CI | Local-only this PR. CI tier is Phase 4. |
249| User dislikes the new minimal top bar after seeing it deployed | This is why we deploy to \`joshuacohen-dev.pages.dev\` first and wait for explicit "ship to v5" approval. |
250
251---
252
253## Approval gate
254
255Phase 1 lands on \`claude/2026-05-06-0422/dashboard-redesign\` → merged into \`dev\` → deploys to \`joshuacohen-dev.pages.dev\`. User reviews live, approves, and only then a separate merge takes it to \`v5\`.
256`;export{e as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.