diff --git a/public/app.js b/public/app.js deleted file mode 100644 index 4040a43..0000000 --- a/public/app.js +++ /dev/null @@ -1,93 +0,0 @@ -function openSignup() { - document.getElementById('signupModal').classList.add('active'); - document.getElementById('signupForm').style.display = 'block'; - document.getElementById('keyResult').style.display = 'none'; - document.getElementById('signupEmail').value = ''; - document.getElementById('signupError').style.display = 'none'; - setTimeout(function() { document.getElementById('signupEmail').focus(); }, 100); -} - -function closeSignup() { - document.getElementById('signupModal').classList.remove('active'); -} - -// Close on overlay click -document.getElementById('signupModal').addEventListener('click', function(e) { - if (e.target === this) closeSignup(); -}); - -// Submit on Enter -document.getElementById('signupEmail').addEventListener('keydown', function(e) { - if (e.key === 'Enter') submitSignup(); -}); - -async function submitSignup() { - var email = document.getElementById('signupEmail').value.trim(); - var errEl = document.getElementById('signupError'); - var btn = document.getElementById('signupBtn'); - - if (!email) { - errEl.textContent = 'Please enter your email.'; - errEl.style.display = 'block'; - return; - } - - btn.textContent = 'Creating...'; - btn.disabled = true; - - try { - var res = await fetch('/v1/signup/free', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email: email }) - }); - var data = await res.json(); - - if (!res.ok) { - errEl.textContent = data.error || 'Something went wrong.'; - errEl.style.display = 'block'; - btn.textContent = 'Get API Key'; - btn.disabled = false; - return; - } - - // Show key - document.getElementById('signupForm').style.display = 'none'; - document.getElementById('keyResult').style.display = 'block'; - document.getElementById('apiKeyDisplay').textContent = data.apiKey; - } catch (err) { - errEl.textContent = 'Network error. Please try again.'; - errEl.style.display = 'block'; - btn.textContent = 'Get API Key'; - btn.disabled = false; - } -} - -function copyKey() { - var key = document.getElementById('apiKeyDisplay').textContent; - navigator.clipboard.writeText(key).then(function() { - var btn = document.getElementById('apiKeyDisplay'); var origText = btn.textContent; btn.textContent = 'Copied!'; document.querySelector('.copy-hint').textContent = '✓ Copied!'; - setTimeout(function() { btn.textContent = origText; document.querySelector('.copy-hint').textContent = 'Click to copy'; - }); -} - -async function checkout() { - try { - var res = await fetch('/v1/billing/checkout', { method: 'POST' }); - var data = await res.json(); - if (data.url) window.location.href = data.url; - else alert('Something went wrong. Please try again.'); - } catch (err) { - alert('Something went wrong. Please try again.'); - } -} - -// BUG-005 fix: attach all click handlers via JS instead of inline onclick -document.addEventListener('DOMContentLoaded', function() { - document.getElementById('btn-signup').addEventListener('click', openSignup); - document.getElementById('btn-signup-2').addEventListener('click', openSignup); - document.getElementById('btn-checkout').addEventListener('click', checkout); - document.getElementById('btn-close-signup').addEventListener('click', closeSignup); - document.getElementById('signupBtn').addEventListener('click', submitSignup); - document.getElementById('apiKeyDisplay').addEventListener('click', copyKey); -}); diff --git a/public/index.html b/public/index.html index b93fb9a..b7fd8fc 100644 --- a/public/index.html +++ b/public/index.html @@ -91,7 +91,7 @@ footer { padding: 40px 0; text-align: center; color: var(--muted); font-size: 0.

HTML & Markdown to PDF

One API call. Beautiful PDFs. Built-in invoice templates. No headless browser setup, no dependencies, no hassle.

- + View Docs
@@ -193,7 +193,7 @@ footer { padding: 40px 0; text-align: center; color: var(--muted); font-size: 0.
  • All templates
  • Community support
  • - +
    @@ -220,24 +220,108 @@ footer { padding: 40px 0; text-align: center; color: var(--muted); font-size: 0. - + diff --git a/src/routes/templates.ts b/src/routes/templates.ts index d65a518..dd7ca01 100644 --- a/src/routes/templates.ts +++ b/src/routes/templates.ts @@ -25,7 +25,7 @@ templatesRouter.post("/:id/render", async (req: Request, res: Response) => { return; } - const data = req.body.data || req.body; + const data = req.body; const html = renderTemplate(id, data); const pdf = await renderPdf(html, { format: data._format || "A4", diff --git a/src/services/browser.ts b/src/services/browser.ts index 0f2efb4..acb831a 100644 --- a/src/services/browser.ts +++ b/src/services/browser.ts @@ -39,10 +39,10 @@ export async function renderPdf( landscape: options.landscape || false, printBackground: options.printBackground !== false, margin: options.margin || { - top: "0", - right: "0", - bottom: "0", - left: "0", + top: "20mm", + right: "15mm", + bottom: "20mm", + left: "15mm", }, headerTemplate: options.headerTemplate, footerTemplate: options.footerTemplate, @@ -79,10 +79,10 @@ export async function renderUrlPdf( landscape: options.landscape || false, printBackground: options.printBackground !== false, margin: options.margin || { - top: "0", - right: "0", - bottom: "0", - left: "0", + top: "20mm", + right: "15mm", + bottom: "20mm", + left: "15mm", }, });