Rebuild /my as a two-purpose tabbed page
Turns the member page into a persistent, tabbed dual-purpose page: - Persistent context strip: "Member #X's RM Circle page · Verified · Qualified" - Tab 1 "The Team Build": pitch for promoted-link visitors — hook, embedded overview video, 3 steps, live proof (member's real on-chain numbers), Join under #X CTA. Persistent (replaces the dismissible cold-intro banner). - Tab 2 "Position Dashboard": the full dashboard as-is (facts, plan, matrix, pipeline, alerts, share, payments, lineage). - Default: cold visitor opens on the pitch, the member opens on their dashboard; both always one tap apart. Retired the coldIntro banner + its handler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+30
-13
@@ -4,6 +4,32 @@
|
||||
const date=ts=>ts?new Date(ts*1000).toLocaleDateString(undefined,{year:'numeric',month:'short',day:'numeric'}):'—';
|
||||
const prompt=document.getElementById('idPrompt'),dash=document.getElementById('dash');
|
||||
|
||||
// Two-purpose page: a "Team Build" pitch tab (for cold visitors who clicked a
|
||||
// promoted link) and the "Position Dashboard" tab. Persistent — the pitch is
|
||||
// always one tap away, never dismissed.
|
||||
function setTab(name){
|
||||
document.querySelectorAll('.mp-tab').forEach(t=>t.classList.toggle('on',t.dataset.tab===name));
|
||||
const tp=document.getElementById('tabPitch'),td=document.getElementById('tabDash');
|
||||
if(tp)tp.classList.toggle('on',name==='pitch');
|
||||
if(td)td.classList.toggle('on',name==='dash');
|
||||
}
|
||||
document.querySelectorAll('.mp-tab').forEach(t=>t.addEventListener('click',()=>{setTab(t.dataset.tab);window.scrollTo({top:0,behavior:'smooth'});}));
|
||||
function renderPitch(d){
|
||||
const set=(id,v)=>{const el=document.getElementById(id);if(el)el.textContent=v;};
|
||||
set('pInvId','#'+d.id); set('pProofId','#'+d.id);
|
||||
set('pEarned',Math.round(d.totalEarnedPol||0).toLocaleString());
|
||||
set('pTeam',(d.subtree&&d.subtree.downCount!=null)?String(d.subtree.downCount):'—');
|
||||
set('pLevel',d.levelName||'—');
|
||||
const jb=document.getElementById('pJoinBtn'); if(jb){jb.href='/join/'+d.id;jb.textContent='Join under #'+d.id+' →';}
|
||||
const pp=document.getElementById('pPayouts');
|
||||
if(pp){
|
||||
const inc=(d.income||[]).slice(0,3);
|
||||
pp.innerHTML=inc.length
|
||||
? '<div class="pitch-l-lab">Real payouts landing on this team — verifiable on Polygonscan</div>'+inc.map(p=>`<div class="pitch-l-row"><span>${esc(p.desc)} — from #${p.fromId}</span><b>+${fmt(p.pol)} POL</b></div>`).join('')
|
||||
: '';
|
||||
}
|
||||
}
|
||||
|
||||
function pathId(){const m=location.pathname.match(/^\/my\/(\d+)$/);if(m)return m[1];const q=new URLSearchParams(location.search).get('id');if(q&&/^\d+$/.test(q))return q;try{return localStorage.getItem('ctb.myId')||''}catch(e){return ''}}
|
||||
|
||||
const treeUI={byId:{},parent:{},homeId:0,rootId:0,mode:'pyramid'};
|
||||
@@ -58,17 +84,10 @@
|
||||
});
|
||||
function render(d){
|
||||
prompt.classList.add('hidden');dash.classList.remove('hidden');
|
||||
// cold-visitor context banner: shown unless this looks like the member's own
|
||||
// dashboard (their stored ID matches) or they dismissed it this session
|
||||
try{
|
||||
const intro=document.getElementById('coldIntro');
|
||||
const seenBefore=d._priorId===String(d.id); // they've viewed this position before (likely their own)
|
||||
const dismissed=sessionStorage.getItem('ctb.introDismissed')==='1';
|
||||
if(intro){
|
||||
if(!seenBefore&&!dismissed){intro.classList.remove('hidden');const cij=document.getElementById('coldIntroJoin');cij.href='/join/'+d.id;cij.textContent='See how to join under #'+d.id+' →';}
|
||||
else intro.classList.add('hidden');
|
||||
}
|
||||
}catch(e){}
|
||||
// default tab: a cold visitor (hasn't viewed this ID before) opens on the
|
||||
// Team Build pitch; the member (their own saved ID) opens on their dashboard.
|
||||
renderPitch(d);
|
||||
try{ setTab(d._priorId===String(d.id)?'dash':'pitch'); }catch(e){ setTab('pitch'); }
|
||||
document.getElementById('dTitle').textContent='#'+d.id;
|
||||
const qb=document.getElementById('dQualified');
|
||||
if(qb)qb.outerHTML=d.directCount>=2
|
||||
@@ -298,8 +317,6 @@
|
||||
document.getElementById('idError').textContent=x.message;
|
||||
}
|
||||
}
|
||||
const introX=document.getElementById('coldIntroClose');
|
||||
if(introX)introX.addEventListener('click',()=>{try{sessionStorage.setItem('ctb.introDismissed','1')}catch(e){};document.getElementById('coldIntro').classList.add('hidden')});
|
||||
document.getElementById('dJoinForm').addEventListener('submit',async e=>{
|
||||
e.preventDefault();
|
||||
const form=e.currentTarget,msg=document.getElementById('dJoinMsg');
|
||||
|
||||
Reference in New Issue
Block a user