Require name or Telegram handle on member ID submission
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
||||
<section id="adminView" class="admin hidden"><div class="admin-top"><div><div class="eyebrow">Sponsor router</div><h1>Crypto Team Build Admin</h1></div><div class="nav-actions"><a class="btn btn-secondary" href="/start" target="_blank">View Live Page ↗</a><button id="logoutBtn" class="btn btn-secondary">Log out</button></div></div>
|
||||
<div class="admin-grid"><div class="stack"><div class="table-card"><div style="display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:12px"><div><h2 style="margin:0">Sponsor Queue</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">Mark a sponsor qualified to automatically activate the next waiting position.</p></div></div><div class="table-wrap"><table class="table"><thead><tr><th>Order</th><th>Sponsor</th><th>Parent</th><th>Directs</th><th>Level</th><th>Status</th><th>Clicks</th><th>Actions</th></tr></thead><tbody id="sponsorRows"></tbody></table></div></div>
|
||||
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">Traffic & Conversions</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">First-touch source per visitor session (referring domain or utm_source). Funnel: bridge page → start page → join click.</p></div><div id="funnelStats" class="funnel"></div><div class="table-wrap"><table class="table"><thead><tr><th>Source</th><th>Bridge views</th><th>Start views</th><th>Training views</th><th>Join clicks</th><th>Start → Join</th></tr></thead><tbody id="trafficRows"></tbody></table></div></div>
|
||||
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">Member ID Submissions</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">New members who confirmed their purchase on the start page. Each one was posted to your Hermes Telegram chat — add them to the rotation.</p></div><div class="table-wrap"><table class="table"><thead><tr><th>When</th><th>New ID</th><th>Joined under</th><th>Source</th></tr></thead><tbody id="submissionRows"></tbody></table></div></div></div>
|
||||
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">Member ID Submissions</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">New members who confirmed their purchase on the start page. Each one was posted to your Hermes Telegram chat — add them to the rotation.</p></div><div class="table-wrap"><table class="table"><thead><tr><th>When</th><th>Name / Handle</th><th>New ID</th><th>Joined under</th><th>Source</th></tr></thead><tbody id="submissionRows"></tbody></table></div></div></div>
|
||||
<div class="stack"><div class="table-card"><h2 style="margin-top:0">Add Sponsor</h2><form id="addSponsorForm"><div class="form-grid"><div class="field"><label>ID</label><input name="id" class="input" required></div><div class="field"><label>Name</label><input name="name" class="input" required></div><div class="field"><label>Parent ID</label><input name="parentId" class="input"></div><div class="field"><label>Level</label><select name="level" class="select"><option>Scintilla</option><option>Ascensus</option><option>Fabrica</option><option>Culmen</option><option>Apex</option><option>Fastigium</option><option>Vertex</option><option>Corona</option></select></div></div><div class="field"><label>Notes</label><input name="notes" class="input"></div><button class="btn btn-teal" style="width:100%">Add to Queue</button></form></div>
|
||||
<div class="table-card"><h2 style="margin-top:0">AI Chat</h2><p style="color:var(--muted);font-size:13px;margin:4px 0 12px">Paste an OpenRouter API key to switch the help chat from canned answers to AI (<span id="aiModel"></span>). Clear it to switch back.</p><div id="aiStatus" class="micro" style="margin-bottom:10px"></div><form id="aiKeyForm"><div class="field"><label>OpenRouter API key</label><input name="key" class="input" type="password" placeholder="sk-or-v1-…" autocomplete="off"></div><button class="btn btn-teal" style="width:100%">Save Key</button><button type="button" id="aiKeyClear" class="btn btn-secondary" style="width:100%;margin-top:8px">Clear Key (use canned answers)</button></form></div>
|
||||
<div class="table-card"><h2 style="margin-top:0">Public Page Settings</h2><form id="configForm"><div class="field"><label>Site name</label><input name="siteName" class="input"></div><div class="field"><label>Program name</label><input name="programName" class="input"></div><div class="field"><label>Bridge headline</label><input name="bridgeHeadline" class="input"></div><div class="field"><label>Bridge subheadline</label><textarea name="bridgeSubheadline" class="input" rows="3"></textarea></div><div class="field"><label>Premium entry (POL)</label><input name="premiumEntryPol" class="input" type="number"></div><div class="field"><label>RM dApp referral base URL</label><input name="dappReferralBaseUrl" class="input" placeholder="https://app.thermcircle.com?ref="></div><div class="field"><label>BeMob postback URL (paid traffic)</label><input name="bemobPostbackUrl" class="input" placeholder="https://xxxxx.bemobtrcks.com/postback"></div><div class="field"><label>Telegram bot token (Hermes notifications)</label><input name="telegramBotToken" class="input" type="password" autocomplete="off" placeholder="123456:ABC…"></div><div class="field"><label>Telegram chat ID (group or user)</label><input name="telegramChatId" class="input" placeholder="-1001234567890"></div><div class="field"><label>Telegram topic ID (optional, for forum groups)</label><input name="telegramTopicId" class="input" placeholder="55"></div><div class="field"><label>Telegram/support URL (optional)</label><input name="telegramUrl" class="input"></div><div class="field"><label>Support message</label><textarea name="supportLabel" class="input" rows="3"></textarea></div><label style="text-transform:none;letter-spacing:0;margin:10px 0"><input type="checkbox" name="showSponsorName"> Show sponsor name publicly</label><label style="text-transform:none;letter-spacing:0;margin:10px 0"><input type="checkbox" name="showQueueProgress"> Show number waiting in queue</label><button class="btn btn-primary" style="width:100%;margin-top:8px">Save Settings</button></form></div></div></div></section>
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ function renderAnalytics(){
|
||||
(tot.purchase?`<div class="fact"><small>Confirmed joins</small><strong>${tot.purchase}</strong></div>`:'')+
|
||||
(tot.postback?`<div class="fact"><small>BeMob postbacks</small><strong>${tot.postback}</strong></div>`:'');
|
||||
const subs=state.submissions||[];
|
||||
document.getElementById('submissionRows').innerHTML=subs.map(s=>`<tr><td>${esc((s.ts||'').replace('T',' ').slice(0,16))}</td><td><strong>${esc(s.newId)}</strong></td><td>ID ${esc(s.sponsorId)}</td><td>${esc(s.source)}</td></tr>`).join('')||'<tr><td colspan="4" class="empty">No submissions yet.</td></tr>';
|
||||
document.getElementById('submissionRows').innerHTML=subs.map(s=>`<tr><td>${esc((s.ts||'').replace('T',' ').slice(0,16))}</td><td>${esc(s.memberName||'—')}</td><td><strong>${esc(s.newId)}</strong></td><td>ID ${esc(s.sponsorId)}</td><td>${esc(s.source)}</td></tr>`).join('')||'<tr><td colspan="5" class="empty">No submissions yet.</td></tr>';
|
||||
document.getElementById('trafficRows').innerHTML=list.map(r=>`<tr><td><strong>${esc(r.name)}</strong></td><td>${r.bridge}</td><td>${r.start}</td><td>${r.training}</td><td>${r.click}</td><td>${pct(r.click,r.start)}</td></tr>`).join('')||'<tr><td colspan="6" class="empty">No traffic recorded yet.</td></tr>';
|
||||
}
|
||||
function esc(s){return String(s??'').replace(/[&<>'"]/g,c=>({'&':'&','<':'<','>':'>',"'":''','"':'"'}[c]))}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
<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>
|
||||
<article class="instruction"><div class="num">4</div><div><h3>Use the current team sponsor</h3><p>Confirm that the sponsor ID shown by the RM Circle dApp matches <strong>ID <span id="sponsorIdInline">—</span></strong> before completing the transaction.</p></div></article>
|
||||
<article class="instruction"><div class="num">5</div><div><h3>Select Premium and review the transaction</h3><p>Read the wallet transaction before signing. Never share your Secret Recovery Phrase or seed words with this site, a sponsor, or a dApp.</p></div></article>
|
||||
<article class="instruction" style="border-color:var(--gold);background:rgba(243,190,67,.05)"><div class="num" style="background:var(--gold);color:#071421;border-color:var(--gold)">6</div><div><h3>Submit your NEW RM Circle ID here</h3><p>After your purchase confirms, the RM Circle dApp shows your <strong>new member ID</strong>. Type it below and hit submit — this tells the team you're in, maps your placement, and puts you in line for the rotation that gets <strong>your</strong> 2.</p><form id="idSubmitForm" style="display:flex;gap:8px;margin-top:12px;flex-wrap:wrap"><input name="newId" class="input" inputmode="numeric" pattern="[0-9]{1,10}" maxlength="10" placeholder="Your NEW RM Circle ID (numbers only)" required style="flex:1;min-width:200px"><button class="btn btn-primary">Submit My ID →</button></form><div id="idSubmitMsg" style="margin-top:10px;font-size:14px"></div></div></article></div>
|
||||
<article class="instruction" style="border-color:var(--gold);background:rgba(243,190,67,.05)"><div class="num" style="background:var(--gold);color:#071421;border-color:var(--gold)">6</div><div><h3>Submit your NEW RM Circle ID here</h3><p>After your purchase confirms, the RM Circle dApp shows your <strong>new member ID</strong>. Type it below and hit submit — this tells the team you're in, maps your placement, and puts you in line for the rotation that gets <strong>your</strong> 2.</p><form id="idSubmitForm" style="display:grid;gap:8px;margin-top:12px"><input name="newId" class="input" inputmode="numeric" pattern="[0-9]{1,10}" maxlength="10" placeholder="Your NEW RM Circle ID (numbers only)" required><input name="memberName" class="input" maxlength="60" placeholder="Your name or Telegram @handle (so the team can reach you)" required><button class="btn btn-primary">Submit My ID →</button></form><div id="idSubmitMsg" style="margin-top:10px;font-size:14px"></div></div></article></div>
|
||||
<div class="callout" style="margin-top:16px"><strong>What happens next:</strong> get exactly 2 directs, retire your qualified referral link, help your 2 get their 2, and upgrade with earned POL when practical. The goal is depth and duplication—not endless directs on one link.</div>
|
||||
<div class="callout warning" style="margin-top:12px"><strong>Risk reminder:</strong> participation involves cryptocurrency and smart-contract risk. No income is guaranteed. Use only funds you can afford to lose.</div><div id="supportBox" class="notice" style="margin-top:12px"></div><div id="supportLinkWrap" class="hidden" style="margin-top:10px"><a id="supportLink" class="btn btn-secondary" target="_blank" rel="noopener noreferrer">Open Team Support ↗</a></div></section></div>
|
||||
<figure class="roadmap-figure"><a href="/roadmap.webp" target="_blank" rel="noopener"><img src="/roadmap.webp" alt="RM Circle Premium Team Build Roadmap — core strategy, step-by-step guide, premium levels, and duplication formula" width="1149" height="1369" loading="lazy"></a><figcaption>The RM Circle is a team build project of the <strong>Crypto Team Build Network</strong>. This roadmap is the plan every member follows — tap to view full size.</figcaption></figure></div></main>
|
||||
|
||||
+3
-1
@@ -28,12 +28,14 @@ document.getElementById('idSubmitForm').addEventListener('submit',async e=>{
|
||||
e.preventDefault();
|
||||
const form=e.currentTarget,input=form.elements.newId,msg=document.getElementById('idSubmitMsg');
|
||||
const newId=input.value.trim();
|
||||
const memberName=form.elements.memberName.value.trim();
|
||||
if(!/^[0-9]{1,10}$/.test(newId)){msg.style.color='var(--danger)';msg.textContent='Numbers only — the ID shown by the RM Circle dApp.';return}
|
||||
if(!memberName){msg.style.color='var(--danger)';msg.textContent='Add your name or Telegram handle so the team can reach you.';return}
|
||||
let joinedSponsor='';try{joinedSponsor=sessionStorage.getItem('ctb.joinedSponsor')||''}catch(e){}
|
||||
const sponsorId=joinedSponsor||(currentSponsor?currentSponsor.id:'?');
|
||||
msg.style.color='var(--muted)';msg.textContent='Submitting…';
|
||||
try{
|
||||
const r=await fetch('/api/public/submit-id',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({newId,sponsorId,source:window.ctbGetSource?window.ctbGetSource():'(direct)',clickid:window.ctbGetClickId?window.ctbGetClickId():''})});
|
||||
const r=await fetch('/api/public/submit-id',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({newId,memberName,sponsorId,source:window.ctbGetSource?window.ctbGetSource():'(direct)',clickid:window.ctbGetClickId?window.ctbGetClickId():''})});
|
||||
const d=await r.json();
|
||||
if(!r.ok)throw new Error(d.error||'Submission failed');
|
||||
form.classList.add('hidden');
|
||||
|
||||
Reference in New Issue
Block a user