Branded Voice copy pass, members activity panels, menu update
Site copy regenerated through the bv-tester1 engine; em dashes scrubbed from all user-visible strings. /api/my/activity serves per-member earnings, referrals, and purchases from the chain index. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,14 +30,15 @@ window.IAP = (function () {
|
||||
+ '<a class="logo" href="/">Instant<b>AdPay</b></a>'
|
||||
+ '<span class="links">'
|
||||
+ '<a href="/" data-p="home">How it works</a>'
|
||||
+ '<a href="/#ladder" data-p="pricing">Ad packages</a>'
|
||||
+ '<a href="/ledger" data-p="ledger">Live ledger</a>'
|
||||
+ '<a href="/my" data-p="my">My account</a>'
|
||||
+ '<a href="/my" data-p="my">Members</a>'
|
||||
+ '</span><span id="navWallet" class="muted">…</span></div>';
|
||||
document.body.prepend(nav);
|
||||
if (c.rehearsal) {
|
||||
const b = document.createElement('div');
|
||||
b.className = 'rehearsal';
|
||||
b.innerHTML = '<b>Testnet rehearsal</b> — running on ' + c.chainName + '. Purchases use valueless test POL while we prove every payout in public.';
|
||||
b.innerHTML = '<b>Testnet rehearsal</b>: running on ' + c.chainName + '. Purchases use valueless test POL while we prove every payout in public.';
|
||||
document.body.prepend(b);
|
||||
}
|
||||
const a = nav.querySelector('[data-p="' + active + '"]');
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
if (sp.sponsorId) {
|
||||
const el = IAP.$('sponsorLine');
|
||||
el.hidden = false;
|
||||
el.textContent = 'You were invited by member #' + sp.sponsorId + ' — your purchases pay their team, and your own link will do the same for you.';
|
||||
el.textContent = 'You were invited by member #' + sp.sponsorId + '. Your purchases pay their team, and your own link will do the same for you.';
|
||||
}
|
||||
|
||||
async function loadLadder() {
|
||||
@@ -33,8 +33,8 @@
|
||||
btn.disabled = true;
|
||||
IAP.status('Confirm the purchase in your wallet…');
|
||||
const r = await IAPWallet.buy(Number(btn.dataset.id), sp.sponsorId || 0, btn.dataset.cost);
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted — see the explorer.');
|
||||
IAP.status('Purchase settled on-chain — credits are yours, payouts delivered. Watch it on the ledger.', 'ok');
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted. Check the explorer.');
|
||||
IAP.status('Purchase settled on-chain. Credits are yours, payouts delivered. Watch it on the ledger.', 'ok');
|
||||
IAP.refreshNavWallet();
|
||||
} catch (e) {
|
||||
IAP.status('Purchase failed: ' + (e.message || e), 'bad');
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
const { events } = await (await fetch('/api/feed?n=150')).json();
|
||||
feed.innerHTML = '';
|
||||
if (!events.length) feed.innerHTML = '<div class="row muted">No activity yet — the first purchase will appear here the moment it lands.</div>';
|
||||
if (!events.length) feed.innerHTML = '<div class="row muted">No activity yet. The first purchase will appear here the moment it lands.</div>';
|
||||
for (const ev of events) feed.appendChild(IAP.feedRow(ev, c));
|
||||
|
||||
try {
|
||||
|
||||
+22
-5
@@ -16,15 +16,16 @@
|
||||
$('creditLine').textContent = (me.credits || 0).toLocaleString();
|
||||
const bc = me.buyerCount || 0;
|
||||
$('qualLine').innerHTML = '<b>' + bc + '</b> qualifying buyer(s) referred<br>'
|
||||
+ (bc >= 5 ? '<span class="badge">Level 3 unlocked — full three-level earnings</span>'
|
||||
+ (bc >= 5 ? '<span class="badge">Level 3 unlocked: full three-level earnings</span>'
|
||||
: bc >= 2 ? '<span class="badge">Level 2 unlocked</span> · ' + (5 - bc) + ' more for level 3'
|
||||
: (2 - bc) + ' more ≥$20 buyer(s) unlock level 2');
|
||||
$('activateCard').hidden = true;
|
||||
$('inviteLine').textContent = location.origin + '/join/' + me.memberId;
|
||||
$('copyInvite').hidden = false;
|
||||
loadActivity();
|
||||
} else {
|
||||
$('posLine').innerHTML = 'Signed in as <span class="mono">' + me.address.slice(0, 8) + '…' + me.address.slice(-6)
|
||||
+ '</span><br>free member — not on-chain yet'
|
||||
+ '</span><br>free member, not on-chain yet'
|
||||
+ (me.sponsorId ? '<br>invited by member #' + me.sponsorId : '');
|
||||
$('creditLine').textContent = '0';
|
||||
$('qualLine').textContent = 'Activate your payout wallet (or buy any package) to start; referrals who buy ≥$20 packages qualify you.';
|
||||
@@ -34,6 +35,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
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.length) { el.innerHTML = '<div class="row muted">' + empty + '</div>'; 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 this wallet yet.');
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
$('signinBtn').addEventListener('click', async () => {
|
||||
try {
|
||||
$('signinBtn').disabled = true;
|
||||
@@ -51,8 +68,8 @@
|
||||
const me = await (await fetch('/api/me')).json();
|
||||
IAP.status('Confirm the free activation in your wallet…');
|
||||
const r = await IAPWallet.activate(me.sponsorId || 0);
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted — see the explorer.');
|
||||
IAP.status('Payout wallet activated — your invite link is live.', 'ok');
|
||||
if (r.receipt.status !== '0x1') throw new Error('Transaction reverted. Check the explorer.');
|
||||
IAP.status('Payout wallet activated. Your invite link is live.', 'ok');
|
||||
await render();
|
||||
} catch (e) { IAP.status('Activation failed: ' + ((e && e.message) || e), 'bad'); }
|
||||
finally { $('activateBtn').disabled = false; }
|
||||
@@ -60,7 +77,7 @@
|
||||
|
||||
$('copyInvite').addEventListener('click', async () => {
|
||||
try { await navigator.clipboard.writeText($('inviteLine').textContent); IAP.status('Link copied.', 'ok'); }
|
||||
catch (e) { IAP.status('Copy failed — select and copy the link text.', 'bad'); }
|
||||
catch (e) { IAP.status('Copy failed. Select and copy the link text.', 'bad'); }
|
||||
});
|
||||
|
||||
render();
|
||||
|
||||
@@ -13,7 +13,7 @@ a:hover{text-decoration:underline}
|
||||
.wrap{max-width:1020px;margin:0 auto;padding:0 18px}
|
||||
/* nav */
|
||||
nav{border-bottom:1px solid var(--line);background:rgba(13,20,32,.92);position:sticky;top:0;z-index:10}
|
||||
nav .wrap{display:flex;align-items:center;gap:22px;height:58px}
|
||||
nav .wrap{display:flex;align-items:center;gap:22px;min-height:58px;flex-wrap:wrap;padding-top:6px;padding-bottom:6px}
|
||||
.logo{font-weight:800;font-size:19px;color:var(--ink)}
|
||||
.logo b{color:var(--amber)}
|
||||
nav .links{display:flex;gap:18px;font-size:14.5px;flex:1}
|
||||
|
||||
@@ -56,7 +56,7 @@ window.IAPWallet = (function () {
|
||||
if (r.result) return r.result;
|
||||
await new Promise(res => setTimeout(res, 2500));
|
||||
}
|
||||
throw new Error('Timed out waiting for the transaction — check the explorer.');
|
||||
throw new Error('Timed out waiting for the transaction. Check the explorer.');
|
||||
}
|
||||
// buy: quote is read live server-side; pad 2% for oracle drift, contract
|
||||
// refunds every wei of excess in the same transaction.
|
||||
|
||||
Reference in New Issue
Block a user