Member dashboard: stat cards, next-move guidance, line roster, share kit
/api/my/dashboard aggregates credits, earned POL (from the chain index), qualification count, and the referral roster (privacy-masked emails, joined-free vs wallet-linked status, code+id referrer match). Members area leads with four stat cards, a next-move card with a qualification progress bar (2 and 5 buyer marks), the line roster, and a copy-ready share message beside the invite link. Assets v=20260904j. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,12 +11,60 @@
|
||||
return r;
|
||||
}
|
||||
|
||||
function nextMove(d) {
|
||||
if (!d.address) return 'Grab your link below and start sharing today. Then link your wallet (one free signature) so every payment can lock to you before your people start buying.';
|
||||
if (!d.memberId) return 'Your wallet is linked. Switch on payouts above (one free transaction) and every purchase in your line pays you the moment it happens.';
|
||||
if (d.buyerCount === 0) return 'Payouts are on and your link is live. Your next milestone: your first buyer of $20 or more. Every direct pays you 50 percent from their very first package.';
|
||||
if (d.buyerCount === 1) return 'One qualifying buyer down, one to go. Your next $20+ buyer unlocks level 2: 20 percent of everything your people’s people buy.';
|
||||
if (d.buyerCount < 5) return 'Level 2 is open. ' + (5 - d.buyerCount) + ' more qualifying buyer(s) unlock level 3 and the full three-level flow.';
|
||||
return 'Fully qualified. Every level pays you, and you catch the pass-ups that under-qualified positions below you let slip. Keep sharing and keep your campaigns running.';
|
||||
}
|
||||
async function loadDashboard() {
|
||||
try {
|
||||
const d = await (await fetch('/api/my/dashboard')).json();
|
||||
if (d.error) return;
|
||||
$('dbCredits').textContent = (d.credits || 0).toLocaleString();
|
||||
$('dbEarned').textContent = IAP.fmtPol(d.earnedWei || '0');
|
||||
$('dbBuyers').textContent = d.buyerCount || 0;
|
||||
$('dbTeam').textContent = (d.referrals || []).length;
|
||||
$('nextMove').textContent = nextMove(d);
|
||||
$('qualFill').style.width = Math.min(100, (d.buyerCount || 0) * 20) + '%';
|
||||
const wrap = $('rosterWrap');
|
||||
if ((d.referrals || []).length) {
|
||||
$('rosterEmpty').hidden = true;
|
||||
let t = wrap.querySelector('table');
|
||||
if (t) t.remove();
|
||||
t = document.createElement('table');
|
||||
t.className = 'roster';
|
||||
t.innerHTML = d.referrals.map(r => '<tr><td>' + r.email + '</td>'
|
||||
+ '<td>' + new Date(r.joined).toLocaleDateString() + '</td>'
|
||||
+ '<td><span class="badge' + (r.status === 'joined free' ? ' amber' : '') + '">' + r.status + '</span></td></tr>').join('');
|
||||
wrap.appendChild(t);
|
||||
}
|
||||
// ready-to-send share message
|
||||
const link = location.origin + '/join/' + (d.refCode || d.memberId || '');
|
||||
if (d.refCode || d.memberId) {
|
||||
const pitch = 'I found an advertising site that pays referrals instantly to your own wallet. '
|
||||
+ 'No withdrawals, no waiting, and every payment is public on a blockchain ledger you can check yourself. '
|
||||
+ 'Free to join and look around: ' + link;
|
||||
$('copyPitch').hidden = false;
|
||||
$('pitchPreview').hidden = false;
|
||||
$('pitchPreview').textContent = '"' + pitch + '"';
|
||||
$('copyPitch').onclick = async () => {
|
||||
try { await navigator.clipboard.writeText(pitch); IAP.status('Message copied. Paste it anywhere.', 'ok'); }
|
||||
catch (e) { IAP.status('Copy failed. Select the preview text instead.', 'bad'); }
|
||||
};
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function render() {
|
||||
const me = await IAP.refreshNavWallet();
|
||||
const signedIn = me && me.signedIn;
|
||||
$('authArea').hidden = !!signedIn;
|
||||
$('memberArea').hidden = !signedIn;
|
||||
if (!signedIn) return;
|
||||
loadDashboard();
|
||||
|
||||
const who = [];
|
||||
if (me.email) who.push(me.email);
|
||||
|
||||
Reference in New Issue
Block a user