[object Object]

← back to Rentv

feat(watchlist): add sort + density to the deal watchlist grid (HARD-rule compliance)

afcf869a7ba42a6a9e8cef5be02c95978c92e6ea · 2026-07-31 16:30:27 -0700 · Steve Abrams

watchlist.html renders /api/deals cards with chip filters but lacked the mandated
sort <select> + density slider. Added both (same reference impl as deals.html),
persisted to separate localStorage keys (rentv.watchlist.sort/.cols) so the existing
rentv_watchlist filter state is untouched.

Cody caught a real ordering bug during verify: the control wiring sat after the
await fetch('/api/deals') early-return, so a down API left the controls dead. Moved
wiring BEFORE the fetch — controls now stay live regardless of API state.

Verified in a headless browser: density→--cols=5 (grid 5 cols), sort+density persist,
filter key intact; inline JS parses. Sort logic identical to the already-proven
deals.html implementation.

Files touched

Diff

commit afcf869a7ba42a6a9e8cef5be02c95978c92e6ea
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Jul 31 16:30:27 2026 -0700

    feat(watchlist): add sort + density to the deal watchlist grid (HARD-rule compliance)
    
    watchlist.html renders /api/deals cards with chip filters but lacked the mandated
    sort <select> + density slider. Added both (same reference impl as deals.html),
    persisted to separate localStorage keys (rentv.watchlist.sort/.cols) so the existing
    rentv_watchlist filter state is untouched.
    
    Cody caught a real ordering bug during verify: the control wiring sat after the
    await fetch('/api/deals') early-return, so a down API left the controls dead. Moved
    wiring BEFORE the fetch — controls now stay live regardless of API state.
    
    Verified in a headless browser: density→--cols=5 (grid 5 cols), sort+density persist,
    filter key intact; inline JS parses. Sort logic identical to the already-proven
    deals.html implementation.
---
 public/watchlist.html | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/public/watchlist.html b/public/watchlist.html
index 43e47425..220c2379 100644
--- a/public/watchlist.html
+++ b/public/watchlist.html
@@ -198,12 +198,13 @@ function render(){
 $('clear').onclick=()=>{sel={types:[],txns:[],states:[]};save();history.replaceState(null,'','/watchlist');render();};
 
 (async function(){
-  try{ const r=await fetch('/api/deals'); ALL=(await r.json()).deals||[]; }catch(e){ $('grid').innerHTML='<div class="empty"><h3>Deals unavailable</h3></div>'; return; }
+  // Wire sort + density BEFORE the fetch so the controls stay live even if /api/deals is down.
   const ws=$('wsort'), wd=$('wdens');
   ws.value=wsort; ws.onchange=()=>{wsort=ws.value;localStorage.setItem('rentv.watchlist.sort',wsort);render();};
   const cols0=localStorage.getItem('rentv.watchlist.cols')||'3';
   wd.value=cols0; document.documentElement.style.setProperty('--cols',cols0);
   wd.oninput=()=>{document.documentElement.style.setProperty('--cols',wd.value);localStorage.setItem('rentv.watchlist.cols',wd.value);};
+  try{ const r=await fetch('/api/deals'); ALL=(await r.json()).deals||[]; }catch(e){ $('grid').innerHTML='<div class="empty"><h3>Deals unavailable</h3></div>'; return; }
   render();
 })();
 </script>

← b4f52715 auto-save: 2026-07-31T16:29:30 (1 files) — public/watchlist.  ·  back to Rentv  ·  fix(watchlist): deal cards drill to the specific deal (/news 4e674a28 →