[object Object]

← back to Wallsandfabrics

fix(api): surface tab counts now reflect active search query in /api/products

742efa04ed38bb3c4b77ae21b02c2bffd86b25d0 · 2026-05-30 21:24:59 -0700 · Steve Abrams

/api/products was returning the global SURFACE_COUNTS constant regardless of
?q= filter, so the surface tabs showed full-catalog totals even when a search
narrowed the result set. Now computes per-surface counts from the q-filtered
list before applying the surface filter, matching /api/facets behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files touched

Diff

commit 742efa04ed38bb3c4b77ae21b02c2bffd86b25d0
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat May 30 21:24:59 2026 -0700

    fix(api): surface tab counts now reflect active search query in /api/products
    
    /api/products was returning the global SURFACE_COUNTS constant regardless of
    ?q= filter, so the surface tabs showed full-catalog totals even when a search
    narrowed the result set. Now computes per-surface counts from the q-filtered
    list before applying the surface filter, matching /api/facets behavior.
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
 server.js | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/server.js b/server.js
index 6e3f3f4..ecfd820 100644
--- a/server.js
+++ b/server.js
@@ -181,13 +181,17 @@ app.get('/api/products', (req, res) => {
     const needle = q.toLowerCase();
     list = list.filter(p => (p.title || '').toLowerCase().includes(needle) || (p.tags || []).some(t => t.toLowerCase().includes(needle)));
   }
+  // Compute surface counts from the q-filtered (but not surface-filtered) list so
+  // the surface tabs in the frontend reflect how many matches exist per surface for
+  // the active search query, not the whole unfiltered catalog.
+  const filteredSurfaces = list.reduce((acc, p) => { acc[p.__surface] = (acc[p.__surface] || 0) + 1; return acc; }, {});
   if (surface && surface !== 'all') list = list.filter(p => p.__surface === surface);
   list = sortProducts(list, sort);
   const total = list.length;
   const pageNum = Math.max(1, parseInt(page) || 1);
   const lim = Math.min(60, parseInt(limit) || 24);
   const start = (pageNum - 1) * lim;
-  res.json({ total, page: pageNum, limit: lim, pages: Math.ceil(total / lim), sort, surfaces: SURFACE_COUNTS, items: list.slice(start, start + lim) });
+  res.json({ total, page: pageNum, limit: lim, pages: Math.ceil(total / lim), sort, surfaces: filteredSurfaces, items: list.slice(start, start + lim) });
 });
 
 app.get('/api/facets', (req, res) => {

← 7c8b3c4 feat(fleet): theme1/theme2 query-param-gated toggle on catal  ·  back to Wallsandfabrics  ·  scrub residual 3rd-party vendor names from products.json sou bac7b3c →