[object Object]

← back to Commercialrealestate

CRCP: 'Pocket listing' badge for off-market rows with no contact at all (Steve 2026-08-19)

95ff71b91f696005caf41501164ba00231fdd1de · 2026-08-19 11:16:49 -0700 · Steve Abrams

- isPocket(a) = no agent name + no phone + no email + no firm/firm-site -> show 🔒 Pocket listing badge instead of 'no agent on file' (which read like missing data). Conservative: only 40/4095 rows qualify (genuinely anonymous/off-market); rows with any firm/name/contact are unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 95ff71b91f696005caf41501164ba00231fdd1de
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 19 11:16:49 2026 -0700

    CRCP: 'Pocket listing' badge for off-market rows with no contact at all (Steve 2026-08-19)
    
    - isPocket(a) = no agent name + no phone + no email + no firm/firm-site -> show 🔒 Pocket listing badge instead of 'no agent on file' (which read like missing data). Conservative: only 40/4095 rows qualify (genuinely anonymous/off-market); rows with any firm/name/contact are unaffected.
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 public/index.html | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/public/index.html b/public/index.html
index f7b9ff0..e4d086d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -224,6 +224,7 @@
   .agentcell .ain:hover { color:var(--blue); }
   .ain a { color:var(--blue); text-decoration:none; } .ain a:hover { text-decoration:underline; }
   .tierb { font-size:9px; text-transform:uppercase; letter-spacing:.4px; color:var(--mut); border:1px solid var(--line); border-radius:4px; padding:0 4px; vertical-align:middle; }
+  .pocketbadge { font-size:11px; font-weight:600; color:var(--gold,#d29922); background:rgba(210,153,34,.12); border:1px solid rgba(210,153,34,.4); border-radius:5px; padding:1px 7px; white-space:nowrap; }
   .agentcell .chiprow:empty { display:none; }
   .agentcell .achip { display:inline-block; font-size:10px; color:var(--mut); background:var(--card); border:1px solid var(--line); border-radius:10px; padding:1px 6px; margin-right:4px; }
   .agentcell .achip.done { color:#3fb950; border-color:#264f2e; }
@@ -982,7 +983,7 @@ function expandBody(p){
   if(firm&&firm!=='Unknown') deep.push(`<button data-firmfilter="${esc(firm).replace(/"/g,'&quot;')}" title="Show only ${esc(firm)} listings">▦ More from ${esc(firm)}</button>`);
   // Agent summary + notes preview. Full editing (info, notes, letters, draft) lives in the inline
   // agent window that ✎ Open launches — no external search, no new tabs.
-  const summary=`<div class="crm-summary">${a.name?`<a class="aname" href="/agent.html?name=${encodeURIComponent(a.name)}" target="_blank" rel="noopener noreferrer" title="Open this agent's own page — current & past listings">${esc(a.name)} ↗</a> `:'<span class="amut">no agent on file — add via ✎ Open</span> '}${contactBits(a)}`
+  const summary=`<div class="crm-summary">${a.name?`<a class="aname" href="/agent.html?name=${encodeURIComponent(a.name)}" target="_blank" rel="noopener noreferrer" title="Open this agent's own page — current & past listings">${esc(a.name)} ↗</a> `:(isPocket(a)?pocketBadge+' ':'<span class="amut">no agent on file — add via ✎ Open</span> ')}${contactBits(a)}`
     +`${a.contacted_at?`<span class="achip done">contacted ${fmtWhen(a.contacted_at)}</span>`:''}${a.letters.length?`<span class="achip">✎ ${a.letters.length} saved</span>`:''}</div>`
     +(a.notes?`<div class="crm-note">🗒 ${esc(a.notes)}</div>`:'');
   return `<div class="src">${deep.join(' ')}</div>`
@@ -1212,6 +1213,11 @@ function listingLinkBits(p, firm){
   }
   return bits;
 }
+// A listing with NO contact of any kind (no agent name, phone, email, or firm site) is an off-market /
+// POCKET listing — the broker deliberately isn't published. Show that honestly instead of "no agent on
+// file" (which reads like missing data). Steve 2026-08-19: "show the word pocket listing if appropriate."
+function isPocket(a){ return !a.name && !a.phone && !a.email && !a.firmWebsite && !a.firm; }
+const pocketBadge = `<span class="pocketbadge" title="Off-market / pocket listing — the broker isn't publicly listed for this property">🔒 Pocket listing</span>`;
 // Firm cell — clicking filters the grid to that firm IN-APP (no external link).
 function firmCell(p){ const n=firmLabel(p); if(!n||n==='Unknown') return esc(n||'—');
   return `<span class="flink" data-firmfilter="${esc(n).replace(/"/g,'&quot;')}" title="Show only ${esc(n)} listings">${esc(n)}</span>`; }
@@ -1234,7 +1240,7 @@ function contactBits(a){
 // The Agent · contact column cell: name + copyable phone/email + Open/Mark buttons + chips.
 function agentContactCell(p){
   const a=agentInfo(p);
-  const nm=a.name?`<a class="aname" href="/agent.html?name=${encodeURIComponent(a.name)}" target="_blank" rel="noopener noreferrer" title="Open this agent's own page — current & past listings">${esc(a.name)} ↗</a>`:`<span class="amut">no agent on file</span>`;
+  const nm=a.name?`<a class="aname" href="/agent.html?name=${encodeURIComponent(a.name)}" target="_blank" rel="noopener noreferrer" title="Open this agent's own page — current & past listings">${esc(a.name)} ↗</a>`:(isPocket(a)?pocketBadge:`<span class="amut">no agent on file</span>`);
   const contacted=a.contacted_at?`<span class="achip done" title="Marked contacted ${esc(a.contacted_at)}">✓ ${fmtWhen(a.contacted_at)}</span>`:'';
   const lc=a.letters.length?`<span class="achip" title="${a.letters.length} saved letter(s)">✎ ${a.letters.length}</span>`:'';
   const nt=a.notes?`<span class="achip" title="Has notes">🗒 notes</span>`:'';
@@ -1337,7 +1343,7 @@ function card(p){
 // contact modal + mark-contacted as the list rows. Compact: name/phone/email + chips + buttons.
 function cardAgentBlock(p){
   const a=agentInfo(p), id=p.id;
-  const nm=a.name?`<a class="aname" href="/agent.html?name=${encodeURIComponent(a.name)}" target="_blank" rel="noopener noreferrer" title="Open this agent's own page — current & past listings">${esc(a.name)} ↗</a>`:`<span class="amut">no agent on file</span>`;
+  const nm=a.name?`<a class="aname" href="/agent.html?name=${encodeURIComponent(a.name)}" target="_blank" rel="noopener noreferrer" title="Open this agent's own page — current & past listings">${esc(a.name)} ↗</a>`:(isPocket(a)?pocketBadge:`<span class="amut">no agent on file</span>`);
   const chips=`${a.contacted_at?`<span class="achip done" title="Contacted ${esc(a.contacted_at)}">✓ ${fmtWhen(a.contacted_at)}</span>`:''}${a.letters.length?`<span class="achip" title="${a.letters.length} saved letter(s)">✎ ${a.letters.length}</span>`:''}${a.notes?`<span class="achip" title="Has notes">🗒 notes</span>`:''}`;
   return `<div class="cardagent" id="cardagent-${id}">`
     +`<div class="ca-top">🧑‍💼 ${nm} ${chips}</div>`

← cf0bd41 CRCP: Frank onload 4-unit multifamily default filter + non-w  ·  back to Commercialrealestate  ·  auto-data-snapshot: 2026-08-19T11:14:55 (3 data files) — dat 3fdbc0b →