feat(store): marketplace browse UX — search/filter, gallery, related products, featured #25

Open
yuris wants to merge 2 commits from feat/store-marketplace into main
Owner

Implements the store browse/discovery issues, plus a build-blocker fix. Static-export safe, WhatsApp-only, no catalog-contract change.

Features

  • #21 Client-side product search + type filter on /products (new ProductBrowser).
  • #22 Product image gallery with thumbnail strip on the detail page (new ProductGallery).
  • #24 Related same-type products on the detail page (excludes self; hidden when no siblings).
  • #23 Featured products section on the homepage (first-N heuristic, ponytail: flagged).
  • Shared ProductCard component (apps/store/app/products/product-card.tsx) used by list, browser, home, and related.
  • Gallery thumbnail styles added to globals.css.

Build fix

  • Restore export const dynamic = "force-static" on robots.ts and sitemap.ts. PR #19 removed these; under Next 16.2.10 output: export that broke next build at /robots.txt (pre-existing regression on main, unrelated to the features).

Verification

  • pnpm --filter garage-store exec tsc --noEmit — clean.
  • pnpm --filter garage-store lint (biome) — clean (5 pre-existing <img>/specificity baseline warnings).
  • pnpm --filter garage-store build (output: export) — succeeds; generates /, /products, /products/[slug], /robots.txt, /sitemap.xml.
  • Feature paths exercised against a temporary local catalog (multi-image + two same-type items, since the local catalog is otherwise empty — see #13): gallery thumbs render for multi-image products and are absent for single-image; related renders for a product with a same-type sibling, excludes itself, and is absent for a type with no sibling; featured grid renders on home. Temp rows rolled back after.

Provenance

Built in parallel via three opus workers in isolated git worktrees (feat/store-search, feat/store-featured, feat/store-detail), then reconciled here onto one branch (all three had independently modified products/page.tsx and two created rival card components; unified to one kebab-case product-card.tsx).

Closes #21
Closes #22
Closes #23
Closes #24

Implements the store browse/discovery issues, plus a build-blocker fix. Static-export safe, WhatsApp-only, no catalog-contract change. ## Features - **#21** Client-side product search + type filter on `/products` (new `ProductBrowser`). - **#22** Product image gallery with thumbnail strip on the detail page (new `ProductGallery`). - **#24** Related same-type products on the detail page (excludes self; hidden when no siblings). - **#23** Featured products section on the homepage (first-N heuristic, `ponytail:` flagged). - Shared `ProductCard` component (`apps/store/app/products/product-card.tsx`) used by list, browser, home, and related. - Gallery thumbnail styles added to `globals.css`. ## Build fix - Restore `export const dynamic = "force-static"` on `robots.ts` and `sitemap.ts`. PR #19 removed these; under Next 16.2.10 `output: export` that broke `next build` at `/robots.txt` (pre-existing regression on `main`, unrelated to the features). ## Verification - `pnpm --filter garage-store exec tsc --noEmit` — clean. - `pnpm --filter garage-store lint` (biome) — clean (5 pre-existing `<img>`/specificity baseline warnings). - `pnpm --filter garage-store build` (`output: export`) — succeeds; generates `/`, `/products`, `/products/[slug]`, `/robots.txt`, `/sitemap.xml`. - Feature paths exercised against a temporary local catalog (multi-image + two same-type items, since the local catalog is otherwise empty — see #13): gallery thumbs render for multi-image products and are absent for single-image; related renders for a product with a same-type sibling, excludes itself, and is absent for a type with no sibling; featured grid renders on home. Temp rows rolled back after. ## Provenance Built in parallel via three opus workers in isolated git worktrees (`feat/store-search`, `feat/store-featured`, `feat/store-detail`), then reconciled here onto one branch (all three had independently modified `products/page.tsx` and two created rival card components; unified to one kebab-case `product-card.tsx`). Closes #21 Closes #22 Closes #23 Closes #24
PR #19 dropped 'export const dynamic = "force-static"' from robots.ts and
sitemap.ts; under Next 16.2.10 output: export this breaks 'next build' at
/robots.txt. Restore it so the static export builds.
- #21 client-side product search + type filter on /products (ProductBrowser)
- #22 product image gallery with thumbnails on detail page
- #24 related same-type products on detail page (excludes self)
- #23 featured products section on the homepage
- shared ProductCard component (apps/store/app/products/product-card.tsx)
- gallery thumbnail styles

Verified: tsc + biome clean; static export build (output: export) generates
/products, /products/[slug], gallery thumbs (multi-image), related (same type),
and featured home grid.
yuris changed title from Store marketplace browse UX: search/filter, gallery, related, featured to feat(store): marketplace browse UX — search/filter, gallery, related products, featured 2026-07-25 14:52:33 +00:00
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/store-marketplace:feat/store-marketplace
git switch feat/store-marketplace

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff feat/store-marketplace
git switch feat/store-marketplace
git rebase main
git switch main
git merge --ff-only feat/store-marketplace
git switch feat/store-marketplace
git rebase main
git switch main
git merge --no-ff feat/store-marketplace
git switch main
git merge --squash feat/store-marketplace
git switch main
git merge --ff-only feat/store-marketplace
git switch main
git merge feat/store-marketplace
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
yuris/garage!25
No description provided.