// 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'); const hostEl = IAP.$('wallHost'); 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; if (hostEl) hostEl.innerHTML = safeName; IAP.$('bioHead').hidden = false; if (w.avatarUrl) { const av = IAP.$('bioAvatar'); av.src = w.avatarUrl; av.hidden = false; } if (w.badge) { const bb = IAP.$('bioBadge'); if (bb) { bb.src = w.badge.img; bb.title = w.badge.label + ' badge'; bb.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; // social links const SOC = { facebook: 'Facebook', twitter: 'X', youtube: 'YouTube', instagram: 'Instagram', tiktok: 'TikTok', telegram: 'Telegram', linkedin: 'LinkedIn', website: 'Website' }; // small line icons, one per platform (currentColor so they follow the pill color) const svg = inner => ''; const ICON = { facebook: svg(''), twitter: svg(''), youtube: svg(''), instagram: svg(''), tiktok: svg(''), telegram: svg(''), linkedin: svg(''), website: svg('') }; const sc = IAP.$('bioSocials'); if (sc && w.socials && typeof w.socials === 'object') { const links = Object.keys(SOC).filter(k => w.socials[k]).map(k => '' + (ICON[k] || '') + '' + SOC[k] + ''); sc.innerHTML = links.join(''); } IAP.$('wallCtaHead').textContent = 'Join ' + w.name + '’s line'; // per-wall viewed-position memory (survives revisits; anonymous-friendly) const VKEY = 'iap-wall-' + name; let viewed = {}; try { viewed = JSON.parse(localStorage.getItem(VKEY) || '{}'); } catch (e) {} const DWELL = 10; const grid = IAP.$('wallGrid'); IAP.adSlot('text', 'adSlotWallText'); IAP.adSlot('banner', 'adSlotWallBanner'); grid.innerHTML = ''; // join is gated: you must view every ad on the wall before you can join const joinBtn = IAP.$('wallJoin'), gate = IAP.$('wallGate'); function updateGate() { const viewable = w.ladder.filter(m => m.targetUrl).length; const seen = w.ladder.filter((m, i) => m.targetUrl && viewed[i]).length; if (viewable > 0 && seen < viewable) { joinBtn.classList.add('disabled'); joinBtn.removeAttribute('href'); if (gate) { gate.hidden = false; gate.textContent = 'View all ' + viewable + ' ads above to unlock joining (' + seen + '/' + viewable + ' viewed).'; } } else { joinBtn.href = w.joinUrl; joinBtn.classList.remove('disabled'); if (gate) gate.hidden = true; } } w.ladder.forEach((m, i) => { const d = document.createElement('div'); d.className = 'wall-card'; const safe = String(m.name || 'member').replace(/[&<>]/g, ''); const creative = m.bannerUrl ? '' + safe + ' banner' : '' + safe + '
' + (m.targetUrl ? 'visit their site' : 'banner slot open') + ''; d.innerHTML = '
Position ' + (i + 1) + (m.own ? ' · this wall' : m.admin ? ' · InstantAdPay' : ' · their line') + '
' + '
' + creative + '
' + '
' + '
' + safe + '
'; const act = d.querySelector('.wc-action'); const done = () => { act.innerHTML = '✓ viewed'; }; if (!m.targetUrl) { act.innerHTML = 'no ad yet'; } else if (viewed[i]) { done(); } else { const btn = document.createElement('button'); btn.className = 'btn small'; btn.textContent = 'View this ad'; btn.addEventListener('click', () => { window.open(m.targetUrl, '_blank'); // real visit to the advertiser (no countdown) viewed[i] = 1; try { localStorage.setItem(VKEY, JSON.stringify(viewed)); } catch (e) {} done(); updateGate(); }); act.appendChild(btn); } grid.appendChild(d); }); updateGate(); })();