← back to Commercialrealestate
modal drill (Cody fixes): gate broker DRE link on verified dre_license not raw regex (+serve.js SELECT), style .maddr a.dl, drop trailing zip space
5d14bae08fb1c0fa3bdfdc8fc2e8ce5564a6bdb7 · 2026-08-03 10:33:52 -0700 · Steve Abrams
Files touched
M public/broker-grid.htmlM public/condos.htmlM scripts/serve.js
Diff
commit 5d14bae08fb1c0fa3bdfdc8fc2e8ce5564a6bdb7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Aug 3 10:33:52 2026 -0700
modal drill (Cody fixes): gate broker DRE link on verified dre_license not raw regex (+serve.js SELECT), style .maddr a.dl, drop trailing zip space
---
public/broker-grid.html | 9 ++++++++-
public/condos.html | 4 ++--
scripts/serve.js | 2 +-
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/public/broker-grid.html b/public/broker-grid.html
index 400df61..ba6b26e 100644
--- a/public/broker-grid.html
+++ b/public/broker-grid.html
@@ -331,7 +331,14 @@ async function openContact(name,id){
track('broker_modal',{kind:'broker',id:d.broker&&d.broker.id,name:d.broker&&d.broker.name,active:(d.current||[]).length,closed:(d.closed||[]).length,withdrawn:(d.expired||[]).length});
const b=d.broker, w=b.website?(/^https?:/.test(b.website)?b.website:'https://'+b.website):null;
const li=b.linkedin?(/^https?:/.test(b.linkedin)?b.linkedin:'https://'+b.linkedin):null;
- mb.innerHTML='<h3>'+esc(b.name)+atb(b.agent_type)+'</h3><div class="mfirm">'+esc(b.firm||'—')+(b.title?' · '+esc(b.title):'')+(b.license?(function(){const L=String(b.license).trim();return /^\d{8}$/.test(L)?' · DRE# <a href="https://www2.dre.ca.gov/PublicASP/pplinfo.asp?License_id='+encodeURIComponent(L)+'" target="_blank" rel="noopener noreferrer" title="Full CA DRE license record ↗">'+esc(L)+' ↗</a>':' · DRE/MLS '+esc(L);})():'')+'</div>'
+ mb.innerHTML='<h3>'+esc(b.name)+atb(b.agent_type)+'</h3><div class="mfirm">'+esc(b.firm||'—')+(b.title?' · '+esc(b.title):'')+(function(){
+ // Prefer the VERIFIED dre_license column (clean, cross-referenced) over regex-matching the
+ // raw scraped license (Cody gate) — so the DRE# always hooks the correct full CA DRE record.
+ const dl=b.dre_license?String(b.dre_license).trim():'', L=b.license?String(b.license).trim():'';
+ const dre=(dl&&/^\d{7,8}$/.test(dl))?dl:(/^\d{8}$/.test(L)?L:'');
+ if(dre) return ' · DRE# <a href="https://www2.dre.ca.gov/PublicASP/pplinfo.asp?License_id='+encodeURIComponent(dre)+'" target="_blank" rel="noopener noreferrer" title="Full CA DRE license record ↗">'+esc(dre)+' ↗</a>';
+ return L?' · DRE/MLS '+esc(L):'';
+ })()+'</div>'
+'<div class="ci">'
+(b.phone?'<a href="tel:'+esc(b.phone)+'">☎ '+esc(b.phone)+'</a>':'<span class="mut">☎ —</span>')
+(b.email?'<a href="mailto:'+esc(b.email)+'">✉ '+esc(b.email)+'</a>':'<span class="mut">✉ —</span>')
diff --git a/public/condos.html b/public/condos.html
index c36634c..8cefecc 100644
--- a/public/condos.html
+++ b/public/condos.html
@@ -101,7 +101,7 @@
#modal .maddr{color:var(--mut);font-size:13px;margin-bottom:10px;}
#modal .litem{display:flex;justify-content:space-between;gap:10px;padding:5px 0;border-bottom:1px solid #20262f;font-size:13px;}
#modal .litem .m{color:var(--mut);}
- #modal .litem a.dl{color:var(--blue);text-decoration:none;} #modal .litem a.dl:hover{text-decoration:underline;}
+ #modal .litem a.dl,#modal .maddr a.dl{color:var(--blue);text-decoration:none;} #modal .litem a.dl:hover,#modal .maddr a.dl:hover{text-decoration:underline;}
#modal .src{font-size:12px;color:var(--mut);margin-top:12px;border-top:1px solid var(--line);padding-top:10px;}
</style>
</head>
@@ -484,7 +484,7 @@ function openDetail(id){
const line=(l,v)=>v==null||v===''?'':`<div class="litem"><span class="m">${esc(l)}</span><span>${v}</span></div>`;
const ppsf=c.sqft?Math.round(c.price/c.sqft):null;
mb.innerHTML='<h3>'+esc(c.project_name||c.address||'Condo')+'</h3>'
- +'<div class="maddr">'+(function(){const q=[c.address,c.city,c.zip].filter(Boolean).join(', ');const txt=esc(c.address||'')+(c.city?', '+esc(c.city):'')+' '+esc(c.zip||'');return q?`<a class="dl" href="https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(q)}" target="_blank" rel="noopener noreferrer" title="Open in Google Maps">${txt} 🗺️</a>`:txt;})()+'</div>'
+ +'<div class="maddr">'+(function(){const q=[c.address,c.city,c.zip].filter(Boolean).join(', ');const txt=esc(c.address||'')+(c.city?', '+esc(c.city):'')+(c.zip?' '+esc(c.zip):'');return q?`<a class="dl" href="https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(q)}" target="_blank" rel="noopener noreferrer" title="Open in Google Maps">${txt} 🗺️</a>`:txt;})()+'</div>'
+statusBadge(c.warrantable_status||c.warrant_signal||'—')
+'<div style="margin-top:12px">'
+line('Price',money(c.price))
diff --git a/scripts/serve.js b/scripts/serve.js
index da7fc97..a35526d 100644
--- a/scripts/serve.js
+++ b/scripts/serve.js
@@ -991,7 +991,7 @@ app.get('/api/broker', async (req, res) => {
const q = (s, a) => brokerdb.pool.query(s, a).then(r => r.rows);
// Prefer id (unambiguous — names collide across commercial/residential). For a name lookup,
// resolve deterministically: the row with the most listings (commercial edges + condos) wins.
- const sel = `SELECT b.id, b.name, f.name firm, b.phone, b.email, b.title, b.total_assets, b.website, b.agent_type, b.license`;
+ const sel = `SELECT b.id, b.name, f.name firm, b.phone, b.email, b.title, b.total_assets, b.website, b.agent_type, b.license, b.dre_license, b.dre_match`;
const brokers = id
? await q(`${sel} FROM broker b LEFT JOIN firm f ON f.id=b.firm_id WHERE b.id=$1`, [id])
: await q(`${sel},
← 0d5ac4f detail-modal drill enrichment: condos modal address→Google M
·
back to Commercialrealestate
·
detail-modal drill enrichment (index/sales/mls): index broke a06fde2 →