Page Builder fixes from Marty's test: our own CSP frame-src blocked framing our member pages (preview showed broken) — add 'self'; /p/<id> now sends explicit permissive framing headers so member pages always render embedded; button label tracks whether a page exists; live progress line with step narration + elapsed seconds; stale preview hidden during rebuild and cache-busted after

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-28 08:56:32 -05:00
parent be2d2719e5
commit 6c73b5d9c5
3 changed files with 48 additions and 6 deletions
+1
View File
@@ -60,6 +60,7 @@
<button id="pgGo" class="btn btn-primary">🧱 Build my page</button>
<span id="pgMeter"></span>
</div>
<div id="pgProg" style="display:none;margin-top:10px;font-size:13.5px;color:var(--teal);font-weight:600"></div>
<div id="pgErr"></div>
</div>
+40 -4
View File
@@ -24,15 +24,46 @@
$('pgMeter').innerHTML = '<b>' + m.remaining + '</b> of ' + m.limit + ' page builds left this month';
}
var built = false;
function showLive(url) {
built = true;
$('pgUrl').textContent = url.replace(/^https:\/\//, '');
$('pgOpen').href = url;
$('pgLive').style.display = 'block';
$('pgFrame').src = url + '?preview=1';
// cache-bust so a rebuild always shows the NEW page, not the old one
$('pgFrame').src = url + '?preview=' + Date.now();
$('pgPrev').style.display = 'block';
$('pgGo').textContent = '🔁 Rebuild my page';
}
// Live status under the button. A silent 40-second wait reads as "frozen",
// so we narrate it and count the seconds.
var progTimer = null;
function startProgress() {
var el = $('pgProg'), t0 = Date.now();
var steps = [
'Reading your notes…',
'Writing your headline and story…',
'Choosing your angle video…',
'Laying out your page…',
'Almost there — finishing up…'
];
el.style.display = 'block';
var tick = function () {
var s = Math.round((Date.now() - t0) / 1000);
var i = Math.min(steps.length - 1, Math.floor(s / 9));
el.innerHTML = '<span class="spin"></span>' + steps[i] + ' <span style="opacity:.65">(' + s + 's)</span>';
};
tick();
progTimer = setInterval(tick, 1000);
}
function stopProgress() {
if (progTimer) clearInterval(progTimer);
progTimer = null;
$('pgProg').style.display = 'none';
}
function gate(msg) {
var g = $('pgGate');
g.style.display = 'block';
@@ -74,8 +105,12 @@
busy = true;
$('pgErr').style.display = 'none';
$('pgGo').disabled = true;
var label = $('pgGo').textContent;
$('pgGo').innerHTML = '<span class="spin"></span>Writing your page… (up to a minute)';
// Hide any previous preview while the new one is being written, so a stale
// or half-loaded frame can't look like a broken result.
$('pgPrev').style.display = 'none';
$('pgFrame').removeAttribute('src');
$('pgGo').innerHTML = '<span class="spin"></span>Writing your page…';
startProgress();
try {
var r = await fetch('/api/public/suite-page', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
@@ -100,9 +135,10 @@
$('pgErr').textContent = 'Connection hiccup — try again.';
$('pgErr').style.display = 'block';
}
stopProgress();
busy = false;
$('pgGo').disabled = false;
$('pgGo').textContent = label.indexOf('Rebuild') !== -1 ? '🔁 Rebuild my page' : '🧱 Build my page';
$('pgGo').textContent = built ? '🔁 Rebuild my page' : '🧱 Build my page';
}
document.addEventListener('DOMContentLoaded', function () {