// My account: email-first join/login, wallet link at purchase time,
// free payout activation, invite link, on-chain activity.
(async function () {
await IAP.renderNav('my');
const $ = IAP.$;
async function api(path, body) {
const r = await (await fetch(path, { method: 'POST',
headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body || {}) })).json();
if (r.error) throw new Error(r.error);
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 => '
' + r.email + '
'
+ '
' + new Date(r.joined).toLocaleDateString() + '
'
+ '
' + r.status + '
').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) {}
}
// ── members-area menu: hash-routed panes ──────────────
const PANES = ['overview', 'line', 'campaigns', 'earnings', 'wallet'];
function setPane(name) {
if (!PANES.includes(name)) name = 'overview';
for (const p of PANES) {
const el = $('pane-' + p);
if (el) el.hidden = p !== name;
}
document.querySelectorAll('.subnav [data-pane]').forEach(b =>
b.classList.toggle('on', b.dataset.pane === name));
if (location.hash !== '#' + name) history.replaceState(null, '', '#' + name);
}
document.querySelectorAll('.subnav [data-pane]').forEach(b =>
b.addEventListener('click', () => setPane(b.dataset.pane)));
window.addEventListener('hashchange', () => setPane(location.hash.slice(1)));
async function render() {
const me = await IAP.refreshNavWallet();
const signedIn = me && me.signedIn;
$('authArea').hidden = !!signedIn;
$('memberArea').hidden = !signedIn;
if (!signedIn) return;
setPane(location.hash.slice(1) || 'overview');
$('campGate').hidden = !!me.memberId;
$('earnGate').hidden = !!me.memberId;
loadDashboard();
const who = [];
if (me.email) who.push(me.email);
if (me.address) who.push('wallet ' + me.address.slice(0, 8) + '…' + me.address.slice(-6) + '');
else who.push('no wallet linked yet');
if (me.memberId) who.push('on-chain member #' + me.memberId + ''
+ (me.onchainSponsorId ? ', sponsored by #' + me.onchainSponsorId : ''));
else if (me.sponsorId) who.push('invited by member #' + me.sponsorId);
$('posLine').innerHTML = who.join(' ');
$('creditLine').textContent = (me.credits || 0).toLocaleString();
$('linkCard').hidden = !!me.address;
$('activateCard').hidden = !(me.address && !me.memberId);
$('activityArea').hidden = !me.memberId;
$('campaignCard').hidden = !me.memberId;
if (me.memberId) loadCampaigns();
// the share link works from day one; codes resolve to your chain id later
if (me.refCode || me.memberId) {
$('inviteLine').textContent = location.origin + '/join/' + (me.refCode || me.memberId);
$('copyInvite').hidden = false;
} else {
$('inviteLine').textContent = 'Sign in with your email to get your link.';
$('copyInvite').hidden = true;
}
if (me.memberId) {
const bc = me.buyerCount || 0;
$('qualLine').innerHTML = '' + bc + ' qualifying buyer(s) referred '
+ (bc >= 5 ? 'Level 3 unlocked: full three-level earnings'
: bc >= 2 ? 'Level 2 unlocked · ' + (5 - bc) + ' more for level 3'
: (2 - bc) + ' more buyer(s) of $20+ unlock level 2');
loadActivity();
} else {
$('qualLine').innerHTML = 'Share your link now. Then switch on payouts (free, above) '
+ 'before your people start buying: the contract locks each buyer to their sponsor at '
+ 'their first purchase, and payments only route to wallets that are switched on.';
}
}
async function loadActivity() {
try {
const c = await IAP.getConfig();
const a = await (await fetch('/api/my/activity')).json();
const fill = (id, evs, empty) => {
const el = $(id);
el.innerHTML = '';
if (!evs || !evs.length) { el.innerHTML = '
' + empty + '
'; return; }
for (const ev of evs) el.appendChild(IAP.feedRow(ev, c));
};
fill('earnFeed', a.earnings, 'No payouts yet. They appear here the moment one lands.');
fill('refFeed', a.referrals, 'No referral activity yet. Share your invite link.');
fill('buyFeed', a.purchases, 'No purchases from your wallet yet.');
} catch (e) {}
}
async function loadCampaigns() {
try {
const r = await (await fetch('/api/my/campaigns')).json();
if (r.error) return;
$('rateLine').textContent = 'Available to spend: ' + r.availableCredits.toLocaleString()
+ ' credits · rates: banner ' + r.rates.bannerCreditsPerBatch + 'cr/' + r.rates.bannerBatch
+ ' views, text ' + r.rates.textCreditsPerBatch + 'cr/' + r.rates.textBatch
+ ' views, login ' + r.rates.loginCreditsPerDay + 'cr/day';
const el = $('campList');
el.innerHTML = '';
if (!r.campaigns.length) { el.innerHTML = '