Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 8s
Build & Deploy / 🧪 QA (push) Successful in 1m22s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
85 lines
2.6 KiB
TypeScript
85 lines
2.6 KiB
TypeScript
'use server';
|
|
|
|
import * as React from 'react';
|
|
import { renderToBuffer } from '@react-pdf/renderer';
|
|
import { getAllProducts } from '@/lib/products';
|
|
import { getExcelTechnicalDataForProduct } from '@/lib/excel-products';
|
|
import { PDFBrochure } from '@/lib/pdf-brochure';
|
|
import { ProductData as PDFProductData } from '@/lib/pdf-datasheet';
|
|
|
|
/**
|
|
* Server action to generate a PDF brochure.
|
|
* Fetches products from Payload CMS and technical data from Excel.
|
|
* Returns the PDF as a base64 string.
|
|
*/
|
|
export async function generateBrochureAction(params: {
|
|
locale: 'en' | 'de';
|
|
productSlugs?: string[];
|
|
title?: string;
|
|
subtitle?: string;
|
|
}) {
|
|
try {
|
|
const { locale, productSlugs, title, subtitle } = params;
|
|
|
|
// 1. Fetch products from Payload
|
|
let products = await getAllProducts(locale);
|
|
|
|
// 2. Filter by slugs if provided
|
|
if (productSlugs && productSlugs.length > 0) {
|
|
products = products.filter((p) => productSlugs.includes(p.slug));
|
|
}
|
|
|
|
// 3. Map Payload products to PDF internal model and attach Excel data
|
|
const pdfProducts: PDFProductData[] = products.map((p, index) => {
|
|
// Get technical data from Excel
|
|
const excelData = getExcelTechnicalDataForProduct({
|
|
slug: p.slug,
|
|
sku: p.frontmatter.sku,
|
|
name: p.frontmatter.title,
|
|
});
|
|
|
|
return {
|
|
id: index + 1,
|
|
name: p.frontmatter.title,
|
|
sku: p.frontmatter.sku,
|
|
shortDescriptionHtml: p.frontmatter.description,
|
|
descriptionHtml: p.frontmatter.description,
|
|
// Application text is usually part of description in Payload v3
|
|
applicationHtml: '',
|
|
featuredImage: p.frontmatter.images[0] || null,
|
|
images: p.frontmatter.images,
|
|
categories: p.frontmatter.categories.map((name) => ({ name })),
|
|
attributes: excelData?.attributes || [],
|
|
};
|
|
});
|
|
|
|
if (pdfProducts.length === 0) {
|
|
throw new Error('No products found for brochure generation.');
|
|
}
|
|
|
|
// 4. Render to PDF buffer
|
|
// Note: React 19 / Next 15+ might need specific handling for renderToBuffer in actions
|
|
const buffer = await renderToBuffer(
|
|
React.createElement(PDFBrochure, {
|
|
products: pdfProducts,
|
|
locale,
|
|
title,
|
|
subtitle,
|
|
})
|
|
);
|
|
|
|
// 5. Convert to Base64 for returning to client
|
|
return {
|
|
success: true,
|
|
data: buffer.toString('base64'),
|
|
fileName: `KLZ_Cables_Brochure_${locale.toUpperCase()}.pdf`,
|
|
};
|
|
} catch (error) {
|
|
console.error('[Action] Brochure generation failed:', error);
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
};
|
|
}
|
|
}
|