Files

3.5 KiB
Raw Permalink Blame History

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
global-items
filters
search
ui
sticky-toolbar
requires provides affects
rebuilt-global-items-page
src/client/routes/global-items/index.tsx
added patterns
inline-filter-popovers
click-outside-useref
debounced-search
client-side-range-filter
created modified
src/client/routes/global-items/index.tsx
Inline popovers (not sidebar) for tag/weight/price filters — matches plan spec, avoids layout shift
click-outside via useRef + mousedown listener (3 refs) — no framer-motion needed
GlobalItemListRow defined in same file — no new component file needed
duration completed tasks_completed files_modified
~15 minutes 2026-04-10T23:13:02Z 1 1

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 (05000g, 50g steps) in a compact card popover
  • Price: min/max range sliders (0100000 cents, 500 cent steps) in a compact card popover
  • All popovers close on click-outside via useRef + mousedown event 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:

  • searchInput debounced 300ms to debouncedQuery → passed to useGlobalItems()
  • selectedTags passed to useGlobalItems() 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.tsx exists and is 640+ lines
  • Commit ee3b6f7 exists
  • bun run lint passes with no errors
  • createFileRoute("/global-items/") preserved
  • validateSearch with z.object({ q: z.string().optional().catch(undefined) }) preserved
  • CatalogSearchOverlay.tsx untouched
  • GlobalItemCard.tsx untouched

Self-Check: PASSED