// Funnel Factory client — lists the member's pages and builds new named ones. (function () { 'use strict'; var $ = function (id) { return document.getElementById(id); }; function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } var state = { angles: {}, angle: 'overview', id: null, pages: [] }; function gate(msg) { $('fGate').style.display = 'block'; $('fGate').innerHTML = msg; } function renderAngles() { var host = $('fAngles'); host.innerHTML = ''; Object.keys(state.angles).forEach(function (k) { var b = document.createElement('button'); b.type = 'button'; b.className = 'f-chip' + (state.angle === k ? ' on' : ''); b.textContent = state.angles[k].label || k; b.addEventListener('click', function () { state.angle = k; renderAngles(); }); host.appendChild(b); }); } function renderPages() { var host = $('fPages'); host.innerHTML = ''; if (!state.pages.length) { host.innerHTML = '
You have no pages yet. Build your main one in the ' + 'Page Builder first, then add more here.
'; return; } state.pages.forEach(function (p) { var row = document.createElement('div'); row.className = 'f-page' + (p.slug ? '' : ' main'); var left = document.createElement('div'); left.style.minWidth = '210px'; left.innerHTML = '
' + esc(p.name || 'Page') + (p.slug ? '' : ' MAIN') + '
' + '
rmcircle.team' + esc(p.url) + '
' + '
' + esc((state.angles[p.angle] && state.angles[p.angle].label) || p.angle || '') + (p.updatedAt ? ' · updated ' + esc(String(p.updatedAt).slice(0, 10)) : '') + '
'; row.appendChild(left); var acts = document.createElement('div'); acts.className = 'f-acts'; var view = document.createElement('a'); view.className = 'btn btn-secondary btn-sm'; view.href = p.url; view.target = '_blank'; view.rel = 'noopener'; view.textContent = 'View'; acts.appendChild(view); var copy = document.createElement('button'); copy.className = 'btn btn-secondary btn-sm'; copy.textContent = 'Copy link'; copy.addEventListener('click', function () { var full = 'https://rmcircle.team' + p.url; if (navigator.clipboard) navigator.clipboard.writeText(full); copy.textContent = 'Copied'; setTimeout(function () { copy.textContent = 'Copy link'; }, 1400); }); acts.appendChild(copy); if (p.slug) { var del = document.createElement('button'); del.className = 'btn btn-secondary btn-sm'; del.textContent = 'Delete'; del.addEventListener('click', function () { removePage(p.slug, p.name, del); }); acts.appendChild(del); } row.appendChild(acts); host.appendChild(row); }); } async function removePage(slug, name, btn) { if (!window.confirm('Delete "' + name + '"? Anything already pointing at that address will fall back to your main page.')) return; btn.disabled = true; try { var r = await fetch('/api/public/suite-funnel', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ remove: slug }) }); var d = await r.json(); if (r.ok) { state.pages = d.pages || []; renderPages(); } else { btn.disabled = false; } } catch (e) { btn.disabled = false; } } async function build() { $('fErr').style.display = 'none'; $('fOk').style.display = 'none'; var name = $('fName').value.trim(); if (name.length < 2) { $('fErr').textContent = 'Give the page a short name first.'; $('fErr').style.display = 'block'; return; } $('fGo').disabled = true; $('fGo').innerHTML = 'Writing your page…'; try { var r = await fetch('/api/public/suite-funnel', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name, angle: state.angle, audience: $('fAud').value.trim(), story: $('fStory').value.trim() }) }); var d = await r.json(); if (!r.ok) { $('fErr').textContent = d.error || 'That did not build — try again.'; $('fErr').style.display = 'block'; } else { state.pages = d.pages || []; renderPages(); if (d.meter) $('fMeter').textContent = d.meter.remaining + ' of ' + d.meter.limit + ' page builds left this month'; $('fOk').innerHTML = '✅ Built. It is live at ' + esc(d.url) + ''; $('fOk').style.display = 'block'; $('fName').value = ''; $('fAud').value = ''; $('fStory').value = ''; } } catch (e) { $('fErr').textContent = 'Connection hiccup — try again.'; $('fErr').style.display = 'block'; } $('fGo').disabled = false; $('fGo').innerHTML = '🏗️ Build this page'; } async function boot() { try { var r = await fetch('/api/public/suite-funnel'); if (r.status === 401) { gate('You’re not signed in yet. Open the Suite and connect the wallet that holds your position, then come back.'); return; } if (r.status === 403) { var g = await r.json(); gate((g.error || 'Not open for this position yet.') + ' See your Suite.'); return; } if (!r.ok) return; var d = await r.json(); state.angles = d.angles || {}; state.pages = d.pages || []; state.id = d.id; $('fIdA').textContent = d.id; if (d.meter) $('fMeter').textContent = d.meter.remaining + ' of ' + d.meter.limit + ' page builds left this month'; $('fBody').style.display = 'block'; renderAngles(); renderPages(); } catch (e) {} } document.addEventListener('DOMContentLoaded', function () { boot(); $('fGo').addEventListener('click', build); }); })();