import * as React from 'react'; import { Document, Page, View, Text, Image, StyleSheet, Font, } from '@react-pdf/renderer'; // Register fonts (using system fonts for now, can be customized) Font.register({ family: 'Helvetica', fonts: [ { src: '/fonts/Helvetica.ttf', fontWeight: 400 }, { src: '/fonts/Helvetica-Bold.ttf', fontWeight: 700 }, ], }); // Industrial/technical/restrained design - STYLEGUIDE.md compliant const styles = StyleSheet.create({ page: { // Large margins for engineering documentation feel. // Extra bottom padding reserves space for the fixed footer so content // (esp. long descriptions) doesn't render underneath it. paddingTop: 72, paddingLeft: 72, paddingRight: 72, paddingBottom: 140, fontFamily: 'Helvetica', fontSize: 10, color: '#1F2933', // Dark gray text lineHeight: 1.5, // Generous line height backgroundColor: '#F8F9FA', // Almost white background }, // Engineering documentation header header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 48, // Large spacing paddingBottom: 24, borderBottom: '2px solid #E6E9ED', // Light gray separator }, // Logo area - industrial style logoArea: { flexDirection: 'column', alignItems: 'flex-start', }, // Optional image logo container (keeps header height stable) logoContainer: { width: 120, height: 32, justifyContent: 'center', }, // Image logo (preferred when available) logo: { width: 110, height: 28, objectFit: 'contain', }, logoText: { fontSize: 20, fontWeight: 700, color: '#0E2A47', // Dark navy letterSpacing: 1, textTransform: 'uppercase', }, logoSubtext: { fontSize: 10, fontWeight: 400, color: '#6B7280', // Medium gray letterSpacing: 0.5, marginTop: 2, }, // Document info - technical style docInfo: { textAlign: 'right', alignItems: 'flex-end', }, docTitle: { fontSize: 16, fontWeight: 700, color: '#0E2A47', // Dark navy marginBottom: 8, letterSpacing: 0.5, textTransform: 'uppercase', }, skuContainer: { backgroundColor: '#E6E9ED', // Light gray background paddingHorizontal: 16, paddingVertical: 8, border: '1px solid #E6E9ED', }, skuLabel: { fontSize: 8, color: '#6B7280', // Medium gray textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 4, }, skuValue: { fontSize: 14, fontWeight: 700, color: '#0E2A47', // Dark navy }, // Product section - technical specification style productSection: { marginBottom: 40, backgroundColor: '#FFFFFF', // White background for content blocks padding: 24, border: '1px solid #E6E9ED', }, productName: { fontSize: 24, fontWeight: 700, color: '#0E2A47', // Dark navy marginBottom: 12, lineHeight: 1.2, textTransform: 'uppercase', letterSpacing: 0.5, }, productMeta: { fontSize: 12, color: '#6B7280', // Medium gray fontWeight: 500, }, // Content sections - rectangular blocks section: { marginBottom: 32, backgroundColor: '#FFFFFF', padding: 24, border: '1px solid #E6E9ED', }, sectionTitle: { fontSize: 14, fontWeight: 700, color: '#0E2A47', // Dark navy marginBottom: 16, letterSpacing: 0.5, textTransform: 'uppercase', borderBottom: '1px solid #E6E9ED', paddingBottom: 8, }, // Description - technical documentation style description: { fontSize: 10, lineHeight: 1.6, color: '#1F2933', // Dark gray text marginBottom: 0, }, // Cross-section table - engineering specification style table: { marginTop: 16, borderWidth: 1, borderColor: '#E6E9ED', }, tableHeader: { flexDirection: 'row', backgroundColor: '#E6E9ED', borderBottomWidth: 1, borderBottomColor: '#E6E9ED', }, tableHeaderCell: { flex: 1, padding: 8, fontSize: 10, fontWeight: 700, color: '#0E2A47', textTransform: 'uppercase', letterSpacing: 0.3, }, tableHeaderCellLast: { borderRightWidth: 0, }, tableHeaderCellWithDivider: { borderRightWidth: 1, borderRightColor: '#E6E9ED', }, tableRow: { flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: '#E6E9ED', }, tableCell: { flex: 1, padding: 8, fontSize: 10, color: '#1F2933', }, tableCellLast: { borderRightWidth: 0, }, tableCellWithDivider: { borderRightWidth: 1, borderRightColor: '#E6E9ED', }, tableRowAlt: { backgroundColor: '#F8F9FA', }, // Specifications - technical data style specsContainer: { flexDirection: 'row', flexWrap: 'wrap', }, // Backwards-compatible alias used by the component markup specsGrid: { flexDirection: 'row', flexWrap: 'wrap', }, // Technical data table (used for the metagrid) specsTable: { borderWidth: 1, borderColor: '#E6E9ED', }, specsTableRow: { flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: '#E6E9ED', }, specsTableRowLast: { borderBottomWidth: 0, }, specsTableLabelCell: { flex: 3, paddingVertical: 8, paddingHorizontal: 8, backgroundColor: '#F8F9FA', borderRightWidth: 1, borderRightColor: '#E6E9ED', justifyContent: 'center', }, specsTableValueCell: { flex: 4, paddingVertical: 8, paddingHorizontal: 8, justifyContent: 'center', }, specsTableLabelText: { fontSize: 9, fontWeight: 700, color: '#0E2A47', textTransform: 'uppercase', letterSpacing: 0.3, lineHeight: 1.2, }, specsTableValueText: { fontSize: 10, color: '#1F2933', lineHeight: 1.4, }, specColumn: { width: '48%', marginRight: '4%', marginBottom: 16, }, specItem: { marginBottom: 12, }, specLabel: { fontSize: 9, fontWeight: 700, color: '#0E2A47', marginBottom: 4, textTransform: 'uppercase', letterSpacing: 0.3, }, specValue: { fontSize: 10, color: '#1F2933', lineHeight: 1.4, }, // Categories - technical classification categories: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, }, categoryTag: { backgroundColor: '#E6E9ED', paddingHorizontal: 12, paddingVertical: 6, border: '1px solid #E6E9ED', }, categoryText: { fontSize: 9, color: '#6B7280', fontWeight: 500, textTransform: 'uppercase', letterSpacing: 0.3, }, // Engineering documentation footer footer: { position: 'absolute', bottom: 48, left: 72, right: 72, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingTop: 24, borderTop: '2px solid #E6E9ED', fontSize: 9, color: '#6B7280', }, footerLeft: { fontWeight: 700, color: '#0E2A47', }, footerRight: { color: '#6B7280', }, }); interface ProductData { id: number; name: string; shortDescriptionHtml: string; descriptionHtml: string; images: string[]; featuredImage: string | null; sku: string; categories: Array<{ name: string }>; attributes: Array<{ name: string; options: string[]; }>; } interface PDFDatasheetProps { product: ProductData; locale: 'en' | 'de'; logoUrl?: string; } // Helper to strip HTML tags const stripHtml = (html: string): string => { return html.replace(/<[^>]*>/g, ''); }; // Helper to get translated labels const getLabels = (locale: 'en' | 'de') => { const labels = { en: { productDatasheet: 'Product Datasheet', description: 'Description', specifications: 'Technical Specifications', categories: 'Categories', sku: 'SKU', noImage: 'No image available', }, de: { productDatasheet: 'Produktdatenblatt', description: 'Beschreibung', specifications: 'Technische Spezifikationen', categories: 'Kategorien', sku: 'Artikelnummer', noImage: 'Kein Bild verfügbar', }, }; return labels[locale]; }; export const PDFDatasheet: React.FC = ({ product, locale, logoUrl = '/media/logo.svg', }) => { const labels = getLabels(locale); return ( {/* Clean, minimal header */} {logoUrl ? ( /* eslint-disable-next-line jsx-a11y/alt-text */ ) : ( KLZ Cables )} {locale === 'en' ? 'Product Datasheet' : 'Produktdatenblatt'} {labels.sku} {product.sku} {/* Product section - clean and prominent */} {product.name} {product.categories.map(cat => cat.name).join(' • ')} {/* Description section */} {(product.shortDescriptionHtml || product.descriptionHtml) && ( {labels.description} {stripHtml(product.shortDescriptionHtml || product.descriptionHtml)} )} {/* Technical specifications */} {product.attributes && product.attributes.length > 0 && ( {labels.specifications} {product.attributes.map((attr, index) => ( {attr.name} {attr.options.join(', ')} ))} )} {/* Categories as clean tags */} {product.categories && product.categories.length > 0 && ( {labels.categories} {product.categories.map((cat, index) => ( {cat.name} ))} )} {/* Minimal footer */} {labels.sku}: {product.sku} {new Date().toLocaleDateString(locale === 'en' ? 'en-US' : 'de-DE', { year: 'numeric', month: 'long', day: 'numeric', })} ); };