← back to Rentv
desk: lead with Commercial brokers (phone/email on file) as default scope; show firm-level phone/email on DRE agent cards; scope-aware status line
9a879ba1555ab5d57dd0df3fa6330a0058c853d3 · 2026-08-12 14:41:35 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 9a879ba1555ab5d57dd0df3fa6330a0058c853d3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Aug 12 14:41:35 2026 -0700
desk: lead with Commercial brokers (phone/email on file) as default scope; show firm-level phone/email on DRE agent cards; scope-aware status line
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
public/desk.html | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/public/desk.html b/public/desk.html
index ace70371..3cbf3c6c 100644
--- a/public/desk.html
+++ b/public/desk.html
@@ -76,11 +76,11 @@
<button data-v="directory" class="on"><span class="i">▤</span>Directory</button>
<button data-v="analytics"><span class="i">▮</span>Analytics</button>
<div class="h" style="margin-top:10px">Scope</div>
- <button data-s="brokers" class="on scope"><span class="i">👤</span>Brokers <span class="c" id="cB">0</span></button>
+ <button data-s="commercial" class="on scope"><span class="i">🏬</span>Commercial <span class="c" id="cC">0</span></button>
+ <button data-s="brokers" class="scope"><span class="i">👤</span>Brokers <span class="c" id="cB">0</span></button>
<button data-s="firms" class="scope"><span class="i">🏢</span>Firms <span class="c" id="cF">0</span></button>
<button data-s="owners" class="scope"><span class="i">🏛️</span>Owners <span class="c" id="cO">0</span></button>
<button data-s="sublease" class="scope"><span class="i">🔑</span>Sublease <span class="c" id="cS">0</span></button>
- <button data-s="commercial" class="scope"><span class="i">🏬</span>Commercial <span class="c" id="cC">0</span></button>
<div class="fresh" id="fresh"></div>
</nav>
<div class="content">
@@ -117,11 +117,21 @@ function actions(k,x){
x.firm?A(LI_C(x.firm),'🏢','Firm'):'',
A(GOOG(x.name+' '+(x.firm||'')+' commercial real estate'),'🔎','Google')
].filter(Boolean).join('');}
- return [A(LI_P(x.name,x.firm_name),'👤','LinkedIn'),A(GOOG(x.name+' '+(x.firm_name||'')+' '+loc(x)),'🔎','Google'),x.firm_name?A(WEB(x.firm_name),'🌐','Firm site'):'',x.firm_name?A(LI_C(x.firm_name),'🏢','Firm'):'',loc(x)?A(MAPS((x.firm_name||x.name)+' '+loc(x)),'📍','Map'):'',x.license_no?A(DRE(x.license_no),'🪪','DRE'):''].filter(Boolean).join('');
+ const ph=x.broker_phone||x.firm_phone, em=x.broker_email||x.firm_email, ws=x.broker_website||x.firm_website;
+ return [
+ ph?A('tel:'+String(ph).replace(/[^\d+]/g,''),'📞','Call'):'',
+ em?A('mailto:'+em,'✉️','Email'):'',
+ ws?A(/^https?:\/\//i.test(ws)?ws:'https://'+ws,'🌐','Website'):(x.firm_name?A(WEB(x.firm_name),'🌐','Firm site'):''),
+ A(LI_P(x.name,x.firm_name),'👤','LinkedIn'),
+ A(GOOG(x.name+' '+(x.firm_name||'')+' '+loc(x)),'🔎','Google'),
+ x.firm_name?A(LI_C(x.firm_name),'🏢','Firm'):'',
+ loc(x)?A(MAPS((x.firm_name||x.name)+' '+loc(x)),'📍','Map'):'',
+ x.license_no?A(DRE(x.license_no),'🪪','DRE'):''
+ ].filter(Boolean).join('');
}
const subRate=x=>x.asking_rate?('$'+Number(x.asking_rate).toFixed(2)+'/'+(x.rate_period||'yr')+' SF'):'Rate on request';
const nm=x=>x.name||x.address||x.street||x.ain, sub=(k,x)=>k==='brokers'?(x.firm_name||'—'):k==='firms'?((x.agent_count||0).toLocaleString()+' agents'):k==='sublease'?[x.sqft?Number(x.sqft).toLocaleString()+' SF':null,subRate(x),x.submarket||x.city].filter(Boolean).join(' · '):k==='commercial'?[x.firm,x.listings?x.listings+' listings':null,x.agent_type].filter(Boolean).join(' · '):(x.type_label||'');
-let D={scope:'brokers',view:'directory',selDir:0,selMap:0};
+let D={scope:'commercial',view:'directory',selDir:0,selMap:0};
// chrome
$('burger').onclick=()=>{$('scrim').classList.add('open');$('drawer').classList.add('open');};
const cd=()=>{$('scrim').classList.remove('open');$('drawer').classList.remove('open');};$('dclose').onclick=cd;$('scrim').onclick=cd;
@@ -139,10 +149,17 @@ async function jget(u,fb){try{const r=await fetch(u,{credentials:'same-origin'})
D.commercial=(cb&&(cb.brokers||cb.rows))||(Array.isArray(cb)?cb:[]);D.totalC=(cs&&(cs.brokers_web||cs.brokers))||D.commercial.length;D.creStats=cs||{};
D.totalB=b.total||D.brokers.length;D.totalF=f.total||D.firms.length;D.totalS=(sl&&sl.total)||D.subleases.length;
$('cB').textContent=D.brokers.length;$('cF').textContent=D.firms.length;$('cO').textContent=D.owners.length;$('cS').textContent=D.subleases.length;$('cC').textContent=D.commercial.length;
- $('fresh').textContent='CA DRE registry · '+D.brokers.length+' brokers of '+D.totalB.toLocaleString()+' statewide';
+ setFresh();
renderAll();
})();
function scopeData(){return D.scope==='brokers'?D.brokers:D.scope==='firms'?D.firms:D.scope==='sublease'?D.subleases:D.scope==='commercial'?D.commercial:D.owners;}
+function setFresh(){let t;
+ if(D.scope==='commercial')t='RENTV commercial desk · '+D.commercial.length.toLocaleString()+' brokers, phone/email on file';
+ else if(D.scope==='firms')t='CA brokerages · '+D.firms.length.toLocaleString()+' of '+Number(D.totalF||D.firms.length).toLocaleString();
+ else if(D.scope==='owners')t='Marquee LA assets · '+D.owners.length.toLocaleString();
+ else if(D.scope==='sublease')t='Sublease inventory · '+D.subleases.length.toLocaleString();
+ else t='CA DRE registry · '+D.brokers.length.toLocaleString()+' of '+Number(D.totalB||D.brokers.length).toLocaleString()+' broker/firm-affiliated';
+ $('fresh').textContent=t;}
const debounce=(fn,ms)=>{let t;return(...a)=>{clearTimeout(t);t=setTimeout(()=>fn(...a),ms);};};
// live server-side search across the FULL registry (382k brokers / 34k firms) via the proxy;
// owners are only 12 so they filter client-side; empty term returns the loaded set.
@@ -170,7 +187,7 @@ function applyScopeViews(){
}
$('rail').addEventListener('click',e=>{const btn=e.target.closest('button');if(!btn||btn.disabled)return;
if(btn.dataset.v){document.querySelectorAll('#rail [data-v]').forEach(x=>x.classList.remove('on'));btn.classList.add('on');D.view=btn.dataset.v;document.querySelectorAll('.view').forEach(v=>v.classList.remove('on'));$('v-'+D.view).classList.add('on');}
- if(btn.dataset.s){document.querySelectorAll('#rail .scope').forEach(x=>x.classList.remove('on'));btn.classList.add('on');D.scope=btn.dataset.s;D.selDir=0;renderAll();}
+ if(btn.dataset.s){document.querySelectorAll('#rail .scope').forEach(x=>x.classList.remove('on'));btn.classList.add('on');D.scope=btn.dataset.s;D.selDir=0;setFresh();renderAll();}
});
function renderAll(){directory();analytics();applyScopeViews();}
// ── Directory (master-detail) ──
@@ -179,7 +196,7 @@ function directory(){
$('v-directory').innerHTML=`<div class="md"><div class="list"><div class="search"><input id="dq" placeholder="Search ${D.scope}…"><div class="fresh" id="dcount" style="padding:7px 2px 0"></div></div><div class="rows" id="drows"></div></div><div class="detail" id="ddetail"></div></div>`;
function list(){let r=rows.slice();const v=($('dq').value||'').toLowerCase();if(v)r=r.filter(x=>JSON.stringify(x).toLowerCase().includes(v));return r;}
function detail(x){if(!x){$('ddetail').innerHTML='';return;}
- const grid=D.scope==='sublease'?[['SqFt',x.sqft?Number(x.sqft).toLocaleString():'—'],['Asking',subRate(x)],['Term',x.term_months?x.term_months+' mo':'—'],['Available',x.available_date?dstr(x.available_date):'Now'],['Sublandlord',x.sublandlord||'—'],['Listing broker',x.firm_name||'—']]:D.scope==='owners'?[['Assessed',shortUsd(x.assessed_total)],['SqFt',(x.sqft||0).toLocaleString()],['Built',x.year_built||'—'],['AIN',x.ain]]:D.scope==='firms'?[['Agents',(x.agent_count||0).toLocaleString()],['HQ',loc(x)||'—'],['License',x.license_no||'—'],['Source',x.source||'—']]:D.scope==='commercial'?[['Firm',x.firm||'—'],['Phone',x.phone||'—'],['Email',x.email||'—'],['Listings',String(x.listings??'0')],['Type',x.agent_type||'—'],['Specialties',x.specialties||'—'],['License',x.dre_license||x.license||'—'],['Office',x.office_addr||'—']]:[['License',x.license_no||'—'],['Type',x.license_type||'—'],['Firm',x.firm_name||'—'],['City',x.city||'—']];
+ const grid=D.scope==='sublease'?[['SqFt',x.sqft?Number(x.sqft).toLocaleString():'—'],['Asking',subRate(x)],['Term',x.term_months?x.term_months+' mo':'—'],['Available',x.available_date?dstr(x.available_date):'Now'],['Sublandlord',x.sublandlord||'—'],['Listing broker',x.firm_name||'—']]:D.scope==='owners'?[['Assessed',shortUsd(x.assessed_total)],['SqFt',(x.sqft||0).toLocaleString()],['Built',x.year_built||'—'],['AIN',x.ain]]:D.scope==='firms'?[['Agents',(x.agent_count||0).toLocaleString()],['HQ',loc(x)||'—'],['License',x.license_no||'—'],['Source',x.source||'—']]:D.scope==='commercial'?[['Firm',x.firm||'—'],['Phone',x.phone||'—'],['Email',x.email||'—'],['Listings',String(x.listings??'0')],['Type',x.agent_type||'—'],['Specialties',x.specialties||'—'],['License',x.dre_license||x.license||'—'],['Office',x.office_addr||'—']]:[['Phone',(x.broker_phone||x.firm_phone)||'—'],['Email',(x.broker_email||x.firm_email)||'—'],['License',x.license_no||'—'],['Type',x.license_type||'—'],['Firm',x.firm_name||'—'],['City',x.city||'—']];
const dk=D.scope==='sublease'?(x.lease_type==='direct'?'Direct Lease':'Sublease Available'):D.scope==='owners'?(x.type_label||'Asset'):D.scope==='firms'?'Brokerage':D.scope==='commercial'?'Commercial Broker':(x.license_type||'Licensee');
const dmeta=D.scope==='sublease'?[x.floor_suite,x.submarket,x.city].filter(Boolean).join(' · '):D.scope==='owners'?[x.address,x.city].filter(Boolean).join(', '):D.scope==='commercial'?[x.firm,x.agent_type,x.office_addr].filter(Boolean).join(' · '):(sub(D.scope,x)+' · '+(loc(x)||''));
$('ddetail').innerHTML=`<div class="k">${esc(dk)}</div><h2>${esc(nm(x))}</h2><div class="meta">${esc(dmeta)}</div><div class="acts">${actions(D.scope,x)}</div><div class="grid">${grid.map(([k,v])=>`<div class="cell"><div class="kk">${k}</div><div class="vv">${esc(v)}</div></div>`).join('')}</div>`;}
@@ -200,7 +217,7 @@ function directory(){
function gotoScope(s){
if(!s) return;
document.querySelectorAll('#rail .scope').forEach(x=>x.classList.toggle('on',x.dataset.s===s));
- D.scope=s; D.selDir=0; D.view='directory';
+ D.scope=s; D.selDir=0; D.view='directory'; setFresh();
document.querySelectorAll('#rail [data-v]').forEach(x=>x.classList.toggle('on',x.dataset.v==='directory'));
document.querySelectorAll('.view').forEach(v=>v.classList.toggle('on',v.id==='v-directory'));
renderAll();
← 367d6825 CRM directory: Doc B complete (22p) — +investment banks, mon
·
back to Rentv
·
auto-data-snapshot: 2026-08-12T15:01:25 (8 data files) — dat 3df566dd →