Linea (the vendor's original format.pdf design), Monogram and Serenity are rebuilt from the Canva PDFs as one parametric family on the engine, with the user's logo in the measured slot, a home for every GST field and A4/Letter support. Adds static Montserrat, Open Sans and Poppins fonts and a generated Ms Madi outline for Serenity's vertical word. Text-only logo placeholders (Monolith, Tangerine) use a doc-derived allowance box. A Carbon TemplatePicker with committed thumbnails opens from the page setup controls.
47 lines
1.6 KiB
JavaScript
47 lines
1.6 KiB
JavaScript
// Renders every registered template with one fixed sample invoice into public/templates/<id>.png, the
|
|
// static thumbnails of the template picker. Run: npm run thumbnails (the PNGs are committed).
|
|
// The sample is the harness's tax invoice with Arun P's logo; the picker says that thumbnails use sample data.
|
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
import path from "node:path";
|
|
import { ROOT, loadRenderer, rasterize } from "./templates/lib.mjs";
|
|
|
|
const OUT = path.join(ROOT, "public", "templates");
|
|
const WIDTH = 420;
|
|
const A4_WIDTH_PT = 595.28;
|
|
|
|
const ITEMS = [
|
|
["Voice-over narration", 4, 1500],
|
|
["Audio mastering", 2, 800],
|
|
].map(([description, quantity, rate], i) => ({
|
|
id: i + 1,
|
|
description,
|
|
mode: "rate",
|
|
rate,
|
|
unit: "hour",
|
|
quantity,
|
|
amount: 0,
|
|
sortOrder: i,
|
|
hsnSac: "998397",
|
|
}));
|
|
|
|
const SAMPLE = {
|
|
name: "thumbnail",
|
|
items: ITEMS,
|
|
logo: "real",
|
|
signature: false,
|
|
// A leaner supplier block keeps the whole design (closing block included) on the thumbnail's one page.
|
|
vendor: { vendorEmail: "", vendorPhone: "", vendorPan: "" },
|
|
invoice: { poNumber: "", notes: "" },
|
|
};
|
|
|
|
const r = await loadRenderer();
|
|
r.ensureSetup();
|
|
mkdirSync(OUT, { recursive: true });
|
|
for (const id of Object.keys(r.TEMPLATES)) {
|
|
const rendered = await r.renderFixture(SAMPLE, r.prefsFor("A4", { templateId: id }));
|
|
const canvas = await rasterize(rendered.result.bytes, 1, WIDTH / A4_WIDTH_PT);
|
|
const file = path.join(OUT, `${id}.png`);
|
|
writeFileSync(file, canvas.toBuffer("image/png"));
|
|
console.log(`${id}: ${canvas.width} x ${canvas.height} px, ${rendered.result.pages} page(s), ${rendered.result.issues.length} audit issue(s)`);
|
|
}
|