Campaigns: gold available-to-spend banner + where-your-ads-run (incl. Network Ad Space); Wallet: live POL balances; Earn credits: done-for-today mark
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+34
-3
@@ -582,6 +582,12 @@
|
||||
if (r.bannerSizes && $('cSize') && !$('cSize').options.length)
|
||||
$('cSize').innerHTML = r.bannerSizes.map(s => '<option value="' + s.id + '">' + s.label + '</option>').join('');
|
||||
soloHint();
|
||||
if ($('spendBanner')) {
|
||||
$('spendBanner').hidden = false;
|
||||
$('spendBig').textContent = r.availableCredits.toLocaleString();
|
||||
$('spendSub').textContent = '= $' + (r.availableCredits / 100).toLocaleString(undefined, { maximumFractionDigits: 2 }) + ' of ad delivery' + (r.earnedCredits ? ' · ' + r.purchasedCredits.toLocaleString() + ' purchased + ' + r.earnedCredits.toLocaleString() + ' earned by viewing' : '') + (r.positionCount > 1 ? ' · pooled across ' + r.positionCount + ' positions (largest single position ' + (r.largestPosition || 0).toLocaleString() + ')' : '');
|
||||
$('spendRates').innerHTML = [['Banner', r.rates.bannerCreditsPerBatch + ' cr / ' + r.rates.bannerBatch + ' views'], ['Text', r.rates.textCreditsPerBatch + ' cr / ' + r.rates.textBatch + ' views'], ['Login', r.rates.loginCreditsPerDay + ' cr / day'], ['Solo', r.rates.soloCostPerRecipient + ' cr / delivery'], ['Featured', (r.rates.featuredPerDay || 40) + ' cr / day'], ['Visit', (r.rates.visitCostPerVisit || 3) + ' cr / visit']].map(x => '<span><b>' + x[0] + '</b> ' + x[1] + '</span>').join('');
|
||||
}
|
||||
$('rateLine').textContent = 'Available to spend: ' + r.availableCredits.toLocaleString()
|
||||
+ (r.earnedCredits ? ' (' + r.purchasedCredits.toLocaleString() + ' purchased + ' + r.earnedCredits + ' earned)' : '')
|
||||
+ ' credits · rates: banner ' + r.rates.bannerCreditsPerBatch + 'cr/' + r.rates.bannerBatch
|
||||
@@ -672,7 +678,17 @@
|
||||
if (raw.hidden) { raw.value = ed.innerHTML; raw.hidden = false; ed.hidden = true; $('edRawBtn').textContent = 'Visual'; }
|
||||
else { ed.innerHTML = raw.value; ed.hidden = false; raw.hidden = true; $('edRawBtn').textContent = 'Raw text'; }
|
||||
});
|
||||
const WHERE = { banner: 'Runs in the ad viewer, on the home page, the live ledger, every Overview, the sidebar tile, and out in the Network Ad Space rotation across the wider network.',
|
||||
text: 'Runs in the ad viewer, the live ledger text slot, and out in the Network Ad Space rotation.',
|
||||
login: 'Full screen for every member who signs in, ten seconds, once a day per member. Opens in a fresh tab, so any working page qualifies.',
|
||||
solo: 'Delivered into member inboxes under Earn credits. Each read is timed and rewarded, so it gets opened.',
|
||||
video: 'Plays in Watch videos and the Shorts feed under Earn credits. You pay only for completed watches.',
|
||||
featured: 'Your headline and link in the Featured strip on every member Overview for the days you book.',
|
||||
visits: 'A distinct member opens your site in a new tab, stays eight seconds and passes a check. Nobody counts twice.' };
|
||||
const whereHint = () => { const el = $('cWhere'); if (el) el.textContent = WHERE[$('cType').value] || ''; };
|
||||
whereHint();
|
||||
$('cType').addEventListener('change', () => {
|
||||
whereHint();
|
||||
const t = $('cType').value;
|
||||
$('cImageRow').hidden = t !== 'banner'; // only banners carry a creative; login frames its URL
|
||||
$('cSizeRow').hidden = t !== 'banner';
|
||||
@@ -1323,15 +1339,26 @@
|
||||
const rows = list.map((p, i) => '<div class="lin-row"><span class="nm">Position ' + (i + 2) + ' <span class="mono">' + short(p.address) + '</span></span>'
|
||||
+ '<span class="id">' + (p.memberId ? '#' + p.memberId : 'not on-chain yet') + '</span>'
|
||||
+ '<span class="earn' + (p.counted ? ' on' : '') + '">' + (p.counted ? 'counts as a qualifying buyer' : p.memberId ? 'registered, buy $20+ to count' : 'buy a $20+ package to register it') + '</span>'
|
||||
+ '<span class="dt">' + (p.credits || 0).toLocaleString() + ' credits</span>'
|
||||
+ '<span class="dt">' + (p.credits || 0).toLocaleString() + ' credits' + (p.balanceWei != null ? ' · ' + (Number(BigInt(p.balanceWei) / 10n ** 14n) / 10000).toLocaleString(undefined, { maximumFractionDigits: 2 }) + ' POL' : '') + '</span>'
|
||||
+ (!p.memberId ? '<button class="btn sec small" type="button" data-unlink="' + p.address + '">Unlink</button>' : '')
|
||||
+ '</div>').join('');
|
||||
const mainRow = r.main && r.main.address ? '<div class="lin-row"><span class="nm">Position 1 · main <span class="mono">' + short(r.main.address) + '</span></span>'
|
||||
+ '<span class="id">' + (r.main.memberId ? '#' + r.main.memberId : 'payouts not on yet') + '</span>'
|
||||
+ '<span class="earn on">' + (r.main.buyerCount || 0) + ' qualifying buyer(s)</span>'
|
||||
+ '<span class="dt">' + (r.main.credits || 0).toLocaleString() + ' credits</span></div>' : '';
|
||||
+ '<span class="dt">' + (r.main.credits || 0).toLocaleString() + ' credits' + (r.main.balanceWei != null ? ' · ' + (Number(BigInt(r.main.balanceWei) / 10n ** 14n) / 10000).toLocaleString(undefined, { maximumFractionDigits: 2 }) + ' POL' : '') + '</span></div>' : '';
|
||||
const html = mainRow + rows + (list.length ? '<p class="muted small" style="margin:8px 0 0">Pooled credits: <b>' + (r.totalCredits || 0).toLocaleString() + '</b>. A campaign budget spends from one position at a time.</p>' : '');
|
||||
if ($('qsList')) $('qsList').innerHTML = html;
|
||||
// Wallet tab: live POL balance of the linked wallet, and which package it covers
|
||||
const wb = $('walletBal');
|
||||
if (wb && r.main && r.main.address && r.main.balanceWei != null) {
|
||||
const polN = Number(BigInt(r.main.balanceWei) / 10n ** 14n) / 10000;
|
||||
const usd = r.polUsd ? polN * r.polUsd : 0;
|
||||
const pkgs = [5, 20, 50, 100, 250];
|
||||
const covers = r.polUsd ? pkgs.filter(p => usd >= p * 1.06 + 0.05) : [];
|
||||
wb.hidden = false;
|
||||
wb.innerHTML = 'Wallet balance: <b class="mono">' + polN.toLocaleString(undefined, { maximumFractionDigits: 2 }) + ' POL</b>' + (usd ? ' (about $' + usd.toLocaleString(undefined, { maximumFractionDigits: 0 }) + ')' : '')
|
||||
+ (r.polUsd ? '<br><span class="muted">' + (covers.length ? 'Enough for the $' + covers[covers.length - 1] + ' package with gas to spare.' : 'Not enough for the $5 package yet. Buy POL with a card on the Buy packages tab, or send POL to this wallet.') + (covers.length && covers.length < pkgs.length ? ' Top up for the $' + pkgs[covers.length] + ' package.' : '') + '</span>' : '');
|
||||
}
|
||||
if ($('posList')) $('posList').innerHTML = html;
|
||||
if ($('posCard')) $('posCard').hidden = !list.length;
|
||||
// "Buy from" picker: main + every position
|
||||
@@ -1461,7 +1488,11 @@
|
||||
$('earnBalance').textContent = st.earned + ' earned credits';
|
||||
const done = st.views >= st.target;
|
||||
$('earnClaimBtn').hidden = !(done && !st.claimed);
|
||||
if (st.claimed) $('earnHint').textContent = 'Claimed for today. Come back tomorrow, or put those credits to work in Campaigns.';
|
||||
if (st.claimed) {
|
||||
$('earnHint').textContent = 'Claimed for today. Come back tomorrow, or put those credits to work in Campaigns.';
|
||||
const box = $('earnAdBox'); if (box && !box.querySelector('.done-big')) box.innerHTML = '<div class="done-big"><span class="tick">✓</span><b>Ads done for today</b><span class="muted small">Today\'s set is viewed and claimed. Fresh ads tomorrow.</span></div>';
|
||||
if ($('earnStartBtn')) $('earnStartBtn').hidden = true;
|
||||
} else if ($('earnStartBtn')) $('earnStartBtn').hidden = false;
|
||||
else if (done) $('earnHint').textContent = 'Set complete. Claim your ' + st.claimCredits + ' credits.';
|
||||
return st;
|
||||
} catch (e) { return null; }
|
||||
|
||||
Reference in New Issue
Block a user