← back to Commercialrealestate
feat(index): aggregate stats strip — median price / $-per-unit / $-per-SF / avg cap (disclosed) / median est. rent / in-budget count computed over the current filtered slice; hidden on the wait-for-selection state. Contrarian-gated, 0 errors.
d9c099f9a84d247176553edeacb3514d93ff02a1 · 2026-07-02 11:14:38 -0700 · Steve Abrams
Officer: vp-engineering
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Files touched
Diff
commit d9c099f9a84d247176553edeacb3514d93ff02a1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jul 2 11:14:38 2026 -0700
feat(index): aggregate stats strip — median price / $-per-unit / $-per-SF / avg cap (disclosed) / median est. rent / in-budget count computed over the current filtered slice; hidden on the wait-for-selection state. Contrarian-gated, 0 errors.
Officer: vp-engineering
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
public/index.html | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/public/index.html b/public/index.html
index 01e903e..78b595c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -186,6 +186,11 @@
.starbtn:hover, .starbtn.on { color:var(--warn); }
.listtbl .starbtn { font-size:14px; margin-right:5px; vertical-align:middle; }
#shortbtn.shorton { background:rgba(210,153,34,.14); border-color:var(--warn); color:var(--warn); }
+ /* aggregate stats strip */
+ .statsbar { display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding:9px 20px; border-bottom:1px solid var(--line); }
+ .statsbar:empty { display:none; }
+ .statpill { font-size:12px; color:var(--ink); background:var(--card); border:1px solid var(--line); border-radius:8px; padding:4px 10px; }
+ .statpill .sl { color:var(--mut); } .statpill b { font-variant-numeric:tabular-nums; }
</style>
</head>
<body>
@@ -435,6 +440,7 @@
</div>
</div>
<div class="activebar" id="activebar"></div>
+ <div class="statsbar" id="statsbar"></div>
<div class="grid" id="grid"></div>
<div class="foot" id="foot"></div>
</main>
@@ -985,6 +991,25 @@ function exportCSV(){
const a=document.createElement('a'); a.href=URL.createObjectURL(new Blob([lines.join('\n')],{type:'text/csv'})); a.download='cre-explorer-'+rows.length+'.csv'; a.click(); setTimeout(()=>URL.revokeObjectURL(a.href),1000);
}
function copyShareLink(){ const t=$('#linkbtn'); try{ navigator.clipboard.writeText(location.href); if(t){ const o=t.textContent; t.textContent='✓ Copied'; setTimeout(()=>t.textContent=o,1400); } }catch(e){ if(t) t.textContent='⌘C to copy'; } }
+function median(a){ if(!a.length) return null; const s=a.slice().sort((x,y)=>x-y); const m=Math.floor(s.length/2); return s.length%2?s[m]:(s[m-1]+s[m])/2; }
+function renderStats(r){
+ const sb=$('#statsbar'); if(!sb) return;
+ if(!r||!r.length){ sb.innerHTML=''; return; }
+ const prices=r.map(p=>p.price).filter(v=>v>0);
+ const ppus=r.map(p=>ppu(p)).filter(v=>v>0);
+ const ppsfs=r.map(p=>ppsf(p)).filter(v=>v>0);
+ const caps=r.map(p=>p.cap_rate).filter(v=>v!=null);
+ const aff=r.filter(p=>p.finance&&p.finance.affordable).length;
+ const rents=r.map(p=>{ const e=rentEstimate(p); return e?e.std:null; }).filter(v=>v);
+ const pill=(l,v)=>v==null?'':`<span class="statpill"><span class="sl">${l}</span> <b>${v}</b></span>`;
+ sb.innerHTML =
+ pill('Median price', prices.length?'$'+Math.round(median(prices)).toLocaleString():null)
+ +pill('Median $/unit', ppus.length?'$'+Math.round(median(ppus)).toLocaleString():null)
+ +pill('Median $/SF', ppsfs.length?'$'+Math.round(median(ppsfs)).toLocaleString():null)
+ +pill('Avg cap', caps.length?(caps.reduce((a,b)=>a+(+b),0)/caps.length).toFixed(2)+'% ('+caps.length+' disc.)':null)
+ +pill('Median est. rent', rents.length?'$'+Math.round(median(rents)).toLocaleString()+'/mo':null)
+ +pill('In budget', aff+' of '+r.length);
+}
function render(){
const g=$('#grid'); const fc=activeFilterCount();
$('#fcount').textContent=fc; $('#fcount').classList.toggle('on',fc>0);
@@ -995,10 +1020,12 @@ function render(){
g.className='grid';
g.innerHTML=`<div class="empty">👈 Expand a filter tab on the left to begin.<br><span class="small">${(DATA.ranked.length).toLocaleString()} listings loaded · ${DATA.meta.market}. Open <b>Asset type</b> (Condo · ◆ Non-QM · ⚑ Unwarrantable), <b>City</b>, or <b>Price</b> — results appear instantly, and your active filters show as removable chips up top.</span></div>`;
$('#count').innerHTML=`<b>${(DATA.ranked.length).toLocaleString()}</b> loaded · choose a filter to view`;
+ $('#statsbar').innerHTML='';
saveState(); return;
}
let r = applyFilters(DATA.ranked.slice());
sortRows(r);
+ renderStats(r);
if(!r.length){ g.className='grid'; g.innerHTML=`<div class="empty">No properties match these filters.<br><span class="small">Loosen a filter or hit “Reset all”.</span></div>`; }
else if(view==='list'){ g.className='listhost'; g.innerHTML=renderList(r); }
else { g.className='grid'; g.innerHTML=r.map(card).join(''); enrichAssessor(); }
← 8b66d89 feat(index): shortlist — ⭐ star any listing (grid + list), d
·
back to Commercialrealestate
·
feat(index): side-by-side Compare modal for shortlisted list 14963d5 →