[object Object]

← back to Commercialrealestate

crcp: make all stat tiles + enrichment bars drill to their filtered-list views

b8c63bcb3e94492743aa9b42223c1422fb4eab36 · 2026-07-31 11:21:20 -0700 · Steve Abrams

Every crcp.html data point now hrefs to deeper data (standing rule):
- 7 stat tiles -> mls/broker-grid/condos/brokers pages (FHA-approved -> warrant modal)
- 3 enrichment bars (phone/email/website captured) -> broker-grid
All targets verified 200 live; no dead links; broker/firm table rows already drilled. TK-10092

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

Files touched

Diff

commit b8c63bcb3e94492743aa9b42223c1422fb4eab36
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Jul 31 11:21:20 2026 -0700

    crcp: make all stat tiles + enrichment bars drill to their filtered-list views
    
    Every crcp.html data point now hrefs to deeper data (standing rule):
    - 7 stat tiles -> mls/broker-grid/condos/brokers pages (FHA-approved -> warrant modal)
    - 3 enrichment bars (phone/email/website captured) -> broker-grid
    All targets verified 200 live; no dead links; broker/firm table rows already drilled. TK-10092
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 public/crcp.html | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/public/crcp.html b/public/crcp.html
index d87cc97..15de2cb 100644
--- a/public/crcp.html
+++ b/public/crcp.html
@@ -33,6 +33,7 @@
   .tile .delta{position:absolute;top:13px;right:14px;font-size:12px;font-weight:700;color:var(--active);opacity:0;transition:opacity .3s;}
   .tile .delta.show{opacity:1;}
   .tile.gold .v{color:var(--gold);} .tile.active .v{color:var(--active);} .tile.draft .v{color:var(--draft);} .tile.staged .v{color:var(--staged);}
