Join: let chosen positions default to direct placement
The moving link is team-first by design: it routes a new join to whoever needs directs next, so the position whose link was actually clicked earns no entry reward. Measured on #21 that came to 80 joins in seven days and zero entry rewards, while the traffic paying for those joins was the owner's. For a position being deliberately built out, that default is backwards. Any ID listed in the new directDefaultIds config now behaves as ?direct=1 on its own /join/<id> link - including every promo tool, flyer QR and downline-builder entry that resolves through it - without needing the parameter appended. ?direct=0 still forces rotation for a single share, so the team-first behaviour stays available rather than being replaced. Config rather than hard-coded, and editable from the admin settings form, so which positions get this can change without a deploy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -46,7 +46,7 @@ function render(){
|
||||
if(!grantAutoLoaded){grantAutoLoaded=true;if(window.agBoot)window.agBoot();}
|
||||
if(!msgsAutoLoaded){msgsAutoLoaded=true;loadAdminMsgs();}
|
||||
const efi=document.getElementById('emailFromInput');if(efi&&!efi.value)efi.value=state.config.emailFrom||em.from||'';
|
||||
const f=document.getElementById('configForm'),c=state.config;for(const k of ['siteName','programName','bridgeHeadline','bridgeSubheadline','premiumEntryPol','dappReferralBaseUrl','telegramUrl','supportLabel','bemobPostbackUrl','telegramBotToken','telegramChatId','telegramTopicId','teamRootId','teamAlertEmail','ownerAlertEmail'])if(f.elements[k])f.elements[k].value=c[k]??'';f.elements.showSponsorName.checked=!!c.showSponsorName;f.elements.showQueueProgress.checked=!!c.showQueueProgress;
|
||||
const f=document.getElementById('configForm'),c=state.config;for(const k of ['siteName','programName','bridgeHeadline','bridgeSubheadline','premiumEntryPol','dappReferralBaseUrl','telegramUrl','supportLabel','bemobPostbackUrl','telegramBotToken','telegramChatId','telegramTopicId','teamRootId','teamAlertEmail','ownerAlertEmail','directDefaultIds'])if(f.elements[k])f.elements[k].value=c[k]??'';f.elements.showSponsorName.checked=!!c.showSponsorName;f.elements.showQueueProgress.checked=!!c.showQueueProgress;
|
||||
}
|
||||
document.getElementById('loginForm').addEventListener('submit',async e=>{e.preventDefault();const err=document.getElementById('loginError');err.textContent='';try{await api('/api/admin/login',{method:'POST',body:JSON.stringify({password:document.getElementById('password').value})});document.getElementById('password').value='';await loadState()}catch(x){err.textContent=x.message}});
|
||||
document.getElementById('logoutBtn').addEventListener('click',async()=>{await api('/api/admin/logout',{method:'POST'});location.reload()});
|
||||
|
||||
+6
-1
@@ -61,7 +61,12 @@ fetch('/api/public/config').then(function(r){return r.json()}).then(function(c){
|
||||
sponsorId=String(ref); $('sponsorLine').innerHTML='You’ll join <strong>directly under #'+ref+'</strong> — a spillover placement in their team.'; return;
|
||||
}
|
||||
if(ref&&/^\d{1,15}$/.test(ref)){
|
||||
try{ var rm=await (await fetch('/api/public/member?id='+ref)).json(); var t=rm&&rm.joinTarget;
|
||||
try{ var rm=await (await fetch('/api/public/member?id='+ref)).json();
|
||||
// position configured to default to direct, not explicitly overridden
|
||||
if(rm&&rm.directDefault&&qp.get('direct')!=='0'){
|
||||
sponsorId=String(ref); $('sponsorLine').innerHTML='You’ll join <strong>directly under #'+ref+'</strong> — a spillover placement in their team.'; return;
|
||||
}
|
||||
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){}
|
||||
}
|
||||
|
||||
+6
-1
@@ -13,7 +13,11 @@
|
||||
// Direct link (?direct=1): opt out of moving-link rotation — new joins land
|
||||
// directly under THIS position (spillover in their team), instead of routing
|
||||
// to the next-to-qualify member. Default (no flag) = the Team/moving link.
|
||||
const direct=new URLSearchParams(location.search).get('direct')==='1';
|
||||
const _dq=new URLSearchParams(location.search).get('direct');
|
||||
// ?direct=1 forces direct placement, ?direct=0 forces rotation. With
|
||||
// neither, the position's own configured default decides (applied once
|
||||
// the member data arrives, below).
|
||||
let direct=_dq==='1';
|
||||
let joinTargetId=id; // where the entry actually lands after moving-link routing
|
||||
|
||||
function setIds(idStr){
|
||||
@@ -57,6 +61,7 @@
|
||||
// Moving-link routing: the entry lands on whoever the smart link resolves to.
|
||||
// A qualified inviter's link routes to the next-to-qualify in their leg, so
|
||||
// the join builds the team down in order instead of spilling onto the inviter.
|
||||
if(_dq!=='1'&&_dq!=='0'&&d.directDefault) direct=true;
|
||||
const t=direct?{id:id,reason:'direct'}:(d.joinTarget||{id:d.id,referralUrl:d.referralUrl,reason:'self'});
|
||||
joinTargetId=t.id;
|
||||
const jb=document.getElementById('joinBtn');
|
||||
|
||||
Reference in New Issue
Block a user