Wire the join funnel to the live /join-now self-enroll page

/join-now now honors ?ref=<id> (resolves that member's moving-link joinTarget;
falls back to the global rotation sponsor). Repointed: /start 'Join With Current
Sponsor' -> /join-now; /my pitch buttons -> /join-now?ref=<id>; invite page
/join/<id> join button -> /join-now?ref=<id>; bare /join redirect -> /join-now.
'Get Started' learn CTAs still go to /start for onboarding. When the flag is off,
/join-now gracefully redirects to /start, so the wiring is safe either way.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-18 07:37:19 -05:00
parent e14c541e5e
commit 629df6336c
6 changed files with 15 additions and 8 deletions
+9 -2
View File
@@ -44,9 +44,16 @@
async function loadSponsor(){
try{
var r=await fetch('/api/public/current-sponsor'); var j=await r.json(); var sp=j&&j.sponsor;
// personal invite: ?ref=<id> -> place in that member's leg via the site's moving-link joinTarget
var ref=new URLSearchParams(location.search).get('ref');
if(ref&&/^\d{1,15}$/.test(ref)){
try{ var rm=await (await fetch('/api/public/member?id='+ref)).json(); var t=rm&&rm.joinTarget;
if(t&&t.id){ sponsorId=String(t.id); $('sponsorLine').innerHTML='You’ll join under <strong>#'+t.id+'</strong>'+(String(t.id)!==String(ref)?' — the next open spot in #'+ref+'’s team':'')+'.'; return; }
}catch(e){}
}
var j=await (await fetch('/api/public/current-sponsor')).json(); var sp=j&&j.sponsor;
if(sp&&sp.id){ sponsorId=String(sp.id); $('sponsorLine').innerHTML='You’ll join the team under <strong>#'+sp.id+(sp.name?' ('+sp.name+')':'')+'</strong> — the current team placement.'; }
else { $('sponsorLine').textContent='Loading the current team placement…'; }
else $('sponsorLine').textContent='Loading the current team placement…';
}catch(e){ $('sponsorLine').textContent='Could not load the current sponsor — please refresh.'; }
}
+1 -1
View File
@@ -56,7 +56,7 @@
const t=d.joinTarget||{id:d.id,referralUrl:d.referralUrl,reason:'self'};
joinTargetId=t.id;
const jb=document.getElementById('joinBtn');
if(t.referralUrl)jb.href=t.referralUrl;
jb.href='/join-now?ref='+id; jb.removeAttribute('target'); // self-enroll page, placed in this leg
// the join CTA + "join under" header + dApp-sponsor mentions reflect the
// ACTUAL sponsor the entry lands on, not the inviter (only the top
// "invited by #X" line keeps the inviter's id)
+2 -2
View File
@@ -21,8 +21,8 @@
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 hj=document.getElementById('pHeroJoin'); if(hj)hj.href='/join/'+d.id;
const jb=document.getElementById('pJoinBtn'); if(jb){jb.href='/join-now?ref='+d.id;jb.textContent='Join under #'+d.id+' →';}
const hj=document.getElementById('pHeroJoin'); if(hj)hj.href='/join-now?ref='+d.id;
const pp=document.getElementById('pPayouts');
if(pp){
const inc=(d.income||[]).slice(0,3);
+1 -1
View File
@@ -5,7 +5,7 @@
<body>
<header class="wrap nav"><a class="brand" href="/"><div class="brand-mark">RM</div><span><span id="brandName">RM Circle</span><small>Getting Started</small></span></a><div class="nav-actions"><a class="btn btn-secondary" href="/">← Strategy</a><a class="btn btn-secondary" href="/training">Training</a></div></header>
<main class="sponsor-shell"><div class="wrap"><div class="section-head"><div class="eyebrow">Current placement</div><h1 style="font-size:clamp(34px,5vw,54px);margin:8px 0 10px">Use the sponsor shown on <span class="gold">this page.</span></h1><p>Team placements rotate as positions become qualified. Do not use an old screenshot or saved referral link.</p></div>
<div class="sponsor-grid"><aside class="sponsor-card"><span class="live-badge"><span class="dot"></span> Current team sponsor</span><div class="sponsor-id" id="sponsorId">—</div><div class="sponsor-name" id="sponsorName">Loading current placement…</div><div id="progressArea"><div style="display:flex;justify-content:space-between;color:var(--muted);font-size:13px"><span>Qualification progress</span><strong id="progressText">0 / 2</strong></div><div class="progress-line"><span id="progressBar" style="width:0%"></span></div></div><div class="facts"><div class="fact"><small>Program</small><strong>Premium</strong></div><div class="fact"><small>Entry</small><strong><span id="entryPol">362</span> POL</strong></div><div class="fact"><small>Network</small><strong>Polygon</strong></div><div class="fact"><small>Gas token</small><strong>POL</strong></div></div><a id="joinButton" class="btn btn-primary" style="width:100%" href="#" target="_blank" rel="noopener noreferrer">Join With Current Sponsor →</a><button id="copyButton" class="btn btn-secondary" style="width:100%;margin-top:9px">Copy Sponsor ID</button><p class="micro" id="queueText" style="text-align:center"></p></aside>
<div class="sponsor-grid"><aside class="sponsor-card"><span class="live-badge"><span class="dot"></span> Current team sponsor</span><div class="sponsor-id" id="sponsorId">—</div><div class="sponsor-name" id="sponsorName">Loading current placement…</div><div id="progressArea"><div style="display:flex;justify-content:space-between;color:var(--muted);font-size:13px"><span>Qualification progress</span><strong id="progressText">0 / 2</strong></div><div class="progress-line"><span id="progressBar" style="width:0%"></span></div></div><div class="facts"><div class="fact"><small>Program</small><strong>Premium</strong></div><div class="fact"><small>Entry</small><strong><span id="entryPol">362</span> POL</strong></div><div class="fact"><small>Network</small><strong>Polygon</strong></div><div class="fact"><small>Gas token</small><strong>POL</strong></div></div><a id="joinButton" class="btn btn-primary" style="width:100%" href="/join-now">Join With Current Sponsor →</a><button id="copyButton" class="btn btn-secondary" style="width:100%;margin-top:9px">Copy Sponsor ID</button><p class="micro" id="queueText" style="text-align:center"></p></aside>
<section><div class="callout" style="margin-bottom:16px"><strong>First time?</strong> <a href="/training" style="color:var(--teal)">Watch the four training videos</a> — how the build works, creating your MetaMask wallet, funding it, and buying your position.</div><div class="instruction-list"><article class="instruction"><div class="num">1</div><div><h3>Install or open MetaMask</h3><p>Use the official MetaMask website or your device's official app store. Never install a wallet from a link sent by a stranger.</p><div style="margin-top:10px"><a class="btn btn-secondary btn-sm" href="https://metamask.io/" target="_blank" rel="noopener noreferrer">Official MetaMask Site ↗</a></div></div></article>
<article class="instruction"><div class="num">2</div><div><h3>Use Polygon Mainnet</h3><p>In MetaMask, select Polygon. Polygon Mainnet uses chain ID <strong>137</strong>, and POL is the native gas token.</p></div></article>
<article class="instruction"><div class="num">3</div><div><h3>Fund your wallet with POL</h3><p>Premium entry is <strong><span id="entryPol2">362</span> POL</strong>. Keep a small additional POL balance available for network gas. POL's USD value changes with the market.</p></div></article>
+1 -1
View File
@@ -13,7 +13,7 @@ async function load(){
document.getElementById('progressBar').style.width=`${Math.min(100,(currentSponsor.directs/2)*100)}%`;
document.getElementById('entryPol').textContent=c.premiumEntryPol;
document.getElementById('entryPol2').textContent=c.premiumEntryPol;
document.getElementById('joinButton').href=currentSponsor.referralUrl;
document.getElementById('joinButton').href='/join-now';
document.getElementById('queueText').textContent=c.showQueueProgress?`${s.waitingCount} team placement${s.waitingCount===1?'':'s'} waiting behind the current sponsor.`:'';
document.getElementById('supportBox').textContent=c.supportLabel||'Contact your team sponsor if you need help before joining.';
if(c.telegramUrl){const w=document.getElementById('supportLinkWrap'),a=document.getElementById('supportLink');a.href=c.telegramUrl;w.classList.remove('hidden')}