feat: product catalog

This commit is contained in:
2026-03-02 16:20:54 +01:00
parent e9ceae3989
commit 501f9659a1
4 changed files with 112 additions and 115 deletions

View File

@@ -74,6 +74,7 @@ export interface BrochureProps {
}>;
galleryImages?: Array<string | Buffer | undefined>;
messages?: Record<string, any>;
directorPhotos?: { michael?: Buffer; klaus?: Buffer };
}
// ─── Helpers ────────────────────────────────────────────────────────────────
@@ -341,8 +342,8 @@ const InfoPage: React.FC<{
<FadeImage
src={image!}
bottom={FOOTER_H + 20} left={0} right={0}
width="100%" height={220}
fadeEdge="top" fadeSize={110}
width="100%" height={340}
fadeEdge="top" fadeSize={140}
bgColor={bg}
opacity={dark ? 0.85 : 0.9} // Extremely subtle
/>
@@ -378,7 +379,7 @@ const InfoPage: React.FC<{
borderLeftWidth: 3, borderLeftColor: C.green, borderLeftStyle: 'solid',
paddingVertical: 12, paddingHorizontal: 12,
}}>
<Text style={{ fontSize: 16, fontWeight: 700, color: dark ? C.white : C.navy, marginBottom: 4 }}>{h.value}</Text>
<Text style={{ fontSize: 10, fontWeight: 700, color: dark ? C.white : C.navy, marginBottom: 4 }}>{h.value}</Text>
<Text style={{ fontSize: 7, color: dark ? C.gray400 : C.gray600, textTransform: 'uppercase', letterSpacing: 0.5 }}>{h.label}</Text>
</View>
))}
@@ -423,7 +424,8 @@ const AboutPage: React.FC<{
logoBlack?: string | Buffer;
image?: string | Buffer;
messages?: Record<string, any>;
}> = ({ locale, companyInfo, logoBlack, image, messages }) => {
directorPhotos?: { michael?: Buffer; klaus?: Buffer };
}> = ({ locale, companyInfo, logoBlack, image, messages, directorPhotos }) => {
const l = labels(locale);
// Image at top: 200pt tall (smaller to leave more room for content)
@@ -463,18 +465,15 @@ const AboutPage: React.FC<{
{companyInfo.tagline}
</RichText>
{/* Legacy / Heritage section */}
{legacy && (
<View style={{ marginTop: 16, borderLeftWidth: 3, borderLeftColor: C.green, borderLeftStyle: 'solid', paddingLeft: 14, paddingVertical: 4 }}>
<Text style={{ fontSize: 11, fontWeight: 700, color: C.navyDeep, marginBottom: 4 }}>{legacy.title}</Text>
<RichText style={{ fontSize: 8.5, color: C.gray600, lineHeight: 1.6 }} gap={4}>
{legacy.p1}
</RichText>
<RichText style={{ fontSize: 8.5, color: C.gray600, lineHeight: 1.6 }} gap={4}>
{legacy.p2}
</RichText>
</View>
)}
{/* Company mission — makes immediately clear what KLZ does */}
<View style={{ marginTop: 12, marginBottom: 8 }}>
<RichText style={{ fontSize: 9, color: C.gray600, lineHeight: 1.7 }} gap={6}>
{locale === 'de'
? 'KLZ Cables ist Ihr Spezialist für Energiekabel von 1 kV bis 220 kV. Wir beliefern Energieversorger, Wind- und Solarparks sowie die Industrie mit VDE-geprüften Kabeln von der Niederspannung über die Mittelspannung bis zur Hochspannung. Mit einem europaweiten Netzwerk und jahrzehntelanger Erfahrung sorgen wir für zuverlässige Kabelinfrastruktur.'
: 'KLZ Cables is your specialist for power cables from 1 kV to 220 kV. We supply energy providers, wind and solar parks, and industry with VDE-certified cables from low voltage through medium voltage to high voltage. With a Europe-wide network and decades of experience, we ensure reliable cable infrastructure.'
}
</RichText>
</View>
{/* Directors — two-column */}
{(michael || klaus) && (
@@ -483,15 +482,22 @@ const AboutPage: React.FC<{
{locale === 'de' ? 'Die Geschäftsführer' : 'The Directors'}
</Text>
<View style={{ flexDirection: 'row', gap: 20 }}>
{[michael, klaus].filter(Boolean).map((person, i) => (
{[{ data: michael, photo: directorPhotos?.michael }, { data: klaus, photo: directorPhotos?.klaus }].filter(p => p.data).map((p, i) => (
<View key={i} style={{ flex: 1 }}>
<Text style={{ fontSize: 10, fontWeight: 700, color: C.navyDeep, marginBottom: 2 }}>{person.name}</Text>
<Text style={{ fontSize: 7, fontWeight: 700, color: C.green, textTransform: 'uppercase', letterSpacing: 0.8, marginBottom: 6 }}>{person.role}</Text>
<Text style={{ fontSize: 8, color: C.gray600, lineHeight: 1.6, marginBottom: 6 }}>{person.description}</Text>
{person.quote && (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 6 }}>
{p.photo && (
<Image src={p.photo} style={{ width: 32, height: 32, borderRadius: 16 }} />
)}
<View>
<Text style={{ fontSize: 10, fontWeight: 700, color: C.navyDeep, marginBottom: 1 }}>{p.data.name}</Text>
<Text style={{ fontSize: 7, fontWeight: 700, color: C.green, textTransform: 'uppercase', letterSpacing: 0.8 }}>{p.data.role}</Text>
</View>
</View>
<Text style={{ fontSize: 8, color: C.gray600, lineHeight: 1.6, marginBottom: 6 }}>{p.data.description}</Text>
{p.data.quote && (
<View style={{ borderLeftWidth: 2, borderLeftColor: C.green, borderLeftStyle: 'solid', paddingLeft: 8 }}>
<Text style={{ fontSize: 8, fontWeight: 700, color: C.navyDeep, fontStyle: 'italic', lineHeight: 1.5 }}>
„{person.quote}"
„{p.data.quote}
</Text>
</View>
)}
@@ -742,7 +748,7 @@ const BackCover: React.FC<{
export const PDFBrochure: React.FC<BrochureProps> = ({
products, locale, companyInfo, introContent,
marketingSections, logoBlack, logoWhite, galleryImages, messages,
marketingSections, logoBlack, logoWhite, galleryImages, messages, directorPhotos,
}) => {
// Cover(1) + About(1) + marketingSections.length + TOC(1) + products + BackCover(1)
const numInfoPages = 1 + (marketingSections?.length || 0);
@@ -770,7 +776,7 @@ export const PDFBrochure: React.FC<BrochureProps> = ({
<CoverPage locale={locale} introContent={introContent} logoWhite={logoWhite} galleryImages={galleryImages} />
{/* About page — image[1] */}
<AboutPage locale={locale} companyInfo={companyInfo} logoBlack={logoBlack} image={galleryImages?.[1]} messages={messages} />
<AboutPage locale={locale} companyInfo={companyInfo} logoBlack={logoBlack} image={galleryImages?.[1]} messages={messages} directorPhotos={directorPhotos} />
{/* Info sections — images[2..] each unique, alternating top/bottom and light/dark */}
{marketingSections?.map((section, i) => (