Flatten authenticated sidebar IA, move admin to the profile menu, right-align TopSearchBar actions, and replace placeholder dashboard panels with data from /api/user/stats and /api/user-cards. Co-authored-by: Cursor <cursoragent@cursor.com>
11 KiB
| name | classification | success_metric | skip | status | created | model_policy | |||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| dashboard-home-realignment | feature | A logged-in user opening /dashboard sees a flat product nav (Dashboard, My Collection, Lists, Decks, Scanner, then Cards + Community), stats sourced from /api/user/stats with no placeholder tiles, Recently added / My activity / last-card spotlight using that user's real data, the top-bar notifications + inbox + profile cluster flush-right, and Admin reachable only from the profile dropdown (not the left nav). |
|
in-progress | 2026-08-15 |
|
Convoy: dashboard-home-realignment
Make /dashboard an honest home for returning collectors, flatten
the sidebar to match the product we actually have, and fix top-bar
chrome (right-aligned actions + admin only in the profile menu).
Why
The redesign-v2-from-mockups epic shipped the visual shell (glass
sidebar, TopSearchBar, StatCard row, featured grid, activity panel,
spotlight rail). The screen still does not behave like a home:
- Sidebar IA is nested and mislabeled.
/dashboardhides under a "My Collection" parent; ownership (/my-cards) is a sub-item named "Cards"; Lists / Decks / Analytics nest underneath. The prototype's Wishlist / Trades / Market / Events items do not exist as product — adding them as "Coming soon" would be graveyard nav. - Dashboard stats sum list
cardCount/value(double-counts cards in multiple lists) and show dead Rare Cards / Wishlist Items tiles at0/ "Coming soon"./api/user/statsalready has ownership totals, value, decks, rarity breakdown, and recent adds — the page does not call it. - Featured Collection / Recent Activity / Card Spotlight mix real thumbnails with fake trades, fake market charts, and a demo Emberclaw Dragon. That trains people the home is marketing.
- TopSearchBar search uses
flex-1 max-w-2xl, so notifications, inbox, and profile sit mid-bar on wide viewports instead of flush-right. - Admins see Admin Tools in the left nav (
/admin/card-editor) and Admin Panel in the profile dropdown (/admin). Operator wants a single entry: the profile menu.
/my-cards stays a browse/manage page (not a second dashboard).
This convoy only promotes it in nav and aligns chrome.
Scope
In scope
- Flatten desktop + mobile nav. First-class: Dashboard
(
/dashboard), My Collection (/my-cards), Lists (/collections), Decks (/decks), Scanner (/scanner). Below a divider: Cards catalog (/cards), Community (existing collapse). Keep locked vocab (My Collection/Lists). Do not add Wishlist, Trades, Market, Events, Analytics, or a top-level Activity item. - Remove left-nav Admin Tools. Keep admin entry in
TopSearchBar<UserMenu>(already gated onuser.role === 'admin'). Architect picks one href (/adminvs/admin/card-editor) and applies it in the profile menu + any leftover mobile-drawer copy ofUserProfileDropdown. Do not resurrect admin inNavigationContent. - Right-align top-bar actions. Notifications, inbox, and
profile cluster flush to the right edge of
TopSearchBar. Search stays left / grows; leftover width aftermax-w-2xlmust not sit to the right of the cluster. Hide the notification badge when count is0(do not invent a fake3). - Honest dashboard stats. Fetch
/api/user/stats. Ship three real tiles: Total Cards (fromuser_cards, not list sums), Collection Value, and a third computable metric (This month / Lists / Decks — IA + Architect lock). Hide Rare Cards and Wishlist until those features exist. Usedelta/subtitleonly when the number is real. - Honest home panels. Rename Featured Collection → Recently
added (same 8-up + empty-slot CTAs, real
/api/user-cardsor stats recent rows). Wire Recent Activity to the signed-in user's adds (statsrecentActivityis an acceptable v1). Spotlight the last added / last scanned card with real metadata; hide price-trend, market-overview, and watchlist until a market-data convoy. - Home CTAs. Keep Scan / Create List only for empty or new collections, or drop the welcome header in favor of stats — UX locks this. Do not keep both a long greeting and two always-on buttons.
- Collection page chrome only. Same max-width / padding rhythm
as dashboard; optional one-line summary from stats. No second
stat row, no spotlight rail on
/my-cards.
Out of scope
- Wishlist / Trades / Market / Events product work (queued
follow-ups from
redesign-v2-from-mockups, still queued). - Daily Ember backend, Level / XP, federated ⌘K search.
- Renaming Lists → Binders.
- Real notification / inbox backends.
- Market-price history or a charting library.
- Redesigning
CardItem, scanner, or community pages. - Changing
/api/user/statsauth or adding new tables.
Roles invoked
role-ia-architect— lock the flat nav map (desktop + mobile), dashboard information hierarchy, and Collection-page-as-browse (not a second home).role-ux-reviewer— empty-state CTAs vs greeting, third stat tile, activity/spotlight honesty, top-bar alignment + badge rules.ui-designskipped: incremental inside Liquid Glass; no new visual language.role-architect— briefs for nav + admin relocation, TopSearchBar alignment, dashboard data wiring (reuse/api/user/stats, no new tables).role-implementer— per brief.- Audit fan-out after PR draft: reviewer + security-auditor + design-system-auditor + a11y-auditor.
role-doc-writer— AGENTS.md / Layout convention note if nav map changes.
Todos
- IA: publish the locked nav map and dashboard outline
- UX: lock greeting/CTA rule, third stat, badge-at-zero, spotlight contents
- Architect: split briefs (nav+admin, top-bar, dashboard data)
- Flatten
NavigationContent+MobileNavigation; drop left-nav Admin Tools - Right-align TopSearchBar action cluster; badge hidden at 0
- Dashboard consumes
/api/user/stats; hide placeholder tiles - Recently added / My activity / last-card spotlight use real user data
/my-cardspadding / max-width aligned with dashboard- Audits + docs pass
IA
Affected routes
[modified]/dashboard— honest home; stats from/api/user/stats[modified]/my-cards— summary line + shared max-width container[impacted]/collections,/collection/[id],/decks,/deck/*,/scanner,/cards,/community/*— nav active states only
User flow
flowchart LR
Login --> Dashboard
Dashboard --> MyCards["My Collection"]
Dashboard --> Scanner
Dashboard --> Lists
MyCards --> CardDetail["/card/:id"]
Screen inventory
| Screen | Path | Change | Notes |
|---|---|---|---|
| Dashboard home | /dashboard |
Modified | 3 stat tiles, recently added, activity, latest card |
| My Collection | /my-cards |
Modified | Browse surface; optional stats summary |
| Layout chrome | all auth pages | Modified | Flat nav; admin in profile menu only |
Content / data model deltas
- No schema changes. Reuse
GET /api/user/statsandGET /api/user-cards. user-cardsGET addsmarket_priceto SELECT for spotlight display.
Open IA questions
- None — third stat locked to Decks (
totalDecks).
UX
Decisions (locked)
- Empty vs returning home: Welcome + Scan/Browse CTAs only when stats load successfully and both
totalCards === 0and no recent cards. Returning users see stats row only (no greeting strip). - Stat row: Three tiles — Total cards, Collection value, Decks. No Rare/Wishlist placeholders.
- Panels: Featured → Recently added; activity from user's
recentActivity; spotlight shows latest owned card with real fields only (no demo charts). - Top bar: Notifications badge hidden at
0. Action cluster flush-right viaml-auto. - Admin: Single Admin Tools entry in profile dropdown (
/admin); removed from sidebar.
Architecture
File plan
| File | Action | Purpose |
|---|---|---|
components/Layout.js |
Modified | Flat nav; remove sidebar admin |
components/MobileNavigation.js |
Modified | Dashboard hub + Collection/Scanner/Decks |
components/ui/TopSearchBar.js |
Modified | Right-align actions; Admin Tools label |
pages/dashboard.js |
Modified | Wire /api/user/stats |
components/Dashboard*.js |
Modified | Real data panels |
pages/my-cards.js |
Modified | Container + summary |
lib/format-relative-time.js |
New | Activity timestamps |
pages/api/user-cards.js |
Modified | Include market_price in GET |
API surface
- No new routes. Consumers:
GET /api/user/stats,GET /api/user-cards(auth required).
Schema diff
- None.
Test plan
test/lib/format-relative-time.test.js(new)- Existing
Layout.test.js,StatCard.test.jsregression
Decomposition
| Brief # | Title | Files | Depends on |
|---|---|---|---|
| 1 | Flat nav + admin relocation | Layout, MobileNavigation, TopSearchBar | — |
| 2 | Honest dashboard home | dashboard.js, Dashboard*.js, format-relative-time | — |
| 3 | My Collection chrome | my-cards.js, user-cards API | — |
slice_dependencies:
- brief: 1
depends_on: []
files: [components/Layout.js, components/MobileNavigation.js, components/ui/TopSearchBar.js]
- brief: 2
depends_on: []
files: [pages/dashboard.js, components/DashboardFeaturedCollection.js, components/DashboardRecentActivity.js, components/DashboardCardSpotlight.js, lib/format-relative-time.js]
- brief: 3
depends_on: []
files: [pages/my-cards.js, pages/api/user-cards.js]
Audits (2026-08-15)
- Reviewer: No blockers after fixes (stats empty-state gate, divider, Lists active on
/collection/*, vocab, admin label). - Security: No medium+ findings; auth boundaries unchanged.
- Design-system / a11y: Incremental Liquid Glass; nav items retain focus rings; activity list uses semantic text.
Doc note
Authenticated sidebar nav (2026-08-15): Dashboard → My Collection → Lists → Decks → Scanner; divider; Cards catalog + Community. Admin only in TopSearchBar profile menu.