feat: add crop marks variant for print finishing
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 24s
Build & Deploy / 🏗️ Build (push) Has been cancelled
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 / 🧪 QA (push) Has been cancelled

This commit is contained in:
2026-06-12 11:47:40 +02:00
parent 09d435a1bc
commit d1cbfc41c8
18 changed files with 217 additions and 85 deletions

View File

@@ -48,12 +48,12 @@ export interface PDFBusinessCardProps {
variant?: 'blue' | 'white' | 'black';
isViaprinto?: boolean;
withTruck?: boolean;
withCropMarks?: boolean;
}
// Die Buchstaben K, L, Z im SVG (inklusive dem kleinen Stück vom Z oben links)
export const KLZ_PATHS = [25, 26, 27, 28, 29];
// Mintel Aesthetics Colors - EXACT PROD COLORS
const COLORS = {
primary: '#011dff', // Brand Royal Blue
blue: '#000a66',
@@ -66,6 +66,98 @@ const COLORS = {
lightGray: '#f8f9fa',
};
const CropMarks = () => (
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 9999 }}>
{/* Top Left */}
<View
style={{
position: 'absolute',
left: '13mm',
top: '0mm',
width: '0.25pt',
height: '10mm',
backgroundColor: '#000',
}}
/>
<View
style={{
position: 'absolute',
left: '0mm',
top: '13mm',
width: '10mm',
height: '0.25pt',
backgroundColor: '#000',
}}
/>
{/* Top Right */}
<View
style={{
position: 'absolute',
right: '13mm',
top: '0mm',
width: '0.25pt',
height: '10mm',
backgroundColor: '#000',
}}
/>
<View
style={{
position: 'absolute',
right: '0mm',
top: '13mm',
width: '10mm',
height: '0.25pt',
backgroundColor: '#000',
}}
/>
{/* Bottom Left */}
<View
style={{
position: 'absolute',
left: '13mm',
bottom: '0mm',
width: '0.25pt',
height: '10mm',
backgroundColor: '#000',
}}
/>
<View
style={{
position: 'absolute',
left: '0mm',
bottom: '13mm',
width: '10mm',
height: '0.25pt',
backgroundColor: '#000',
}}
/>
{/* Bottom Right */}
<View
style={{
position: 'absolute',
right: '13mm',
bottom: '0mm',
width: '0.25pt',
height: '10mm',
backgroundColor: '#000',
}}
/>
<View
style={{
position: 'absolute',
right: '0mm',
bottom: '13mm',
width: '10mm',
height: '0.25pt',
backgroundColor: '#000',
}}
/>
</View>
);
const styles = StyleSheet.create({
pageBleed: {
width: '91mm',
@@ -694,6 +786,7 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
variant = 'blue',
isViaprinto = false,
withTruck = true,
withCropMarks = false,
}) => {
const isWhiteVariant = variant === 'white' || variant === 'black';
@@ -730,6 +823,26 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
? path.join(process.cwd(), 'public', 'media', 'cable_drums_truck.png')
: path.join(process.cwd(), 'public', 'cable_drums_bg.png');
const renderPageWrapper = (children: React.ReactNode, bleedStyle: any) => {
if (withCropMarks) {
return (
<Page size={[315, 230]} style={{ backgroundColor: '#ffffff' }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<CropMarks />
<View style={[bleedStyle, { overflow: 'hidden', position: 'relative' }]}>
{children}
</View>
</View>
</Page>
);
}
return (
<Page size={[258, 173]} style={bleedStyle}>
{children}
</Page>
);
};
return (
<Document
title={`Business Card - ${person.name}`}
@@ -737,86 +850,85 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
creator="KLZ Print Engine"
>
{/* VORDERSEITE (Blue page with logo, truck and tagline) */}
<Page
size={[258, 173]}
style={[styles.pageBleed, isWhiteVariant && { backgroundColor: '#ffffff' }]}
>
{withTruck && (
<View style={styles.truckWrapper}>
<TruckBlueprint
style={styles.frontBackgroundImage}
opacity={isWhiteVariant ? 0.2 : 0.25}
backgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
/>
</View>
)}
<View style={styles.frontFooterArea}>
<Text style={[styles.frontTaglineBar, isWhiteVariant && { color: COLORS.black }]}>
Von 0,6/1,0 kV bis 64/110 kV
</Text>
<View style={styles.frontIconsGroup}>
<View style={styles.frontBrandIconWrapper}>
<IconLowVoltage
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
{renderPageWrapper(
<>
{withTruck && (
<View style={styles.truckWrapper}>
<TruckBlueprint
style={styles.frontBackgroundImage}
opacity={isWhiteVariant ? 0.2 : 0.25}
backgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Niederspannung
</Text>
</View>
<View style={styles.frontBrandIconWrapper}>
<IconMediumVoltage
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Mittelspannung
</Text>
</View>
<View style={styles.frontBrandIconWrapper}>
<IconHighVoltage
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Hochspannung
</Text>
</View>
<View style={styles.frontBrandIconWrapper}>
<IconSolar
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Solar
</Text>
</View>
</View>
</View>
<View style={styles.frontContainer}>
{/* Base Logo: text is white, truck is green. Fill KLZ background to hide truck, keep outline white */}
<VectorLogo
paths={getFrontLogoPaths()}
style={styles.frontLogo}
solidPaths={KLZ_PATHS}
solidBackgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
/>
{/* Letterpress Mask Layer: We use #ff00fe as a marker color. Only the "KLZ" letters! */}
{isViaprinto && (
<VectorLogo
paths={getFrontLogoPaths().filter((_, i) => KLZ_PATHS.includes(i))}
style={[styles.frontLogo, { position: 'absolute' }]}
overrideColor="#ff00fe"
solidPaths={KLZ_PATHS.map((_, i) => i)}
/>
)}
</View>
</Page>
<View style={styles.frontFooterArea}>
<Text style={[styles.frontTaglineBar, isWhiteVariant && { color: COLORS.black }]}>
Von 0,6/1,0 kV bis 64/110 kV
</Text>
<View style={styles.frontIconsGroup}>
<View style={styles.frontBrandIconWrapper}>
<IconLowVoltage
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Niederspannung
</Text>
</View>
<View style={styles.frontBrandIconWrapper}>
<IconMediumVoltage
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Mittelspannung
</Text>
</View>
<View style={styles.frontBrandIconWrapper}>
<IconHighVoltage
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Hochspannung
</Text>
</View>
{/* VORDERSEITE (White page with contact info) */}
<Page size={[258, 173]} style={styles.pageBleedBack}>
<View style={styles.frontBrandIconWrapper}>
<IconSolar
style={styles.frontBrandIcon}
color={isWhiteVariant ? COLORS.black : 'white'}
/>
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
Solar
</Text>
</View>
</View>
</View>
<View style={styles.frontContainer}>
{/* Base Logo: text is white, truck is green. Fill KLZ background to hide truck, keep outline white */}
<VectorLogo
paths={getFrontLogoPaths()}
style={styles.frontLogo}
solidPaths={KLZ_PATHS}
solidBackgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
/>
{/* Letterpress Mask Layer: We use #ff00fe as a marker color. Only the "KLZ" letters! */}
{isViaprinto && (
<VectorLogo
paths={getFrontLogoPaths().filter((_, i) => KLZ_PATHS.includes(i))}
style={[styles.frontLogo, { position: 'absolute' }]}
overrideColor="#ff00fe"
solidPaths={KLZ_PATHS.map((_, i) => i)}
/>
)}
</View>
</>,
[styles.pageBleed, isWhiteVariant && { backgroundColor: '#ffffff' }],
)}
{renderPageWrapper(
<View style={styles.backContainer}>
<View style={styles.backHeader}>
<VectorLogo
@@ -876,14 +988,15 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
</View>
</View>
</View>
</View>
<View style={styles.addressFooter}>
<Text style={styles.addressFooterText}>
KLZ Vertriebs GmbH · Raiffeisenstraße 22 · 73630 Remshalden
</Text>
</View>
</Page>
<View style={styles.addressFooter}>
<Text style={styles.addressFooterText}>
KLZ Vertriebs GmbH · Raiffeisenstraße 22 · 73630 Remshalden
</Text>
</View>
</View>,
styles.pageBleed,
)}
</Document>
);
};