[object Object]

← back to 1950swallpaper

fix sort + facets: wire sort param into grid fetch, count niche list in /api/facets

ddeed62e84a4dbbda1a03857a11e5f8013ecabf7 · 2026-05-19 08:26:18 -0700 · SteveStudio2

The sort <select> persisted to localStorage and set state.sort but
loadGridPage() never sent it to the server, so sort was cosmetic.
Now hydrates state.sort before the first grid load and adds the sort
query param. /api/facets total now counts PRODUCTS_NICHE (the list
actually served) instead of the raw PRODUCTS array.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit ddeed62e84a4dbbda1a03857a11e5f8013ecabf7
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Tue May 19 08:26:18 2026 -0700

    fix sort + facets: wire sort param into grid fetch, count niche list in /api/facets
    
    The sort <select> persisted to localStorage and set state.sort but
    loadGridPage() never sent it to the server, so sort was cosmetic.
    Now hydrates state.sort before the first grid load and adds the sort
    query param. /api/facets total now counts PRODUCTS_NICHE (the list
    actually served) instead of the raw PRODUCTS array.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 public/index.html | 11 ++++++++++-
 server.js         |  2 +-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/public/index.html b/public/index.html
index 4e6eb2d..c68a762 100644
--- a/public/index.html
+++ b/public/index.html
@@ -430,7 +430,15 @@ textarea:focus-visible,
 </script>
 
 <script>
-const state = { q:'', facet:'all', page:1, pages:1, total:0, loading:false, exhausted:false };
+const state = { q:'', facet:'all', sort:'newest', page:1, pages:1, total:0, loading:false, exhausted:false };
+// Hydrate saved sort BEFORE the first grid load so the sort param is honored on page one.
+(function(){
+  try {
+    var sortSel = document.getElementById('sortSelect');
+    var saved = localStorage.getItem(location.hostname.replace(/\./g, '_') + '_sort');
+    if (saved) { if (sortSel) sortSel.value = saved; state.sort = saved; }
+  } catch(e){}
+})();
 const LABELS = {"all":"All"};
 
 function escAttr(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c])); }
@@ -543,6 +551,7 @@ async function loadGridPage() {
   const params = new URLSearchParams({ page:state.page, limit:24 });
   if (state.q) params.set('q', state.q);
   if (state.facet !== 'all') params.set('aesthetic', state.facet);
+  if (state.sort && state.sort !== 'newest') params.set('sort', state.sort);
   let data;
   try {
     const r = await fetch('/api/products?' + params);
diff --git a/server.js b/server.js
index d6e30b4..cafecb0 100644
--- a/server.js
+++ b/server.js
@@ -170,7 +170,7 @@ app.get('/api/facets', (req, res) => {
     aesthetics[p.aesthetic] = (aesthetics[p.aesthetic] || 0) + 1;
     vendors[p.vendor] = (vendors[p.vendor] || 0) + 1;
   }
-  res.json({ aesthetics, vendors, total: PRODUCTS.length });
+  res.json({ aesthetics, vendors, total: PRODUCTS_NICHE.length });
 });
 
 app.get('/api/health', (req, res) => res.json({ status: 'ok', count: PRODUCTS_NICHE.length, dropped: DROPPED }));

← 760e6ec hero-4grid: relocate json from data/ to public/ for Express  ·  back to 1950swallpaper  ·  untrack .bak/.pre- snapshots, add 404-guard middleware 16dde5a →