+  .tile.clickable{cursor:pointer;transition:border-color .12s,transform .12s;} .tile.clickable:hover{border-color:var(--gold);transform:translateY(-1px);} .tile.clickable::after{content:'↗';position:absolute;bottom:8px;right:11px;font-size:11px;color:var(--muted);opacity:0;transition:opacity .12s;} .tile.clickable:hover::after{opacity:1;}
   .cols{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
   @media(max-width:880px){.cols{grid-template-columns:1fr;}}
   /* tablet + mobile: header + nav wrap instead of overflowing the viewport
@@ -299,8 +300,8 @@ async function openWarrant(status){
 }
 const fmt=n=>n==null?'—':Number(n).toLocaleString();
 let prev={};
-function tile(k,key,v,sub,cls){ const d=(prev[key]!=null&&v>prev[key])?('+'+(v-prev[key])):'';
-  return `<div class="tile ${cls||''}" data-key="${key}"><div class="k">${k}</div><div class="v">${fmt(v)}</div><div class="sub">${sub||''}</div><div class="delta ${d?'show':''}">${d}</div></div>`; }
+function tile(k,key,v,sub,cls,href){ const d=(prev[key]!=null&&v>prev[key])?('+'+(v-prev[key])):'';
+  return `<div class="tile ${cls||''}${href?' clickable':''}" data-key="${key}" data-href="${href||''}"><div class="k">${k}</div><div class="v">${fmt(v)}</div><div class="sub">${sub||''}</div><div class="delta ${d?'show':''}">${d}</div></div>`; }
 function bar(label,have,total,color){ const pct=total?Math.round(100*have/total):0;
   return `<div style="margin-bottom:10px"><div class="prog"><span>${label}</span><span>${fmt(have)} / ${fmt(total)} · ${pct}%</span></div><div class="bar"><i style="width:${pct}%;background:${color||'linear-gradient(90deg,var(--gold),var(--active))'}"></i></div></div>`; }
 
@@ -388,23 +389,29 @@ async function poll(){
   $('#livetxt').textContent='live · '+new Date(s.ts).toLocaleTimeString();
   // tiles
   $('#tiles').innerHTML = [
-    tile('Listings','listings',s.listings,s.market||'LA County','gold'),
-    tile('Brokers','brokers',s.brokers,(s.colist!=null?s.colist+' co-list links':''),'active'),
-    tile('Firms','firms',s.firms,'brokerages','draft'),
-    tile('Condos scraped','condos',s.condos,(s.condosByStatus?Object.entries(s.condosByStatus).map(([k,v])=>v+' '+k.replace('_',' ')).join(' · '):'awaiting Job A'),'staged'),
-    tile('Residential agents','agents_residential',s.agents_residential||0,((s.condos_with_agent||0)+' condos w/ agent · '+(s.agents_res_phone||0)+'☎ '+(s.agents_res_email||0)+'✉'),'draft'),
+    tile('Listings','listings',s.listings,s.market||'LA County','gold','/mls.html'),
+    tile('Brokers','brokers',s.brokers,(s.colist!=null?s.colist+' co-list links':''),'active','/broker-grid.html'),
+    tile('Firms','firms',s.firms,'brokerages','draft','/broker-grid.html'),
+    tile('Condos scraped','condos',s.condos,(s.condosByStatus?Object.entries(s.condosByStatus).map(([k,v])=>v+' '+k.replace('_',' ')).join(' · '):'awaiting Job A'),'staged','/condos.html'),
+    tile('Residential agents','agents_residential',s.agents_residential||0,((s.condos_with_agent||0)+' condos w/ agent · '+(s.agents_res_phone||0)+'☎ '+(s.agents_res_email||0)+'✉'),'draft','/mls.html'),
     tile('FHA-approved','fhaApproved',s.fhaApproved,'warrantable (proxy)','active'),
-    tile('Broker edges','edges',s.edges,'broker↔listing','gold')
+    tile('Broker edges','edges',s.edges,'broker↔listing','gold','/brokers.html')
   ].join('');
-  // FHA-approved tile drills into the warrantability list too (TK-10092, "all data points href")
+  // Every stat tile drills to its filtered-list page ("all data points href", TK-10092).
+  document.querySelectorAll('#tiles .tile[data-href]').forEach(t=>{ const h=t.dataset.href;
+    if(h){ t.classList.add('clickable'); t.title='Open '+h.replace(/^\//,'').replace('.html',''); t.onclick=()=>{ location.href=h; }; } });
+  // FHA-approved tile drills into the warrantability list instead (a modal, not a page).
   const fhaTile=document.querySelector('#tiles .tile[data-key="fhaApproved"]');
-  if(fhaTile){ fhaTile.style.cursor='pointer'; fhaTile.title='Click to list the FHA-approved condos';
+  if(fhaTile){ fhaTile.classList.add('clickable'); fhaTile.title='Click to list the FHA-approved condos';
     fhaTile.onclick=()=>{ window._waQ=''; openWarrant('fha_approved'); }; }
   // enrichment bars (the LIVE populating)
   $('#enrLbl').textContent = (s.brokers_phone||0)+' phone · '+(s.brokers_email||0)+' email';
-  $('#enrBars').innerHTML = bar('Phone captured', s.brokers_phone||0, s.brokers, 'var(--active)')
-    + bar('Email captured', s.brokers_email||0, s.brokers, 'var(--draft)')
-    + (s.brokers_web!=null?bar('Website found', s.brokers_web, s.brokers, 'var(--gold)'):'');
+  // each enrichment count drills to the broker grid (where phone/email/website are columns) — "all data points href"
+  $('#enrBars').innerHTML =
+      `<div class="wclk" title="Open the broker grid — phone column">`+bar('Phone captured', s.brokers_phone||0, s.brokers, 'var(--active)')+`</div>`
+    + `<div class="wclk" title="Open the broker grid — email column">`+bar('Email captured', s.brokers_email||0, s.brokers, 'var(--draft)')+`</div>`
+    + (s.brokers_web!=null?`<div class="wclk" title="Open the broker grid — website column">`+bar('Website found', s.brokers_web, s.brokers, 'var(--gold)')+`</div>`:'');
+  document.querySelectorAll('#enrBars .wclk').forEach(el=>el.onclick=()=>{ location.href='/broker-grid.html'; });
   const enr=(s.brokers_phone||0)+(s.brokers_email||0);
   const penr=(prev.brokers_phone||0)+(prev.brokers_email||0);
   $('#enrMeta').innerHTML = enr>penr ? `<span class="has">▲ +${enr-penr} contacts since last refresh — Job B populating…</span>` : (enr===0?'Job B (broker enrichment) queued — contacts will populate here live.':'enrichment idle / complete');

← df8a26f harden esc(): escape > as well as & < " (condos + crcp)  ·  back to Commercialrealestate  ·  col-resize: don't enhance/pin HIDDEN tables (fleet regressio 9865336 →