Skip to content
// Serve the proposal page (token required), count views, show the accept form or the current state.
const q = $('View API').first().json.query ?? {};
const p = ($getWorkflowStaticData('global').proposals ?? {})[String(q.id ?? '')];
const page = (title, msg) => `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${title}</title></head><body style="font-family:system-ui;max-width:560px;margin:4rem auto;padding:0 1rem"><h1>${title}</h1><p>${msg}</p></body></html>`;
if (!p) return [{ json: { code: 404, html: page('Proposal not found', 'Check the link in your email.') } }];
if (q.t !== p.token) return [{ json: { code: 403, html: page('Link not valid', 'Please use the link from your email.') } }];
const today = String(q.now || new Date().toISOString()).slice(0, 10);
const expired = p.status !== 'accepted' && today > p.valid_until;
if (q.preview !== '1') { p.views += 1; p.first_viewed_at ??= new Date().toISOString(); p.last_viewed_at = new Date().toISOString(); }
const s = $('Settings (edit me)').first().json;
const banner = expired ? `<p style="background:#fde68a;color:#422;padding:.8rem 1rem;border-radius:8px">This proposal expired on ${p.valid_until}. Reply to the email and we'll refresh it.</p>`
  : p.status === 'accepted' ? `<p style="background:#bbf7d0;color:#123;padding:.8rem 1rem;border-radius:8px">Accepted by ${p.accepted_by} on ${p.accepted_at.slice(0, 10)}. Thank you!</p>` : '';
const accept = expired || p.status === 'accepted' ? `<p>Questions? Reply to the email or write to ${s.owner_email}.</p>`
  : `<form method="post" action="${s.public_base_url}/webhook/prop/accept"><input type="hidden" name="id" value="${p.id}"><input type="hidden" name="t" value="${p.token}">
<p><strong>Ready to go?</strong> Type your full name to accept this proposal and its terms.</p><p><input type="text" name="name" required placeholder="Full name" autocomplete="name"></p>
<p><label><input type="checkbox" name="agree" value="yes" required> I accept the scope and the ${s.deposit_percent}% deposit</label></p><button type="submit">Accept proposal</button></form>`;
return [{ json: { code: 200, html: p.html.replace('<!--BANNER-->', banner).replace('<!--ACCEPT-->', accept) } }];