1aab52ca90
- Profile pane: avatar upload + bio, with a link to your public page - Wall becomes a bio page: avatar, bio, scannable join QR, line ladder, join CTA - qrcode npm dep; /api/qr renders SVG QR server-side (CSP-clean img) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
39 lines
1.9 KiB
JavaScript
39 lines
1.9 KiB
JavaScript
// Public banner wall: a member's line banner plus their upline ladder, with
|
||
// their join link. The viral surface: members send traffic here, every visit
|
||
// puts eyes on the whole line.
|
||
(async function () {
|
||
await IAP.renderNav('');
|
||
const name = location.pathname.split('/').pop();
|
||
let w = null;
|
||
try { w = await (await fetch('/api/wall/' + encodeURIComponent(name))).json(); } catch (e) {}
|
||
const title = IAP.$('wallTitle');
|
||
if (!w || w.error) {
|
||
title.textContent = 'No wall under that name.';
|
||
IAP.$('wallJoin').href = '/my';
|
||
return;
|
||
}
|
||
const safeName = String(w.name).replace(/[&<>]/g, '');
|
||
title.innerHTML = safeName;
|
||
IAP.$('bioHead').hidden = false;
|
||
if (w.avatarUrl) { const av = IAP.$('bioAvatar'); av.src = w.avatarUrl; av.hidden = false; }
|
||
IAP.$('bioText').textContent = w.bio || 'Building a team on InstantAdPay — join through this page and you\'re in my line.';
|
||
if (w.qrUrl) IAP.$('bioQr').src = w.qrUrl;
|
||
IAP.$('wallCtaHead').textContent = 'Join ' + w.name + '’s line';
|
||
IAP.$('wallJoin').href = w.joinUrl;
|
||
const grid = IAP.$('wallGrid');
|
||
grid.innerHTML = '';
|
||
w.ladder.forEach((m, i) => {
|
||
const d = document.createElement('div');
|
||
d.className = 'wall-card';
|
||
const safe = String(m.name || 'member').replace(/[&<>]/g, '');
|
||
d.innerHTML = '<div class="wall-pos">Position ' + (i + 1) + (i === 0 ? ' · this wall' : '') + '</div>'
|
||
+ (m.bannerUrl
|
||
? '<a href="' + m.targetUrl + '" target="_blank" rel="noopener nofollow"><img src="' + m.bannerUrl + '" alt="' + safe + ' banner"></a>'
|
||
: m.targetUrl
|
||
? '<a href="' + m.targetUrl + '" target="_blank" rel="noopener nofollow"><b>' + safe + '</b><br><span class="muted small">visit their site</span></a>'
|
||
: '<b>' + safe + '</b><br><span class="muted small">banner slot open</span>')
|
||
+ '<div class="small muted" style="margin-top:8px">' + safe + '</div>';
|
||
grid.appendChild(d);
|
||
});
|
||
})();
|