Coaching Radar: live downline triage in admin + member dashboards
- chain.js getCoachingScan(rootId): classifies everyone below a root into atRisk (POL forming they can't catch - corrected bought-level rule), rollForward (qualified-at-Scintilla with entry rewards covering Ascensus), and oneAway (1/2 directs) - Admin: GET /api/admin/coaching?root= (name-decorated) + "Coaching Radar" panel with tiered who/what-to-say/POL-at-stake rows, auto-loaded - Member dashboards: memberPublic now returns .coach scoped to the member's own leg; new "Coach your team" card shows the same triage so every member coaches their own team - computed live, no snapshots or cron needed - Chatbot canned answer + AI system prompt updated to describe the panel Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -124,6 +124,7 @@
|
||||
renderNextStep(d);
|
||||
renderGens(d);
|
||||
renderPipeline(d);
|
||||
renderCoach(d);
|
||||
renderAlerts(d);
|
||||
renderShare(d);
|
||||
document.getElementById('dLineage').innerHTML=d.uplineChain&&d.uplineChain.length
|
||||
@@ -157,6 +158,23 @@
|
||||
}).join('');
|
||||
el.innerHTML=`<div style="border-top:1px solid var(--line);padding-top:12px"><small style="text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-size:11px">Team depth — members per generation</small><div style="margin-top:8px">${rows}</div><p class="micro" style="margin:8px 0 0">Full generations duplicate: each one can hold twice the last. A generation pays this position at exactly one level — stay qualified and at that level to catch it.</p></div>`;
|
||||
}
|
||||
// "Coach your team" — the same triage the team admin runs, scoped to THIS
|
||||
// position's leg: who below could use a nudge, and exactly what to tell them.
|
||||
function renderCoach(d){
|
||||
const card=document.getElementById('dCoachCard'),el=document.getElementById('dCoach');
|
||||
if(!card||!el)return;
|
||||
const c=d.coach;
|
||||
if(!c||!c.ready||!c.scanned||((c.rollForward||[]).length+(c.atRisk||[]).length+(c.oneAway||[]).length)===0){card.style.display='none';return;}
|
||||
const link=id=>`<a href="/my/${id}" style="color:var(--teal)">#${id}</a>`;
|
||||
const rows=[];
|
||||
(c.rollForward||[]).forEach(r=>rows.push(`<div class="pp-row" style="padding:9px 12px"><div class="pp-icon">💬</div><div class="pp-body">${link(r.id)} is <strong>qualified but still Scintilla</strong> with ${fmt(r.earnedPol)} POL of entry rewards — their Ascensus upgrade (${fmt(r.ascensusCost)} POL) is already covered and catches their team's first payments. Tell them!</div></div>`));
|
||||
(c.atRisk||[]).filter(r=>r.qualified&&r.level>1).forEach(r=>rows.push(`<div class="pp-row" style="padding:9px 12px"><div class="pp-icon">⚠️</div><div class="pp-body">${link(r.id)} (${esc(r.levelName)}) has <strong style="color:var(--gold)">${fmt(r.atRiskPol)} POL forming</strong> below them but needs <strong>${esc(r.neededLevelName)}</strong> to catch it — worth a heads-up before it passes them.</div></div>`));
|
||||
(c.atRisk||[]).filter(r=>!r.qualified).forEach(r=>rows.push(`<div class="pp-row" style="padding:9px 12px"><div class="pp-icon">⏰</div><div class="pp-body">${link(r.id)} has <strong style="color:var(--gold)">${fmt(r.atRiskPol)} POL forming</strong> below but isn't qualified yet (${r.directCount}/2) — help them find their ${r.directCount===1?'last direct':'2 directs'}.</div></div>`));
|
||||
(c.oneAway||[]).forEach(r=>rows.push(`<div class="pp-row" style="padding:9px 12px"><div class="pp-icon">🎯</div><div class="pp-body">${link(r.id)} is <strong>one direct away</strong> from qualifying — introduce them to one good person and their whole position activates.</div></div>`));
|
||||
if(!rows.length){card.style.display='none';return;}
|
||||
el.innerHTML=rows.slice(0,8).join('')+`<p class="micro" style="margin:10px 0 0">Why this matters to YOU: every upgrade below you either pays your position directly or builds the depth that will. Helping them is not charity — it's your pipeline.</p>`;
|
||||
card.style.display='';
|
||||
}
|
||||
// "My Next Step" — the single clearest action + the level ladder + a funded
|
||||
// badge (server tells us funded true/false; it never sends the raw balance).
|
||||
function renderNextStep(d){
|
||||
|
||||
Reference in New Issue
Block a user