3.5 KiB
3.5 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | |||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| quick | 260411-1h2 | client/routes |
|
|
|
|
|
|
Quick 260411-1h2: Rebuild Global Items Page with Sticky Toolbar Summary
One-liner: Rebuilt global items page with sticky two-row toolbar (search + view toggle + inline tag/weight/price filter popovers), grid/list view toggle using GlobalItemCard and Link-based list rows.
Tasks Completed
| Task | Name | Commit | Files |
|---|---|---|---|
| 1 | Rebuild global items page with sticky toolbar, filters, and dual view | ee3b6f7 |
src/client/routes/global-items/index.tsx |
What Was Built
src/client/routes/global-items/index.tsx was completely rewritten from a simple 94-line grid-only page to a 640+ line full-featured catalog browsing page:
Sticky toolbar (sticky top-14 z-[5]) with two rows:
- Row 1: Back link to Discover, centered search input with clear (X) button, grid/list view toggle
- Row 2 (conditional): Tags, Weight, Price filter pills — only shown when tags exist or any filter is active
Filter popovers:
- Tags: dropdown listing all tags from
useTags()— click to toggle, active tags highlighted blue, count badge on pill - Weight: min/max range sliders (0–5000g, 50g steps) in a compact card popover
- Price: min/max range sliders (0–100000 cents, 500 cent steps) in a compact card popover
- All popovers close on click-outside via
useRef+mousedownevent listener - Only one popover open at a time (opening one closes others)
Active filter pills:
- Selected tag names shown as removable blue pills
- Active weight/price range bounds shown as removable pills
- "Clear all" button clears all filters at once
Results area:
- Grid view:
GlobalItemCard(existing component, untouched) - List view:
GlobalItemListRow(inline component, uses<Link>for navigation, no Add button) - Loading:
SkeletonGrid/SkeletonList(6-item animate-pulse layouts) - Empty: contextual message based on whether query/filters are active
Data flow:
searchInputdebounced 300ms todebouncedQuery→ passed touseGlobalItems()selectedTagspassed touseGlobalItems()for server-side tag filtering- Weight/price filters applied client-side via
useMemo - Search input pre-filled from
?q=URL param on mount
Deviations from Plan
None — plan executed exactly as written.
Known Stubs
None — all functionality is wired to real data hooks.
Self-Check
src/client/routes/global-items/index.tsxexists and is 640+ lines- Commit
ee3b6f7exists bun run lintpasses with no errorscreateFileRoute("/global-items/")preservedvalidateSearchwithz.object({ q: z.string().optional().catch(undefined) })preservedCatalogSearchOverlay.tsxuntouchedGlobalItemCard.tsxuntouched