Members area menu: Overview / My line / Campaigns / Earnings / Wallet

Hash-routed pane tabs replace the single scrolling page. Overview keeps the
stat cards, next-move guidance, and levels; My line holds the invite/share
kit and roster; Campaigns gains a pre-purchase gate card; Earnings gains a
pre-activation explainer; Wallet gathers account, credits, link, activate,
logout. Deep links (/my#campaigns) land on the right pane. Browser-verified
tab exclusivity, hash sync, deep links, and 390px overflow. Assets
v=20260904q.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-04 16:39:23 -05:00
parent 537b11cfde
commit c10af1d1e7
6 changed files with 167 additions and 116 deletions
+19
View File
@@ -58,12 +58,31 @@
} 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 = [];