feat(search): only surface Connect users; clear "not on Connect"/"not found" (batch67)

Contact search no longer lists BizGaze directory people who aren't on Connect as
addable rows (they can't be messaged). It shows only people actually on Connect;
if a search matches nobody on Connect it shows either "Not on Connect" (they exist
on BizGaze but haven't signed in) or "Contact not found".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 15:36:18 +05:30
parent aa4bb2902d
commit 9b86def921
+21 -6
View File
@@ -120,6 +120,10 @@
.dir-row .dr-main{display:flex;flex-direction:column;min-width:0;flex:1;}
.dir-row .dr-sub{font-size:.74rem;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.dir-row .dr-tag{font-size:.62rem;font-weight:700;color:#92600b;background:#fff3cd;border-radius:99px;padding:.1rem .4rem;flex:0 0 auto;}
.dir-empty{display:flex;gap:.55rem;align-items:flex-start;margin:.5rem .9rem;padding:.6rem .7rem;background:#f6f8fc;border:1px solid var(--line);border-radius:10px;color:var(--muted);}
.dir-empty svg{flex:0 0 auto;margin-top:.05rem;color:var(--blue);}
.dir-empty b{display:block;font-size:.82rem;color:var(--ink);margin-bottom:.1rem;}
.dir-empty span{font-size:.74rem;line-height:1.35;}
/* Chat-list header (now the app's top area — the blue bar is gone). */
.side-head{padding:.85rem 1rem .75rem;border-bottom:1px solid var(--line);background:linear-gradient(180deg,#f3f7fd 0%,var(--card) 100%);}
.side-title{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.7rem;}
@@ -856,7 +860,7 @@
<body>
<script src="/icons.js?v=5"></script>
<script src="https://cdn.jsdelivr.net/npm/@twemoji/api@15.1.0/dist/twemoji.min.js" crossorigin="anonymous"></script>
<script>window.__BUILD='2026-07-10-batch66';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
<script>window.__BUILD='2026-07-10-batch67';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
// Render modern (Twemoji) emojis in place of the OS's flat ones. No-op if the CDN didn't load
// (emojis stay as plain Unicode). (#5)
function twemojify(el){ try{ if(el && window.twemoji) window.twemoji.parse(el, { folder:'svg', ext:'.svg' }); }catch(_){} }</script>
@@ -1413,11 +1417,22 @@ function queryDirectory(q){
if(seq!==_dirSeq) return; // a newer search superseded this one
const box=document.getElementById('dirResults'); if(!box) return;
const haveEmail=new Set(CONTACTS.map(c=>(c.email||'').toLowerCase()).filter(Boolean));
const ext=(Array.isArray(list)?list:[]).filter(p=>!(p.email&&haveEmail.has(p.email.toLowerCase()))); // hide dups of team contacts
if(!ext.length){ box.innerHTML=''; return; }
box.innerHTML='<div class="side-sec">On BizGaze</div>'+ext.map((p,i)=>{ const sub=[p.org,p.phone].filter(Boolean).join(' · ');
return '<div class="dir-row'+(p.onConnect?'':' ext')+'" data-i="'+i+'"><span class="mini-av" style="background:'+avColor(p.name||'?')+'">'+pEsc(initials(p.name||'?'))+'</span><span class="dr-main"><span class="cr-name">'+pEsc(p.name||p.email||'Unknown')+'</span>'+(sub?'<span class="dr-sub">'+pEsc(sub)+'</span>':'')+'</span>'+(p.onConnect?'':'<span class="dr-tag">Not on Connect</span>')+'</div>'; }).join('');
box.querySelectorAll('.dir-row').forEach(row=>{ const p=ext[+row.dataset.i]; row.onclick=()=>{ if(p.onConnect&&p.connectId) selectChat('dm', p.connectId); else toast(pEsc(p.name||'This person')+' is on BizGaze but hasnt joined Connect yet — theyll be reachable once they sign in.'); }; });
const all=Array.isArray(list)?list:[];
// Only people actually ON Connect can be messaged — show just those (deduped against team contacts).
// Everyone else (on BizGaze but not signed into Connect) is NOT listed as addable; instead we show a
// clear "not on Connect" / "not found" state so the user isn't confused by un-chattable rows.
const onc=all.filter(p=>p.onConnect && p.connectId && !(p.email&&haveEmail.has(p.email.toLowerCase())));
const localHit=box.parentElement && box.parentElement.querySelector('.chat-row, .contact-row');
if(onc.length){
box.innerHTML='<div class="side-sec">On Connect</div>'+onc.map((p,i)=>{ const sub=[p.org,p.phone].filter(Boolean).join(' · ');
return '<div class="dir-row" data-i="'+i+'"><span class="mini-av" style="background:'+avColor(p.name||'?')+'">'+pEsc(initials(p.name||'?'))+'</span><span class="dr-main"><span class="cr-name">'+pEsc(p.name||p.email||'Unknown')+'</span>'+(sub?'<span class="dr-sub">'+pEsc(sub)+'</span>':'')+'</span></div>'; }).join('');
box.querySelectorAll('.dir-row').forEach(row=>{ const p=onc[+row.dataset.i]; row.onclick=()=>selectChat('dm', p.connectId); });
} else if(!localHit){
// Nothing on Connect matched. Distinguish "exists on BizGaze but not on Connect" from "not found".
box.innerHTML = all.length
? '<div class="dir-empty">'+ic('info',16)+'<div><b>Not on Connect</b><span>Matching people are on BizGaze but havent joined Connect yet, so they cant be messaged.</span></div></div>'
: '<div class="dir-empty">'+ic('search',16)+'<div><b>Contact not found</b><span>No Connect user matches “'+pEsc(q)+'”.</span></div></div>';
} else box.innerHTML='';
}, 280);
}
function updateRailUnread(){