refactor: Replace PDF quote generation script with a new estimate generator and update PDF component styling.

This commit is contained in:
2026-02-04 16:51:01 +01:00
parent 226de83d0f
commit 4bba61078a
8 changed files with 16 additions and 15 deletions

View File

@@ -14,7 +14,7 @@
"test:file-examples": "tsx ./scripts/test-file-examples-comprehensive.ts",
"clone-website": "tsx ./scripts/clone-recursive.ts",
"clone-page": "tsx ./scripts/clone-page.ts",
"generate-quote": "tsx ./scripts/generate-quote.ts",
"generate-estimate": "tsx ./scripts/generate-estimate.ts",
"ai-estimate": "tsx ./scripts/ai-estimate.ts",
"video:preview": "remotion preview video/index.ts",
"video:render": "remotion render video/index.ts ButtonShowcase out/button-showcase.mp4",

View File

@@ -145,7 +145,7 @@ async function main() {
console.log('📄 Generating PDF estimation...');
try {
const genArgs = isEstimation ? '--estimation' : '';
execSync(`npx tsx ./scripts/generate-quote.ts --input ${tempJsonPath} ${genArgs}`, { stdio: 'inherit' });
execSync(`npx tsx ./scripts/generate-estimate.ts --input ${tempJsonPath} ${genArgs}`, { stdio: 'inherit' });
} finally {
// await fs.unlink(tempJsonPath);
}

View File

@@ -199,7 +199,7 @@ export const pdfStyles = StyleSheet.create({
industrialBulletBox: {
width: 6,
height: 6,
backgroundColor: COLORS.CHARCOAL,
backgroundColor: COLORS.DIVIDER,
marginRight: 8,
marginTop: 5,
},
@@ -296,7 +296,7 @@ export const Footer = ({ logo, companyData, bankData, showDetails = true, showPa
);
export const Header = ({ sender, recipient, icon, showAddress = true }: { sender?: string; recipient?: { title: string; subtitle?: string; email?: string; address?: string; phone?: string; taxId?: string }; icon?: string; showAddress?: boolean; }) => (
<PDFView style={[pdfStyles.header, showAddress ? {} : { minHeight: 60, marginBottom: 10 }]}><PDFView style={pdfStyles.addressBlock}>{showAddress && sender && (<><PDFText style={pdfStyles.senderLine}>{sender}</PDFText>{recipient && (<PDFView style={pdfStyles.recipientAddress}><PDFText style={{ fontWeight: 'bold' }}>{recipient.title}</PDFText>{recipient.subtitle && <PDFText>{recipient.subtitle}</PDFText>}{recipient.address && <PDFText>{recipient.address}</PDFText>}{recipient.phone && <PDFText>{recipient.phone}</PDFText>}{recipient.email && <PDFText>{recipient.email}</PDFText>}{recipient.taxId && <PDFText>USt-ID: {recipient.taxId}</PDFText>}</PDFView>)}</>)}</PDFView><PDFView style={pdfStyles.brandLogoContainer}><PDFView style={pdfStyles.brandIconContainer}>{icon ? (<PDFImage src={icon} style={{ width: 24, height: 24 }} />) : (<PDFText style={pdfStyles.brandIconText}>M</PDFText>)}</PDFView></PDFView></PDFView>
<PDFView style={[pdfStyles.header, showAddress ? {} : { minHeight: 40, marginBottom: 0 }]}><PDFView style={pdfStyles.addressBlock}>{showAddress && sender && (<><PDFText style={pdfStyles.senderLine}>{sender}</PDFText>{recipient && (<PDFView style={pdfStyles.recipientAddress}><PDFText style={{ fontWeight: 'bold' }}>{recipient.title}</PDFText>{recipient.subtitle && <PDFText>{recipient.subtitle}</PDFText>}{recipient.address && <PDFText>{recipient.address}</PDFText>}{recipient.phone && <PDFText>{recipient.phone}</PDFText>}{recipient.email && <PDFText>{recipient.email}</PDFText>}{recipient.taxId && <PDFText>USt-ID: {recipient.taxId}</PDFText>}</PDFView>)}</>)}</PDFView><PDFView style={pdfStyles.brandLogoContainer}><PDFView style={pdfStyles.brandIconContainer}>{icon ? (<PDFImage src={icon} style={{ width: 24, height: 24 }} />) : (<PDFText style={pdfStyles.brandIconText}>M</PDFText>)}</PDFView></PDFView></PDFView>
);
export const DocumentTitle = ({ title, subLines }: { title: string; subLines?: string[] }) => (

View File

@@ -6,7 +6,8 @@ import { Header, Footer, pdfStyles, BlueprintBackground } from './SharedUI';
const simpleStyles = StyleSheet.create({
industrialPage: {
padding: 40,
padding: 30,
paddingTop: 20,
backgroundColor: '#ffffff',
},
industrialNumber: {
@@ -19,8 +20,8 @@ const simpleStyles = StyleSheet.create({
zIndex: -1,
},
industrialSection: {
marginTop: 32,
paddingTop: 24,
marginTop: 16,
paddingTop: 12,
flexDirection: 'row',
position: 'relative',
},

View File

@@ -14,7 +14,7 @@ const styles = StyleSheet.create({
industrialBulletBox: {
width: 6,
height: 6,
backgroundColor: COLORS.CHARCOAL,
backgroundColor: COLORS.DIVIDER,
marginRight: 8,
marginTop: 5,
},

View File

@@ -72,7 +72,7 @@ export const TransparenzModule = ({ pricing }: any) => (
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>6. Integrationen</PDFText>
<PDFText style={styles.pricingDesc}>Ich binde Drittsysteme wie CRM, ERP oder Stripe an. Ich richte CMS-Schnittstellen zur unabhängigen Inhaltsverwaltung ein.</PDFText>
<PDFText style={styles.pricingTag}>ab {pricing.API_INTEGRATION?.toLocaleString('de-DE')} / Stück</PDFText>
<PDFText style={styles.pricingTag}>ab {pricing.API_INTEGRATION?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView>
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>7. Betrieb (12 Monate)</PDFText>

View File

@@ -10,12 +10,12 @@ const styles = StyleSheet.create({
sitemapTree: { marginTop: 8 },
rootNode: {
padding: 12,
backgroundColor: COLORS.CHARCOAL,
backgroundColor: COLORS.GRID,
marginBottom: 20,
borderLeftWidth: 3,
borderLeftColor: COLORS.TEXT_LIGHT
borderLeftWidth: 2,
borderLeftColor: COLORS.CHARCOAL
},
rootTitle: { fontSize: FONT_SIZES.H3, fontWeight: 'bold', color: COLORS.WHITE, letterSpacing: 0.5 },
rootTitle: { fontSize: FONT_SIZES.H3, fontWeight: 'bold', color: COLORS.CHARCOAL, letterSpacing: 0.5 },
categorySection: { marginBottom: 20 },
categoryHeader: {
flexDirection: 'row',
@@ -25,7 +25,7 @@ const styles = StyleSheet.create({
borderBottomColor: COLORS.BLUEPRINT,
marginBottom: 10
},
categoryIcon: { width: 8, height: 8, backgroundColor: COLORS.CHARCOAL, marginRight: 10 },
categoryIcon: { width: 8, height: 8, backgroundColor: COLORS.GRID, borderInlineWidth: 1, borderColor: COLORS.DIVIDER, marginRight: 10 },
categoryTitle: { fontSize: FONT_SIZES.BODY, fontWeight: 'bold', color: COLORS.CHARCOAL, textTransform: 'uppercase', letterSpacing: 1 },
pagesGrid: { flexDirection: 'row', flexWrap: 'wrap' },
pageCard: {
@@ -51,7 +51,7 @@ export const SitemapModule = ({ state }: any) => (
<PDFView style={styles.sitemapTree}>
<PDFView style={styles.rootNode}>
<PDFText style={styles.rootTitle}>{state.websiteTopic || 'Digitales Ökosystem'}</PDFText>
<PDFText style={styles.rootTitle}>Seitenstruktur</PDFText>
</PDFView>
{state.sitemap?.map((cat: any, i: number) => (