Back-office polish: Overview command center, quick actions, pane motion

Overview gains a recent-activity mini-feed (chain events + line joins) and
a quick-actions card jumping straight to buy/earn/campaigns plus one-tap
invite copy. Panes fade in (reduced-motion safe). First slice of the
back-office polish pass. Assets v=20260905f.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-05 06:09:37 -05:00
parent a4c7028c0e
commit 7331eac244
6 changed files with 74 additions and 23 deletions
+31
View File
@@ -50,6 +50,28 @@
+ '<td><span class="badge' + (r.status === 'joined free' ? ' amber' : '') + '">' + r.status + '</span></td></tr>').join(''); + '<td><span class="badge' + (r.status === 'joined free' ? ' amber' : '') + '">' + r.status + '</span></td></tr>').join('');
wrap.appendChild(t); wrap.appendChild(t);
} }
// overview recent-activity widget: chain events + line joins, newest first
try {
const c = await IAP.getConfig();
const ov = $('ovFeed');
const rows = [];
if (d.memberId) {
const a = await (await fetch('/api/my/activity')).json();
for (const ev of [...(a.earnings || []), ...(a.purchases || [])]
.sort((x, y) => y.block - x.block).slice(0, 5)) rows.push(IAP.feedRow(ev, c));
}
for (const r of (d.referrals || []).slice(0, 3)) {
const div = document.createElement('div');
div.className = 'row';
div.innerHTML = '<span>🤝 ' + r.email + ' joined your line</span><span class="tx muted small">'
+ new Date(r.joined).toLocaleDateString() + '</span>';
rows.push(div);
}
if (rows.length) {
ov.innerHTML = '';
rows.slice(0, 6).forEach(r => ov.appendChild(r));
}
} catch (e) {}
// ready-to-send share message // ready-to-send share message
const link = location.origin + '/join/' + (d.refCode || d.memberId || ''); const link = location.origin + '/join/' + (d.refCode || d.memberId || '');
if (d.refCode || d.memberId) { if (d.refCode || d.memberId) {
@@ -85,6 +107,15 @@
} }
document.querySelectorAll('.bo-menu [data-pane]').forEach(b => document.querySelectorAll('.bo-menu [data-pane]').forEach(b =>
b.addEventListener('click', () => setPane(b.dataset.pane))); b.addEventListener('click', () => setPane(b.dataset.pane)));
document.querySelectorAll('.qa [data-goto]').forEach(b =>
b.addEventListener('click', () => setPane(b.dataset.goto)));
const qaCopy = document.getElementById('qaCopyInvite');
if (qaCopy) qaCopy.addEventListener('click', async () => {
const link = document.getElementById('inviteLine').textContent;
if (!link || !link.startsWith('http')) { setPane('line'); return; }
try { await navigator.clipboard.writeText(link); IAP.status('Invite link copied.', 'ok'); }
catch (e) { setPane('line'); }
});
window.addEventListener('hashchange', () => setPane(location.hash.slice(1))); window.addEventListener('hashchange', () => setPane(location.hash.slice(1)));
if ($('boBurger')) $('boBurger').addEventListener('click', () => if ($('boBurger')) $('boBurger').addEventListener('click', () =>
document.getElementById('memberArea').classList.toggle('side-open')); document.getElementById('memberArea').classList.toggle('side-open'));
+10
View File
@@ -257,6 +257,16 @@ input:focus,select:focus{border-color:var(--mint)}
#boBurger{display:block} #boBurger{display:block}
.bo-content{padding:18px} .bo-content{padding:18px}
} }
/* back-office polish: pane transitions, quick actions */
@media(prefers-reduced-motion:no-preference){
.pane:not([hidden]){animation:panein .25s ease}
@keyframes panein{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
}
.qa{display:flex;flex-direction:column;gap:8px}
.qa button{display:flex;align-items:center;gap:10px;background:rgba(67,232,195,.05);border:1px solid var(--line);
color:var(--ink);font:600 14px var(--disp);padding:11px 14px;border-radius:11px;cursor:pointer;text-align:left;
transition:border-color .15s ease,background .15s ease}
.qa button:hover{border-color:var(--mint);background:rgba(67,232,195,.1)}
/* member sub-navigation */ /* member sub-navigation */
.subnav{display:flex;gap:6px;flex-wrap:wrap;background:rgba(16,28,24,.7);border:1px solid var(--line); .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} border-radius:999px;padding:6px 8px;width:fit-content;margin:0 0 22px}
+4 -4
View File
@@ -5,7 +5,7 @@
<title>The contract | InstantAdPay</title> <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."> <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="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260905e"> <link rel="stylesheet" href="/assets/site.css?v=20260905f">
</head> </head>
<body> <body>
<div class="wrap"> <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> <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> </footer>
</div> </div>
<script src="/assets/common.js?v=20260905e"></script> <script src="/assets/common.js?v=20260905f"></script>
<script src="/assets/contract.js?v=20260905e"></script> <script src="/assets/contract.js?v=20260905f"></script>
<script src="/assets/chat.js?v=20260905e"></script> <script src="/assets/chat.js?v=20260905f"></script>
</body> </body>
</html> </html>
+5 -5
View File
@@ -5,7 +5,7 @@
<title>InstantAdPay: advertise and earn, locked in code</title> <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."> <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="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260905e"> <link rel="stylesheet" href="/assets/site.css?v=20260905f">
</head> </head>
<body> <body>
@@ -399,9 +399,9 @@
</div> </div>
</section> </section>
<script src="/assets/common.js?v=20260905e"></script> <script src="/assets/common.js?v=20260905f"></script>
<script src="/assets/wallet.js?v=20260905e"></script> <script src="/assets/wallet.js?v=20260905f"></script>
<script src="/assets/home.js?v=20260905e"></script> <script src="/assets/home.js?v=20260905f"></script>
<script src="/assets/chat.js?v=20260905e"></script> <script src="/assets/chat.js?v=20260905f"></script>
</body> </body>
</html> </html>
+4 -4
View File
@@ -5,7 +5,7 @@
<title>Live ledger | InstantAdPay</title> <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."> <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="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap">
<link rel="stylesheet" href="/assets/site.css?v=20260905e"> <link rel="stylesheet" href="/assets/site.css?v=20260905f">
</head> </head>
<body> <body>
<div class="wrap"> <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> <div>InstantAdPay · <a href="/">how it works</a> · <a id="contractLink" href="#" target="_blank" rel="noopener">contract source ↗</a></div>
</footer> </footer>
</div> </div>
<script src="/assets/common.js?v=20260905e"></script> <script src="/assets/common.js?v=20260905f"></script>
<script src="/assets/ledger.js?v=20260905e"></script> <script src="/assets/ledger.js?v=20260905f"></script>
<script src="/assets/chat.js?v=20260905e"></script> <script src="/assets/chat.js?v=20260905f"></script>
</body> </body>
</html> </html>
+19 -9
View File
@@ -4,7 +4,7 @@
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Member area | InstantAdPay</title> <title>Member area | InstantAdPay</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&display=swap"> <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=20260905e"> <link rel="stylesheet" href="/assets/site.css?v=20260905f">
</head> </head>
<body class="bo-body"> <body class="bo-body">
@@ -98,12 +98,22 @@
</div> </div>
</div> </div>
<div class="grid c2"> <div class="grid c2">
<div class="card">
<h3>Recent activity</h3>
<div class="feed" id="ovFeed"><div class="row muted">Your line's joins, buys, and payouts land here.</div></div>
</div>
<div>
<div class="card">
<h3>Quick actions</h3>
<div class="qa">
<button type="button" data-goto="buy">🛒 Buy a package</button>
<button type="button" data-goto="earn">👁 View today's ads</button>
<button type="button" data-goto="campaigns">📣 Launch a campaign</button>
<button type="button" id="qaCopyInvite">🔗 Copy my invite link</button>
</div>
</div>
<div class="card"><h3>Earning levels</h3> <div class="card"><h3>Earning levels</h3>
<p id="qualLine" class="muted small">…</p></div> <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> </div>
</div> </div>
@@ -240,9 +250,9 @@
</div> </div>
</div> </div>
<script src="/assets/common.js?v=20260905e"></script> <script src="/assets/common.js?v=20260905f"></script>
<script src="/assets/wallet.js?v=20260905e"></script> <script src="/assets/wallet.js?v=20260905f"></script>
<script src="/assets/my.js?v=20260905e"></script> <script src="/assets/my.js?v=20260905f"></script>
<script src="/assets/chat.js?v=20260905e"></script> <script src="/assets/chat.js?v=20260905f"></script>
</body> </body>
</html> </html>