Files
helvoirtgevelreiniging.nl/scripts/gen-homepage-media.mjs
T

101 lines
5.6 KiB
JavaScript

/**
* Wave 2b — homepage-BEELD in het CMS. Maakt twee kleine collecties:
* - `hero_cards` (3 staande werkfoto-cards in de hero)
* - `galerij` (6 foto's in de bewijs-sectie "Echt werk, echte resultaten")
* met image-rijen (een repeater kan geen image-subveld). De galerij hergebruikt de
* werk-foto's die al in R2 staan (uit 0010_diensten_media); de hero gebruikt de kleine
* -768-varianten (perf, want boven de vouw) → 2 nieuwe media-rijen + uploads.
* Print UPLOAD-regels voor de 2 nieuwe bestanden.
*/
import { ulid } from "ulidx";
import { writeFileSync, mkdirSync } from "node:fs";
import { generate } from "./gen-cms-sql.mjs";
const q = (s) => "'" + String(s).replace(/'/g, "''") + "'";
// Bestaande media uit 0010_diensten_media (storage_key == id + ".webp").
const EXIST = {
"werk-1": { id: "01KVABG8HZENXT71V00NY1M2N5", file: "werk-1.webp", w: 1200, h: 1600 },
"werk-2": { id: "01KVABG8HZSPH8YKM0GJC0WDE2", file: "werk-2.webp", w: 1600, h: 1200 },
"werk-3": { id: "01KVABG8HZN66T8KPTBWHQSFZS", file: "werk-3.webp", w: 738, h: 1600 },
"werk-4": { id: "01KVABG8HZ2H1TAB7E4J3QRCSM", file: "werk-4.webp", w: 1200, h: 1600 },
"werk-5": { id: "01KVABG8HZ9KFWV8604FYYSEAY", file: "werk-5.webp", w: 1200, h: 1600 },
"werk-6": { id: "01KVABG8HZV3AHQ5RQGVAKW29F", file: "werk-6.webp", w: 1200, h: 1600 },
};
for (const k of Object.keys(EXIST)) EXIST[k].storageKey = EXIST[k].id + ".webp";
// Nieuwe kleine hero-varianten (worden geupload + krijgen een media-rij).
const NEW = {
"werk-1-768": { file: "werk-1-768.webp", w: 768, h: 1024, size: 172718, alt: "Herstelde schoorsteen met nieuw loodwerk op een dak" },
"werk-5-768": { file: "werk-5-768.webp", w: 768, h: 1024, size: 191256, alt: "Dak wordt op hoogte gereinigd" },
};
for (const k of Object.keys(NEW)) {
NEW[k].id = ulid();
NEW[k].storageKey = NEW[k].id + ".webp";
}
function imgJson(m, alt) {
return {
id: m.id, provider: "local", filename: m.file, mimeType: "image/webp",
width: m.w, height: m.h, alt, meta: { storageKey: m.storageKey },
};
}
// ---- Model: twee image-collecties met content (image-veld = media-JSON) ----
const model = [
{
slug: "hero_cards",
label: "Homepage · hero-foto's",
labelSingular: "Hero-foto",
supports: ["drafts"],
fields: [
{ slug: "sort", label: "Volgorde", type: "integer" },
{ slug: "image", label: "Foto", type: "image", required: false },
{ slug: "title", label: "Titel (op de foto)", type: "string", required: true },
{ slug: "sub", label: "Ondertitel (op de foto)", type: "string" },
{ slug: "alt", label: "Alt-tekst", type: "string" },
],
content: [
{ slug: "card-1", status: "published", data: { sort: 1, image: imgJson(EXIST["werk-3"], "Strak nieuw voegwerk tussen bakstenen van een gevel"), title: "Voegwerk", sub: "gevel hersteld", alt: "Strak nieuw voegwerk tussen bakstenen van een gevel" } },
{ slug: "card-2", status: "published", data: { sort: 2, image: imgJson(NEW["werk-1-768"], "Herstelde schoorsteen met nieuw loodwerk op een dak"), title: "Schoorsteen", sub: "nieuw loodwerk", alt: "Herstelde schoorsteen met nieuw loodwerk op een dak" } },
{ slug: "card-3", status: "published", data: { sort: 3, image: imgJson(NEW["werk-5-768"], "Dak wordt op hoogte gereinigd"), title: "Dakreiniging", sub: "op hoogte", alt: "Dak wordt op hoogte gereinigd" } },
],
},
{
slug: "galerij",
label: "Homepage · bewijs-galerij",
labelSingular: "Galerij-foto",
supports: ["drafts"],
fields: [
{ slug: "sort", label: "Volgorde", type: "integer" },
{ slug: "image", label: "Foto", type: "image", required: false },
{ slug: "caption", label: "Bijschrift", type: "string", required: true },
{ slug: "featured", label: "Uitgelicht (grote tegel)", type: "boolean" },
],
content: [
{ slug: "g-1", status: "published", data: { sort: 1, image: imgJson(EXIST["werk-3"], "Voegwerk aan de gevel"), caption: "Voegwerk aan de gevel", featured: true } },
{ slug: "g-2", status: "published", data: { sort: 2, image: imgJson(EXIST["werk-1"], "Schoorsteen met nieuw loodwerk"), caption: "Schoorsteen met nieuw loodwerk", featured: false } },
{ slug: "g-3", status: "published", data: { sort: 3, image: imgJson(EXIST["werk-4"], "Dak vol mos, voor reiniging"), caption: "Dak vol mos, voor reiniging", featured: false } },
{ slug: "g-4", status: "published", data: { sort: 4, image: imgJson(EXIST["werk-2"], "Tuinmuur en bestrating"), caption: "Tuinmuur en bestrating", featured: false } },
{ slug: "g-5", status: "published", data: { sort: 5, image: imgJson(EXIST["werk-5"], "Dakreiniging op hoogte"), caption: "Dakreiniging op hoogte", featured: false } },
{ slug: "g-6", status: "published", data: { sort: 6, image: imgJson(EXIST["werk-6"], "Metselwerk, tuintrap"), caption: "Metselwerk, tuintrap", featured: false } },
],
},
];
// ---- Media-rijen voor de 2 nieuwe hero-varianten ----
const mediaSql = [
"-- Nieuwe hero-card-varianten in de mediabibliotheek.",
"INSERT OR REPLACE INTO media (id, filename, mime_type, size, width, height, alt, storage_key, status, created_at) VALUES",
Object.values(NEW)
.map((m) => ` (${q(m.id)}, ${q(m.file)}, 'image/webp', ${m.size}, ${m.w}, ${m.h}, ${q(m.alt)}, ${q(m.storageKey)}, 'ready', datetime('now'))`)
.join(",\n") + ";",
].join("\n");
const sql = mediaSql + "\n\n" + generate(model);
mkdirSync("migrations", { recursive: true });
writeFileSync("migrations/0011_homepage_media.sql", sql, "utf8");
for (const m of Object.values(NEW)) console.log(`UPLOAD|public/images/${m.file}|${m.storageKey}`);
console.log("geschreven: migrations/0011_homepage_media.sql");