← back to Rentv 2026
console: surface existing phone/website (60,861 contractors have phone) as tel/site links + CSV export + fix Los Angeles→Greater LA market-map bug
749d977384202aff5021a2b117d057b7b726d23e · 2026-07-31 10:38:47 -0700 · Steve
Files touched
Diff
commit 749d977384202aff5021a2b117d057b7b726d23e
Author: Steve <steve@designerwallcoverings.com>
Date: Fri Jul 31 10:38:47 2026 -0700
console: surface existing phone/website (60,861 contractors have phone) as tel/site links + CSV export + fix Los Angeles→Greater LA market-map bug
---
public/social.html | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/public/social.html b/public/social.html
index 1c28000e..8ceef789 100644
--- a/public/social.html
+++ b/public/social.html
@@ -81,6 +81,9 @@
.gitem.sel { border-color:var(--li); box-shadow:0 0 0 2px #cfe3f8 inset; }
.gi-letter { display:inline-block; margin:8px 0 0 8px; border:1px solid var(--li); background:#fff; color:var(--li); border-radius:7px; padding:3px 9px; font-size:11px; font-weight:600; cursor:pointer; }
.gi-letter:hover { background:var(--li); color:#fff; }
+ .gi-contact { font-size:11px; margin-top:5px; }
+ .gi-contact a { color:var(--li); text-decoration:none; margin-right:10px; }
+ .gi-contact a:hover { text-decoration:underline; }
.grail-add { display:flex; gap:6px; margin-top:14px; }
.grail-add input { flex:1; }
.grail-add button { padding:9px 12px; font-size:12.5px; }
@@ -146,6 +149,7 @@
<div class="grail-actions">
<button id="grailAddAll">+ Add all categories</button>
<button class="ghost" id="grailPull">Pull registry contacts</button>
+ <button class="ghost" id="grailCsv">⤓ CSV</button>
<button class="ghost" id="grailClear">Clear</button>
</div>
<input id="grailFilter" placeholder="Filter targets…">
@@ -318,6 +322,7 @@
+'<a class="gi-li" href="'+liUrl(x.terms||x.name)+'" target="_blank" rel="noopener">in ↗</a>'
+'<button class="gi-x" data-del="'+x.id+'" title="Remove">✕</button></div>'
+(x.sub?'<div class="gi-sub">'+esc(x.sub)+'</div>':'')
+ +((x.phone||x.website)?'<div class="gi-contact">'+(x.phone?'<a href="tel:'+esc(String(x.phone).replace(/[^\d+]/g,''))+'">📞 '+esc(x.phone)+'</a>':'')+(x.website?'<a href="'+(/^https?:/i.test(x.website)?esc(x.website):'https://'+esc(x.website))+'" target="_blank" rel="noopener">🌐 site</a>':'')+'</div>':'')
+'<span class="gstatus s'+(x.status||0)+'" data-st="'+x.id+'">'+GSTL[x.status||0]+'</span>'
+'<span class="gwhen">🕓 '+when+'</span>'
+'<button class="gi-letter" data-letter="'+x.id+'">'+lLabel+'</button>'
@@ -371,6 +376,20 @@
document.getElementById('grailAddAll').onclick=gAddAllCats;
document.getElementById('grailPull').onclick=gPull;
document.getElementById('grailClear').onclick=function(){ if(confirm('Clear the growth LinkedIn list?')){ gsave([]); grender(); gmsg('Cleared.'); } };
+ function gExportCsv(){
+ var l=gload(); if(!l.length){ gmsg('List is empty.'); return; }
+ function q(s){ return '"'+String(s==null?'':s).replace(/"/g,'""')+'"'; }
+ var lines=['name,role,market,city,license,phone,website,status,linkedin_search'];
+ l.forEach(function(x){
+ if(x.kind==='category') return;
+ lines.push([q(x.name),q(x.cat),q(x.market||''),q((x.sub||'').split(' · ')[0]),q(x.license_no||''),q(x.phone||''),q(x.website||''),q(GSTL[x.status||0]),q(liUrl(x.terms||x.name))].join(','));
+ if(x.people) x.people.forEach(function(p){ lines.push([q(cap(p.name)),q(x.cat),q(x.market||''),q(cap(p.city||'')),q(p.license_no||''),q(''),q(''),q(GSTL[p.status||0]),q(liUrl(p.name+' '+(x.name||'')))].join(',')); });
+ });
+ var a=document.createElement('a'); a.href=URL.createObjectURL(new Blob([lines.join('\n')],{type:'text/csv'}));
+ a.download='rentv-growth-targets.csv'; a.click();
+ gmsg('Exported '+(lines.length-1)+' rows ✓');
+ }
+ document.getElementById('grailCsv').onclick=gExportCsv;
document.getElementById('grailFilter').oninput=grender;
var gsortEl=document.getElementById('grailSort'); gsortEl.value=localStorage.getItem(GSORT)||'added';
gsortEl.onchange=function(){ localStorage.setItem(GSORT,gsortEl.value); grender(); };
@@ -534,13 +553,13 @@
document.getElementById('fReg').onclick=function(){
if(!GF._registry)return;
if(GF._licRole){ // licensed CRE roles from the realestate DB (title/escrow/contractor/lender/attorney)
- var lrole=GF_LICENSED[GF._licRole], mkt=GF._regMkt||'';
+ var lrole=GF_LICENSED[GF._licRole], mkt=({'Los Angeles':'Greater LA'}[GF._regMkt]||GF._regMkt||'');
gmsg('Loading '+lrole+'…');
fetch('/api/summit/licensed?role='+encodeURIComponent(lrole)+(mkt?('&market='+encodeURIComponent(mkt)):'')+'&limit=200',{credentials:'same-origin'})
.then(function(r){ return r.json(); }).then(function(d){
var l=gload(), seen={}; l.forEach(function(x){ if(x.rid) seen[x.rid]=1; }); var now=Date.now(), added=0;
(d.rows||[]).forEach(function(r){ var rid='L'+r.id; if(seen[rid])return; seen[rid]=1;
- l.push({id:gid(),rid:rid,kind:'contact',cat:GF._licRole,name:cap(r.entity_name),sub:[cap(r.city||''),r.license_type||''].filter(Boolean).join(' · ')+(r.license_no?(' · '+r.license_no):''),terms:r.entity_name+' '+(r.city||'')+' commercial real estate',market:r.market,status:0,added:now}); added++; });
+ l.push({id:gid(),rid:rid,kind:'contact',cat:GF._licRole,name:cap(r.entity_name),sub:[cap(r.city||''),r.license_type||''].filter(Boolean).join(' · ')+(r.license_no?(' · '+r.license_no):''),terms:r.entity_name+' '+(r.city||'')+' commercial real estate',market:r.market,phone:(r.phone||''),website:(r.website||''),license_no:(r.license_no||''),status:0,added:now}); added++; });
gsave(l); grender(); gmsg(added ? ('Loaded '+added+' '+lrole+' ✓') : 'No new records.');
}).catch(function(){ gmsg('realestate unavailable.'); });
return;
← 7a41e57b console: split 'Title & Escrow' facet → Escrow (registry-bac
·
back to Rentv 2026
·
chore: v0.10.0 → v0.11.0 (session close — licensed-CRE conso 8eff89bc →