feat: product catalog

This commit is contained in:
2026-03-02 15:41:26 +01:00
parent ec3f2cf8c9
commit e9ceae3989
5 changed files with 439 additions and 241 deletions

View File

@@ -395,29 +395,39 @@ async function main(): Promise<void> {
console.log(`Logos: white=${!!logoWhite} black=${!!logoBlack}`);
// Load gallery images — 7 diverse images for different sections
const galleryPaths = [
'uploads/2024/12/DSC07433-Large-600x400.webp', // 0: Cover
'uploads/2024/12/DSC07460-Large-600x400.webp', // 1: About section
'uploads/2025/01/technicians-inspecting-wind-turbines-in-a-green-en-2024-12-09-01-25-20-utc-scaled.webp', // 2: After "Was wir tun"
'uploads/2025/01/power-grid-station-electrical-distribution-statio-2023-11-27-05-25-36-utc-scaled.webp', // 3: After Legacy
'uploads/2025/01/transportation-and-logistics-trucking-2023-11-27-04-54-40-utc-scaled.webp', // 4: After Experience
'uploads/2024/12/DSC07539-Large-600x400.webp', // 5: TOC page
'uploads/2025/01/business-planning-hand-using-laptop-for-working-te-2024-11-01-21-25-44-utc-scaled.webp', // 6: Back cover
// EXACT image mapping to website sections to prevent "random" images.
// Index map: 0=Cover, 1=About, 2=WhatWeDo, 3=Legacy, 4=Experience, 5=WhyChooseUs, 6=Team, 7=Manifesto, 8=BackCover
const galleryPaths: Array<string | null> = [
'uploads/2024/12/DSC07655-Large.webp', // 0: Cover (Hero)
'uploads/2024/12/DSC07460-Large-600x400.webp', // 1: About section
null, // 2: What we do (NO IMAGE)
'uploads/2024/12/1694273920124-copy.webp', // 3: Legacy (Matching Team page)
'uploads/2024/12/1694273920124-copy-2.webp', // 4: Experience (Matching Home page)
null, // 5: Why choose us (NO IMAGE)
'uploads/2024/12/DSC08036-Large.webp', // 6: Team (Matching Team page)
null, // 7: Manifesto (NO IMAGE)
'uploads/2024/12/DSC07433-Large-600x400.webp', // 8: Back cover
];
const galleryImages: (string | Buffer)[] = [];
const galleryImages: (string | Buffer | undefined)[] = [];
for (const gp of galleryPaths) {
if (!gp) {
galleryImages.push(undefined);
continue;
}
const fullPath = path.join(process.cwd(), 'public', gp);
if (fs.existsSync(fullPath)) {
try {
const buf = await sharp(fullPath).png({ quality: 80 }).resize(600).toBuffer();
const buf = await sharp(fullPath).png({ quality: 80 }).resize(800).toBuffer();
galleryImages.push(buf);
} catch { /* skip */ }
} catch {
galleryImages.push(undefined);
}
} else {
galleryImages.push(Buffer.alloc(0)); // placeholder to maintain index mapping
galleryImages.push(undefined);
}
}
console.log(`Gallery images loaded: ${galleryImages.filter(b => (b as Buffer).length > 0).length}`);
console.log(`Gallery images mapping complete. Succeeded bindings: ${galleryImages.filter(b => b !== undefined).length}`);
for (const locale of locales) {
console.log(`\nGenerating ${locale.toUpperCase()} brochure...`);
@@ -430,12 +440,19 @@ async function main(): Promise<void> {
if (products.length === 0) continue;
const companyInfo = getCompanyInfo(locale);
// Load messages for About page content (directors, legacy, etc.)
let messages: Record<string, any> | undefined;
try {
const messagesPath = path.join(process.cwd(), `messages/${locale}.json`);
messages = JSON.parse(fs.readFileSync(messagesPath, 'utf-8'));
} catch { /* messages are optional */ }
try {
// Render the React-PDF brochure
const buffer = await renderToBuffer(
React.createElement(PDFBrochure, {
products, locale, companyInfo, introContent,
marketingSections, logoBlack, logoWhite, galleryImages,
marketingSections, logoBlack, logoWhite, galleryImages, messages,
} as any) as any
);

14
scripts/inspect-start2.ts Normal file
View File

@@ -0,0 +1,14 @@
import { getPayload } from 'payload';
import configPromise from '../payload.config';
async function main() {
const payload = await getPayload({ config: configPromise });
const result = await payload.find({
collection: 'pages',
where: { slug: { equals: 'start' } },
locale: 'de',
depth: 2,
});
console.log(JSON.stringify(result.docs[0], null, 2));
}
main().catch(console.error);