[object Object]

← back to Madagascarwallpaper

index: wire sort select to API, hydrate saved sort before first load

dd75db743ef626ee9c5e6839e84842afc0729f19 · 2026-05-19 08:05:58 -0700 · Steve

The sort <select> persisted to localStorage but state.sort was never
sent in the /api/products query, and the wire-up that read the saved
value ran AFTER the initial loadGridPage(). Now state.sort is hydrated
from localStorage at state-init time (before the first fetch), the
select reflects it, and loadGridPage() passes sort= to the server.
Also add rel="noopener noreferrer" to the Facebook external link.

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

Files touched

Diff

commit dd75db743ef626ee9c5e6839e84842afc0729f19
Author: Steve <steve@designerwallcoverings.com>
Date:   Tue May 19 08:05:58 2026 -0700

    index: wire sort select to API, hydrate saved sort before first load
    
    The sort <select> persisted to localStorage but state.sort was never
    sent in the /api/products query, and the wire-up that read the saved
    value ran AFTER the initial loadGridPage(). Now state.sort is hydrated
    from localStorage at state-init time (before the first fetch), the
    select reflects it, and loadGridPage() passes sort= to the server.
    Also add rel="noopener noreferrer" to the Facebook external link.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 public/index.html | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/public/index.html b/public/index.html
index 952a9a5..5ef0030 100644
--- a/public/index.html
+++ b/public/index.html
@@ -238,7 +238,9 @@ textarea:focus-visible,
         </a>
         <nav class="ns-nav" id="nsPrimaryNav" aria-label="Primary">
             <a href="/">Home</a>
-            <a href="/about">About</a>
+            <a href="/history">History</a>
+            <a href="/care">Care</a>
+            <a href="/trade">Trade</a>
             <button type="button" onclick="nsContactOpen()">Contact</button>
         </nav>
         <button type="button" class="mobile-toggle" aria-label="Toggle menu" aria-controls="nsPrimaryNav" aria-expanded="false" onclick="nsToggleNav(this)">
@@ -338,7 +340,7 @@ textarea:focus-visible,
     <div>
       <div class="footer-brand">madagascarwallpaper</div>
       <p class="footer-text">madagascarwallpaper — real samples ship free.</p>
-      <p class="footer-text" style="margin-top:14px;font-size:11px;letter-spacing:0.18em;text-transform:uppercase;font-weight:600;color:var(--paper);opacity:0.7"><a href="/about" style="color:inherit;text-decoration:none;border-bottom:1px solid var(--accent)">About →</a></p>
+      <p class="footer-text" style="margin-top:14px;font-size:11px;letter-spacing:0.18em;text-transform:uppercase;font-weight:600;color:var(--paper);opacity:0.7"><a href="/history" style="color:inherit;text-decoration:none;border-bottom:1px solid var(--accent)">Our History →</a></p>
     </div>
     <div class="footer-col">
       <h4>Aesthetic</h4>
@@ -353,7 +355,7 @@ textarea:focus-visible,
   
     <div class="footer-col">
       <h4>Social</h4>
-      <a class="fb-link" href="https://www.facebook.com/SteveAbramsDesigns.DesignerWallcoverings" target="_blank" rel="noopener">Facebook</a>
+      <a class="fb-link" href="https://www.facebook.com/SteveAbramsDesigns.DesignerWallcoverings" target="_blank" rel="noopener noreferrer">Facebook</a>
     </div>
   </div>
   <div class="footer-bottom">
@@ -427,7 +429,13 @@ 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', page:1, pages:1, total:0, loading:false, exhausted:false, sort:'newest' };
+// DW STANDARD: hydrate saved sort BEFORE first grid load so the initial fetch honors it.
+try {
+  const __sk = location.hostname.replace(/\./g, '_') + '_sort';
+  const __sv = localStorage.getItem(__sk);
+  if (__sv) state.sort = __sv;
+} catch(e){}
 const LABELS = {"all":"All"};
 
 function escAttr(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c])); }
@@ -540,6 +548,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);
@@ -898,9 +907,9 @@ loadGridPage();
   const sortSel = document.getElementById('sortSelect');
   if (!sortSel) return;
   const KEY = location.hostname.replace(/\./g, '_') + '_sort';
-  const saved = localStorage.getItem(KEY);
-  if (saved) { try { sortSel.value = saved; } catch(e){} }
-  if (typeof state !== 'undefined') state.sort = sortSel.value;
+  // state.sort was already hydrated from localStorage before the first grid load;
+  // just reflect it in the <select> so the UI matches.
+  if (typeof state !== 'undefined' && state.sort) { try { sortSel.value = state.sort; } catch(e){} }
   sortSel.addEventListener('change', e => {
     const v = e.target.value;
     try { localStorage.setItem(KEY, v); } catch(e){}

← e17fe8c server: fix facets total, add .bak 404-guard, clean-URL stat  ·  back to Madagascarwallpaper  ·  nav: remove dead /about and /vocabulary links 690771d →