Tools page auto-personalization: dashboard hands off ?id=, every post/swipe (copy payload AND visible preview) swaps the bare main-domain link for the member's /join/<id> link; sticky via localStorage; green confirmation banner

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-20 07:14:45 -05:00
parent 4014d12208
commit 8841e9d718
3 changed files with 37 additions and 2 deletions
+2
View File
@@ -92,6 +92,8 @@
renderPitch(d);
setTab(openDashTab?'dash':'pitch');
document.getElementById('dTitle').textContent='#'+d.id;
// hand the member's id to the tools page so every promo asset arrives pre-personalized
document.querySelectorAll('a[href="/tools"]').forEach(function(a){a.href='/tools?id='+d.id;});
const qb=document.getElementById('dQualified');
if(qb)qb.outerHTML=d.directCount>=2
?'<span id="dQualified" class="q-badge q-yes">★ Qualified</span>'
+2 -1
View File
@@ -18,7 +18,8 @@
<h2 style="font-size:30px;margin:36px 0 14px">🔗 Your invite link</h2>
<p style="color:var(--muted);margin:0 0 14px">Enter your RM Circle ID to build your personal invite page link — it shows a live preview when shared and points people to the current join steps.</p>
<div class="tool-card"><div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center"><input id="toolId" class="input" style="max-width:220px" placeholder="Your ID (e.g. 21)" inputmode="numeric"><span style="color:var(--muted);font-size:15px">→</span><code id="shareLink" class="share-link">https://rmcircle.team/join/…</code><button class="btn btn-teal btn-sm" id="copyShare">Copy link</button></div><p class="micro" style="margin:10px 0 0">Tip: always confirm the current sponsor on the <a href="/start" style="color:var(--teal)">Getting Started page</a> before someone buys — placements rotate. Swap <strong style="color:var(--text)">https://rmcircle.team</strong> for your personal link in any post below.</p></div>
<div class="tool-card"><div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center"><input id="toolId" class="input" style="max-width:220px" placeholder="Your ID (e.g. 21)" inputmode="numeric"><span style="color:var(--muted);font-size:15px">→</span><code id="shareLink" class="share-link">https://rmcircle.team/join/…</code><button class="btn btn-teal btn-sm" id="copyShare">Copy link</button></div><p class="micro" style="margin:10px 0 0">Tip: always confirm the current sponsor on the <a href="/start" style="color:var(--teal)">Getting Started page</a> before someone buys — placements rotate.</p>
<div id="personalNote" class="callout" style="display:none;margin-top:12px;border-color:rgba(123,224,161,.5)">✅ <strong>#—</strong> — every post and swipe below has been personalized with <em>your</em> invite link (<span class="pnl" style="color:var(--teal)"></span>). Copy and share as-is; people who click land in your team. Wrong ID? Change it in the box above.</div></div>
<h2 style="font-size:30px;margin:36px 0 14px">📣 Social posts</h2>
<p style="color:var(--muted);margin:0 0 18px">Copy-paste ready for X/Twitter, Facebook, or anywhere. Tap <strong style="color:var(--text)">Copy</strong>, tweak a word or two so it sounds like you, and post. Swap in your personal invite link where it fits.</p>
+34 -2
View File
@@ -12,6 +12,38 @@
const idIn=document.getElementById('toolId'), link=document.getElementById('shareLink'), copyShare=document.getElementById('copyShare');
function url(){ const id=(idIn.value||'').replace(/\D/g,'').slice(0,15); return id?`https://rmcircle.team/join/${id}`:''; }
function render(){ link.textContent=url()||'https://rmcircle.team/join/…'; }
if(idIn){ idIn.addEventListener('input',render); render(); }
if(copyShare){ copyShare.addEventListener('click',()=>{ const u=url(); if(!u){ idIn.focus(); return; } copy(u,copyShare); }); }
// ---- personalization: every asset carries the member's own invite link ----
// Replaces BARE https://rmcircle.team mentions (not /contract, /v/…, /banners/…)
// in both the copy payloads and the visible previews. ID comes from ?id=
// (dashboard hand-off), then localStorage, then the "Your link" box.
const BARE=/https:\/\/rmcircle\.team(?![\w./-])/g;
function personalize(){
const id=(idIn&&idIn.value||'').replace(/\D/g,'').slice(0,15);
const mine=id?`https://rmcircle.team/join/${id}`:null;
document.querySelectorAll('.copy-btn').forEach(b=>{
if(b.dataset.orig===undefined)b.dataset.orig=b.getAttribute('data-copy')||'';
b.setAttribute('data-copy', mine?b.dataset.orig.replace(BARE,mine):b.dataset.orig);
});
document.querySelectorAll('pre.swipe').forEach(p=>{
if(p.dataset.orig===undefined)p.dataset.orig=p.textContent;
p.textContent= mine?p.dataset.orig.replace(BARE,mine):p.dataset.orig;
});
const note=document.getElementById('personalNote');
if(note){
if(mine){ note.style.display='block'; const s=note.querySelector('strong'); if(s)s.textContent='#'+id; const l=note.querySelector('.pnl'); if(l)l.textContent=mine; }
else note.style.display='none';
}
if(id){ try{localStorage.setItem('rmc.toolsId',id);}catch(e){} }
}
(function initId(){
if(!idIn)return;
const q=new URLSearchParams(location.search).get('id');
let id=(q&&/^\d{1,15}$/.test(q))?q:'';
if(!id){ try{const s=localStorage.getItem('rmc.toolsId'); if(s&&/^\d{1,15}$/.test(s))id=s;}catch(e){} }
if(id&&!idIn.value)idIn.value=id;
})();
if(idIn){ idIn.addEventListener('input',function(){render();personalize();}); render(); }
if(copyShare){ copyShare.addEventListener('click',()=>{ const u=url(); if(!u){ idIn.focus(); return; } copy(u,copyShare); }); }
personalize();
})();