feat(layout): add preview PDF button to layout editor

Generates a 3-up PDF with dummy check data (no real checks touched) so the
layout can be proofed without printing live checks.

Closes #12
This commit is contained in:
2026-05-02 17:21:41 -06:00
parent f91fc7bd8a
commit 0b21f4ea3c
3 changed files with 79 additions and 1 deletions
+2 -1
View File
@@ -886,7 +886,8 @@
</div>
</div>
<div id="layout-save-status" style="font-size:11px;color:var(--text-muted);min-width:56px"></div>
<div style="margin-left:auto">
<div style="margin-left:auto;display:flex;gap:8px;align-items:center">
<button id="btn-layout-preview" class="btn-secondary btn-sm">⎙ Preview PDF</button>
<button id="btn-layout-reset" class="btn-secondary btn-sm" data-admin-only>↺ Reset to Default</button>
</div>
</div>
+26
View File
@@ -2007,6 +2007,7 @@ async function init() {
document.getElementById('nudge-left').addEventListener('click', () => nudgeLayoutField(-1, 0));
document.getElementById('nudge-right').addEventListener('click', () => nudgeLayoutField( 1, 0));
document.getElementById('btn-layout-reset').addEventListener('click', resetLayoutToDefault);
document.getElementById('btn-layout-preview').addEventListener('click', previewLayoutPdf);
// Initial auth check → loads app if already signed in
const authed = await checkAuth();
@@ -2456,6 +2457,31 @@ async function saveLayoutField(f) {
}
}
async function previewLayoutPdf() {
const btn = document.getElementById('btn-layout-preview');
const orig = btn.textContent;
btn.disabled = true;
btn.textContent = '…';
try {
const res = await fetch('/api/pdf/preview', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ account_id: state.activeAccountId }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({ error: res.statusText }));
throw new Error(err.error || res.statusText);
}
const blob = await res.blob();
openPdfBlob(blob, 'layout-preview.pdf');
} catch (err) {
alert('Preview error: ' + err.message);
} finally {
btn.disabled = false;
btn.textContent = orig;
}
}
async function resetLayoutToDefault() {
if (!confirm('Reset all layout fields to default positions? This cannot be undone.')) return;
try {