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 = [];
+7
View File
@@ -222,6 +222,13 @@ input[type=range]{padding:0;border:0;background:transparent;accent-color:var(--m
input:focus,select:focus{border-color:var(--mint)}
:focus-visible{outline:2px solid var(--mint);outline-offset:2px}
.hero-note{font-family:var(--mono);font-size:12px;color:var(--muted);margin-top:26px}
/* member sub-navigation */
.subnav{display:flex;gap:6px;flex-wrap:wrap;background:rgba(16,28,24,.7);border:1px solid var(--line);
border-radius:999px;padding:6px 8px;width:fit-content;margin:0 0 22px}
.subnav button{background:transparent;border:0;color:var(--muted);font:600 13.5px var(--disp);
padding:8px 16px;border-radius:999px;cursor:pointer}
.subnav button:hover{color:var(--ink)}
.subnav button.on{color:var(--mint-ink);background:var(--mint)}
/* member dashboard: qualification progress + roster */
.qualbar{position:relative;height:12px;border-radius:999px;background:rgba(4,8,7,.7);border:1px solid var(--line-strong);
margin:26px 0 30px;max-width:520px}
+4 -4
View File
@@ -5,7 +5,7 @@
<title>The contract | InstantAdPay</title>
<meta name="description" content="Plain-language review of the InstantAdPay settlement contract: what it does, what nobody can change, what the operator can and cannot touch, and how to verify all of it yourself.">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260904p">
<link rel="stylesheet" href="/assets/site.css?v=20260904q">
</head>
<body>
<div class="wrap">
@@ -129,8 +129,8 @@
<div class="small">Advertising services with a performance referral program. Not an investment product; no income guarantees. Crypto transactions are irreversible. Never spend what you cannot afford.</div>
</footer>
</div>
<script src="/assets/common.js?v=20260904p"></script>
<script src="/assets/contract.js?v=20260904p"></script>
<script src="/assets/chat.js?v=20260904p"></script>
<script src="/assets/common.js?v=20260904q"></script>
<script src="/assets/contract.js?v=20260904q"></script>
<script src="/assets/chat.js?v=20260904q"></script>
</body>
</html>
+5 -5
View File
@@ -5,7 +5,7 @@
<title>InstantAdPay: advertise and earn, locked in code</title>
<meta name="description" content="Real ad packages with instant on-chain settlement. Every purchase pays the sponsor line in the same transaction, verifiable by anyone on the live ledger.">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260904p">
<link rel="stylesheet" href="/assets/site.css?v=20260904q">
</head>
<body>
@@ -398,9 +398,9 @@
</div>
</section>
<script src="/assets/common.js?v=20260904p"></script>
<script src="/assets/wallet.js?v=20260904p"></script>
<script src="/assets/home.js?v=20260904p"></script>
<script src="/assets/chat.js?v=20260904p"></script>
<script src="/assets/common.js?v=20260904q"></script>
<script src="/assets/wallet.js?v=20260904q"></script>
<script src="/assets/home.js?v=20260904q"></script>
<script src="/assets/chat.js?v=20260904q"></script>
</body>
</html>
+4 -4
View File
@@ -5,7 +5,7 @@
<title>Live ledger | InstantAdPay</title>
<meta name="description" content="Every purchase, payout, and pass-up on InstantAdPay, streamed straight from the blockchain with a verify link on every line.">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260904p">
<link rel="stylesheet" href="/assets/site.css?v=20260904q">
</head>
<body>
<div class="wrap">
@@ -25,8 +25,8 @@
<div>InstantAdPay · <a href="/">how it works</a> · <a id="contractLink" href="#" target="_blank" rel="noopener">contract source ↗</a></div>
</footer>
</div>
<script src="/assets/common.js?v=20260904p"></script>
<script src="/assets/ledger.js?v=20260904p"></script>
<script src="/assets/chat.js?v=20260904p"></script>
<script src="/assets/common.js?v=20260904q"></script>
<script src="/assets/ledger.js?v=20260904q"></script>
<script src="/assets/chat.js?v=20260904q"></script>
</body>
</html>
+128 -103
View File
@@ -4,11 +4,11 @@
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>My account | InstantAdPay</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260904p">
<link rel="stylesheet" href="/assets/site.css?v=20260904q">
</head>
<body>
<div class="wrap">
<section class="hero" style="padding-bottom:16px">
<section class="hero" style="padding:56px 0 10px">
<h1>My <em>account</em></h1>
<p class="lead" id="introLead">Join free with your email. Your wallet only comes out when you buy
a package or switch on payouts, and it stays yours the whole time.</p>
@@ -46,123 +46,148 @@
</div>
<div id="memberArea" hidden>
<div class="stats" style="margin-top:0">
<div class="stat"><div class="n" id="dbCredits">0</div><div class="l">Ad credits</div></div>
<div class="stat"><div class="n mono" id="dbEarned">0</div><div class="l">POL earned</div></div>
<div class="stat"><div class="n" id="dbBuyers">0</div><div class="l">Qualifying buyers</div></div>
<div class="stat"><div class="n" id="dbTeam">0</div><div class="l">Joined your line</div></div>
<div class="subnav" role="tablist">
<button data-pane="overview" class="on" type="button">Overview</button>
<button data-pane="line" type="button">My line</button>
<button data-pane="campaigns" type="button">Campaigns</button>
<button data-pane="earnings" type="button">Earnings</button>
<button data-pane="wallet" type="button">Wallet</button>
</div>
<div class="card" id="nextCard">
<h3>Your next move</h3>
<p class="muted" id="nextMove">…</p>
<div id="qualBarWrap">
<div class="qualbar"><div id="qualFill"></div>
<span class="qb-mark" style="left:40%">2 · level 2</span>
<span class="qb-mark end">5 · level 3</span>
<!-- ── Overview ─────────────────────────────────────── -->
<div class="pane" id="pane-overview">
<div class="stats" style="margin-top:0">
<div class="stat"><div class="n" id="dbCredits">0</div><div class="l">Ad credits</div></div>
<div class="stat"><div class="n mono" id="dbEarned">0</div><div class="l">POL earned</div></div>
<div class="stat"><div class="n" id="dbBuyers">0</div><div class="l">Qualifying buyers</div></div>
<div class="stat"><div class="n" id="dbTeam">0</div><div class="l">Joined your line</div></div>
</div>
<div class="card" id="nextCard">
<h3>Your next move</h3>
<p class="muted" id="nextMove">…</p>
<div id="qualBarWrap">
<div class="qualbar"><div id="qualFill"></div>
<span class="qb-mark" style="left:40%">2 · level 2</span>
<span class="qb-mark end">5 · level 3</span>
</div>
</div>
</div>
<div class="card"><h3>Earning levels</h3>
<p id="qualLine" class="muted small">…</p></div>
<div class="card">
<h3>Buy ad packages</h3>
<p class="muted small">The full ladder with live pricing is on the <a href="/#ladder-h">home page</a>.
Purchases from your linked wallet automatically credit this account.</p>
</div>
</div>
<div class="grid c3">
<!-- ── My line ──────────────────────────────────────── -->
<div class="pane" id="pane-line" hidden>
<div class="card">
<h3>Your invite link, live from day one</h3>
<p class="muted small">Share it anywhere, starting now. Everyone who joins through it becomes part of
your line, and you earn 50 percent of every ad package they ever buy, plus levels 2 and 3 as you
qualify. Just switch on payouts before your people start buying so every payment locks to you.</p>
<p class="mono" id="inviteLine">…</p>
<p>
<button class="btn small sec" id="copyInvite" hidden>Copy link</button>
<button class="btn small sec" id="copyPitch" hidden>Copy a ready-to-send message</button>
</p>
<p class="muted small" id="pitchPreview" hidden></p>
</div>
<div class="card">
<h3>Your line</h3>
<p class="muted small">Everyone who joined through your link, newest first. When they buy their
first package of $20 or more, they count toward your qualification.</p>
<div id="rosterWrap"><p class="muted small" id="rosterEmpty">Nobody yet. Your link is ready above; share it and this list starts filling.</p></div>
</div>
</div>
<!-- ── Campaigns ────────────────────────────────────── -->
<div class="pane" id="pane-campaigns" hidden>
<div class="card" id="campGate" hidden>
<h3>Campaigns unlock with your first package</h3>
<p class="muted small">Campaigns spend the on-chain credits a package mints. Grab any package on the
<a href="/#ladder-h">home page</a> and this tab turns into your campaign manager.</p>
</div>
<div class="card" id="campaignCard" hidden>
<h3>Your ad campaigns</h3>
<p class="muted small" id="rateLine">…</p>
<div id="campList"></div>
<h3 style="margin-top:18px">New campaign</h3>
<div class="grid c3">
<p><select id="cType" style="width:100%">
<option value="banner">Banner (per impression)</option>
<option value="text">Text ad (per impression)</option>
<option value="login">Login ad (per day)</option>
</select></p>
<p><input id="cName" placeholder="Campaign name" style="width:100%"></p>
<p><input id="cBudget" type="number" placeholder="Budget (credits)" min="10" style="width:100%"></p>
</div>
<p><input id="cTarget" placeholder="Target URL (https://…)" style="width:100%"></p>
<p id="cImageRow"><input id="cImage" placeholder="Image URL (banner/login ads)" style="width:100%"></p>
<p id="cTitleRow" hidden><input id="cTitle" placeholder="Headline (max 60)" style="width:100%"></p>
<p id="cBodyRow" hidden><input id="cBody" placeholder="Ad text (max 140)" style="width:100%"></p>
<button class="btn" id="createCampBtn">Launch campaign</button>
</div>
</div>
<!-- ── Earnings ─────────────────────────────────────── -->
<div class="pane" id="pane-earnings" hidden>
<div id="activityArea" hidden>
<div class="grid c2">
<div class="card">
<h3>Earnings</h3>
<p class="muted small">Every payout the contract has sent to your wallet. Each line links to the transaction.</p>
<div class="feed" id="earnFeed"><div class="row muted">Nothing yet.</div></div>
</div>
<div class="card">
<h3>Your referrals</h3>
<p class="muted small">Activations and qualifying buys in your line.</p>
<div class="feed" id="refFeed"><div class="row muted">Nothing yet.</div></div>
</div>
</div>
<div class="card">
<h3>Your purchases</h3>
<div class="feed" id="buyFeed"><div class="row muted">Nothing yet.</div></div>
</div>
</div>
<div class="card" id="earnGate" hidden>
<h3>Your on-chain history starts with payouts</h3>
<p class="muted small">Once payouts are switched on, every payment, referral event, and purchase in
your line shows here with a verify link to the blockchain. Nothing to claim, nothing to request:
the money is already in your wallet when the line appears.</p>
</div>
</div>
<!-- ── Wallet ───────────────────────────────────────── -->
<div class="pane" id="pane-wallet" hidden>
<div class="card"><h3>Your account</h3>
<p id="posLine" class="muted small">…</p></div>
<div class="card"><h3>Ad credits</h3>
<p class="mono" style="font-size:26px;margin:0" id="creditLine">0</p>
<p class="muted small">1 credit = 1 cent of ad delivery across the network. Recorded on-chain. Only your campaigns can spend them.</p></div>
<div class="card"><h3>Earning levels</h3>
<p id="qualLine" class="muted small">…</p></div>
</div>
<div class="card">
<h3>Your line</h3>
<p class="muted small">Everyone who joined through your link, newest first. When they buy their
first package of $20 or more, they count toward your qualification.</p>
<div id="rosterWrap"><p class="muted small" id="rosterEmpty">Nobody yet. Your link is ready below; share it and this list starts filling.</p></div>
</div>
<div class="card" id="linkCard" hidden>
<h3>Link your wallet</h3>
<p class="muted small">Your earnings pay straight to your own wallet, so we need to know which one is yours.
One free signature links it. It cannot move funds or approve anything. Buying any package links it automatically too.</p>
<button class="btn" id="linkBtn">Connect &amp; link wallet</button>
</div>
<div class="card" id="activateCard" hidden>
<h3>Switch on payouts, free</h3>
<p class="muted small">One free transaction registers your linked wallet on-chain so commissions can reach it,
and it unlocks your invite link. Buying any package does this automatically.</p>
<button class="btn sec" id="activateBtn">Activate payouts</button>
</div>
<div class="card">
<h3>Your invite link, live from day one</h3>
<p class="muted small">Share it anywhere, starting now. Everyone who joins through it becomes part of
your line, and you earn 50 percent of every ad package they ever buy, plus levels 2 and 3 as you
qualify. Just switch on payouts before your people start buying so every payment locks to you.</p>
<p class="mono" id="inviteLine">…</p>
<p>
<button class="btn small sec" id="copyInvite" hidden>Copy link</button>
<button class="btn small sec" id="copyPitch" hidden>Copy a ready-to-send message</button>
</p>
<p class="muted small" id="pitchPreview" hidden></p>
</div>
<div class="card">
<h3>Buy ad packages</h3>
<p class="muted small">The full ladder with live pricing is on the <a href="/">home page</a>.
Purchases from your linked wallet automatically credit this account.</p>
</div>
<div class="card" id="campaignCard" hidden>
<h3>Your ad campaigns</h3>
<p class="muted small" id="rateLine">…</p>
<div id="campList"></div>
<h3 style="margin-top:18px">New campaign</h3>
<div class="grid c3">
<p><select id="cType" style="width:100%">
<option value="banner">Banner (per impression)</option>
<option value="text">Text ad (per impression)</option>
<option value="login">Login ad (per day)</option>
</select></p>
<p><input id="cName" placeholder="Campaign name" style="width:100%"></p>
<p><input id="cBudget" type="number" placeholder="Budget (credits)" min="10" style="width:100%"></p>
<div class="card" id="linkCard" hidden>
<h3>Link your wallet</h3>
<p class="muted small">Your earnings pay straight to your own wallet, so we need to know which one is yours.
One free signature links it. It cannot move funds or approve anything. Buying any package links it automatically too.</p>
<button class="btn" id="linkBtn">Connect &amp; link wallet</button>
</div>
<p><input id="cTarget" placeholder="Target URL (https://…)" style="width:100%"></p>
<p id="cImageRow"><input id="cImage" placeholder="Image URL (banner/login ads)" style="width:100%"></p>
<p id="cTitleRow" hidden><input id="cTitle" placeholder="Headline (max 60)" style="width:100%"></p>
<p id="cBodyRow" hidden><input id="cBody" placeholder="Ad text (max 140)" style="width:100%"></p>
<button class="btn" id="createCampBtn">Launch campaign</button>
</div>
<div id="activityArea" hidden>
<h2>Your activity, straight from the chain</h2>
<div class="grid c2">
<div class="card">
<h3>Earnings</h3>
<p class="muted small">Every payout the contract has sent to your wallet. Each line links to the transaction.</p>
<div class="feed" id="earnFeed"><div class="row muted">Nothing yet.</div></div>
</div>
<div class="card">
<h3>Your referrals</h3>
<p class="muted small">Activations and qualifying buys in your line.</p>
<div class="feed" id="refFeed"><div class="row muted">Nothing yet.</div></div>
</div>
</div>
<div class="card">
<h3>Your purchases</h3>
<div class="feed" id="buyFeed"><div class="row muted">Nothing yet.</div></div>
<div class="card" id="activateCard" hidden>
<h3>Switch on payouts, free</h3>
<p class="muted small">One free transaction registers your linked wallet on-chain so commissions can reach it,
and it unlocks the full flow. Buying any package does this automatically.</p>
<button class="btn sec" id="activateBtn">Activate payouts</button>
</div>
<p class="small"><a href="#" id="logoutLink">Log out</a></p>
</div>
<p class="small"><a href="#" id="logoutLink">Log out</a></p>
</div>
<footer><div>InstantAdPay · <a href="/ledger">live ledger</a></div></footer>
<footer><div>InstantAdPay · <a href="/ledger">live ledger</a> · <a href="/contract">the contract</a></div></footer>
</div>
<script src="/assets/common.js?v=20260904p"></script>
<script src="/assets/wallet.js?v=20260904p"></script>
<script src="/assets/my.js?v=20260904p"></script>
<script src="/assets/chat.js?v=20260904p"></script>
<script src="/assets/common.js?v=20260904q"></script>
<script src="/assets/wallet.js?v=20260904q"></script>
<script src="/assets/my.js?v=20260904q"></script>
<script src="/assets/chat.js?v=20260904q"></script>
</body>
</html>