From 38f2b871b927338fe66a0ae155b87bdd479a0443 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Tue, 3 Feb 2026 19:41:06 +0100 Subject: [PATCH] feat: Refine PDF module labels and styling, and add a divider to the sitemap module. --- scripts/ai-estimate.ts | 78 ++++++++------- src/components/pdf/SharedUI.tsx | 10 ++ .../pdf/modules/BrandingModules.tsx | 63 ++++++------ src/components/pdf/modules/BriefingModule.tsx | 6 +- src/components/pdf/modules/CommonModules.tsx | 37 ++++--- .../pdf/modules/EstimationModule.tsx | 8 +- .../pdf/modules/FrontPageModule.tsx | 4 +- src/components/pdf/modules/SitemapModule.tsx | 3 +- .../default/SDK_CRAWLER_STATISTICS_0.json | 22 ++--- .../default/SDK_SESSION_POOL_STATE.json | 96 +++++++++---------- 10 files changed, 176 insertions(+), 151 deletions(-) diff --git a/scripts/ai-estimate.ts b/scripts/ai-estimate.ts index 3fc28d4..f749882 100644 --- a/scripts/ai-estimate.ts +++ b/scripts/ai-estimate.ts @@ -360,15 +360,16 @@ ${tone} ### OBJECTIVE: 1. **briefingSummary**: Summarize the project's essence for the CUSTOMER. - - FOLLOW PRINCIPLE 1 & 5: Clear, direct, no marketing fluff. - - **MIRROR TEST**: Capture unique customer "hooks" or personality (e.g., if they mention an Instagram account or a specific hobby/preference that influences the project vibe). - - Focus 100% on the BRIEFING (TRUTH SOURCE). Ignore the CRAWL context for this narrative. - - Keep it 2-3 professional, direct sentences. + - FOLLOW PRINCIPLE 1, 5 & 6: Clear, direct, no marketing fluff. + - **TONE**: Write naturally in the Ich-Form. Avoid starting every sentence with "Ich". + - **MIRROR TEST**: Capture unique customer "hooks" or personality. + - Focus 100% on the BRIEFING (TRUTH SOURCE). 2. **designVision**: A solid, grounded, and high-quality description of the look & feel. - - FOLLOW PRINCIPLE 1 & 3: Fact-based, professional, high density of information. - - **BESPOKE ELEMENTS**: If the client mentions specific layout ideas (e.g., "Timeline", "Grid", "Industrial Tiles"), incorporate these as strategic decisions. - - **NO ARROGANCE**: Eliminate all "high-end", "world-class", "dominance" language. Be humble and precise. - - **SIMPLE & CLEAR**: Use simple German. No buzzwords. "Solid Industrial Design" instead of "Technocratic Sovereignty". + - FOLLOW PRINCIPLE 1, 3 & 6: Fact-based, professional, high density of information. + - **TONE**: Natural Ich-Form. Focus on the execution and technical decisions. + - **BESPOKE ELEMENTS**: If the client mentions specific layout ideas, incorporate these. + - **NO ARROGANCE**: Eliminate all "high-end", "world-class" language. + - **SIMPLE & CLEAR**: Use simple German. No buzzwords. - 3-5 sentences of deep analysis. ### OUTPUT FORMAT (Strict JSON): @@ -421,34 +422,38 @@ You are a Senior Solution Architect. Your goal is ABSOLUTE TRANSPARENCY for the Each position in the quote must be perfectly justified and detailed. ### POSITION TITLES: -"Basis Website Setup", "Individuelle Seiten", "System-Module", "Logik-Funktionen", "Schnittstellen (API)", "Inhaltsverwaltung (CMS)". +"Basis Website Setup", "Individuelle Seiten", "System-Module", "Logik-Funktionen", "Visuelle Inszenierung", "Komplexe Interaktion", "Schnittstellen (API)", "Inhaltsverwaltung (CMS)", "Sorglos-Betrieb (Hosting)". ### MAPPING RULES (STRICTLY BASED ON PRICING.MD): -- **Basis Website Setup**: Includes Infrastructure, Hosting Setup, Basic SEO, Cookie-Consent (!), Design-Template. -- **System-Module (Features)**: ONLY closed data systems: [Blog, News, Products, Jobs, Cases/References, Events]. - - NEVER put "Video Player", "Cookies", "Animations" here. -- **Logik-Funktionen**: Functional logic like: Search, Filter, Forms, PDF-Export, Multi-lang. -- **Schnittstellen (API)**: REAL Data Syncs (CRM, ERP). DO NOT include Tracking, Google Maps, or simple Video embedding here. Basic embedding is "Basis Website Setup". -- **Sorglos-Betrieb (Hosting)**: Hosting & Maintenance. +- **Basis Website Setup**: Infrastructure, Hosting, SEO-Basics, Cookie-Consent, Staging/Production. +- **Individuelle Seiten**: Layout and structure for specific pages (e.g. Home, Services). +- **System-Module (Features)**: Closed systems with data structures (Blog, News, Products, Jobs, References). +- **Logik-Funktionen**: Pure logic (Search, Filter, Forms, PDF-Export, Multi-lang). +- **Visuelle Inszenierung**: Hero-Story, visual flows, Scroll-effects. +- **Komplexe Interaktion**: UI-experiences like Configurators or multi-step processes. +- **Schnittstellen (API)**: REAL Data Syncs (CRM, ERP, Stripe). +- **Inhaltsverwaltung (CMS)**: Setup and mapping for Headless CMS. +- **Sorglos-Betrieb (Hosting)**: Hosting, Updates, Backups. ### RULES FOR positionDescriptions (STRICT): -1. **ZERO GENERALIZATION**: Do NOT say "Verschiedene Funktionen". -2. **ITEMIZED SYNTHESIS**: Mention EVERY component selected in Pass 1. -3. **HARD SPECIFICS**: Preserve technical details from the briefing (e.g., "110 kV", "HDD-Bohrtechnik", specific industry standards). -4. **BREVITY & DENSITY**: Max 1-2 short sentences. Focus on TASKS not RESULTS. -5. **STYLE**: Direct, engineering-grade, no fluff. -6. **LANGUAGE**: 100% GERMAN. +1. **NO "ICH-FORM"**: Do NOT use "Ich" or "Mein". Lead with the action or component. +2. **CONCISE & ITEM-BASED**: Use short, technical sentences. Focus on WHAT is delivered. +3. **ZERO GENERALIZATION**: Do NOT say "Verschiedene Funktionen". +4. **ITEMIZED SYNTHESIS**: Mention EVERY component selected in Pass 1. +5. **HARD SPECIFICS**: Preserve technical details from the briefing (e.g., "110 kV", "HDD-Bohrtechnik"). +6. **STYLE**: Direct, engineering-grade, 100% GERMAN. 7. **SPECIFIC - PAGES**: For "Individuelle Seiten", list the pages as a comma-separated list. -8. **SPECIFIC - API**: Video Uploads, Google Maps, and Tracking are NOT APIs. -9. **SPECIFIC - HOSTING**: Always append: "Inkl. 20GB Speicher. Auto-Erweiterung +10€/10GB." -10. **SPECIFIC - LOGIC**: Describe the ACTUAL logic. NEVER use generic terms like "Erweiterte Formulare" or "Individuelle Formular-Logik". -11. **STRICT KEYS**: Keys MUST be EXACTLY: "Basis Website Setup", "Individuelle Seiten", "System-Module", "Logik-Funktionen", "Schnittstellen (API)", "Inhaltsverwaltung (CMS)", "Sorglos-Betrieb (Hosting)". +8. **SPECIFIC - HOSTING**: Always append: "Inkl. 20GB Speicher." +9. **SPECIFIC - LOGIC**: Describe the ACTUAL logic. NEVER use generic terms. +10. **STRICT KEYS**: Keys MUST be EXACTLY the ones defined in POSITION TITLES. ### EXAMPLES (FEW-SHOT): -- **BAD**: "Individuelle Seiten für die Unternehmensdarstellung." -- **GOOD**: "Erstellung der Seiten: Startseite (Video-Hero), Über uns (Timeline), Leistungen (110kV Montage), Kontakt." -- **BAD**: "Anbindung von externen Systemen." -- **GOOD**: "Native Integration von Google Maps zur Standortermittlung inkl. individueller Marker-Logik." +- **BAD**: "Ich entwickle die Seiten: Startseite, Leistungen, Kontakt." +- **GOOD**: "Erstellung der Seiten: Startseite (Video-Hero), Über uns (Timeline), Leistungen, Kontakt." +- **BAD**: "Ich binde Google Maps an." +- **GOOD**: "Native API-Integration von Google Maps mit individueller Standort-Visualisierung." +- **BAD**: "Ich programmiere Scroll-Effekte." +- **GOOD**: "Visuelle Inszenierung der Meilensteine durch Scroll-aktivierte Timeline-Elemente." ### FORBIDDEN PHRASES: - "Erweiterte Formulare", "Verschiedene Funktionen", "Allgemeine Logik", "Optimierte Darstellung", "Individuelle Formular-Logik". @@ -478,11 +483,20 @@ You are the "Industrial Critic". Your goal is to catch quality regressions and e Analyze the CURRENT_STATE against the BRIEFING_TRUTH. ### CRITICAL ERROR CHECKLIST (FAIL IF FOUND): -1. **Placeholder Leakage**: Catch "null", "undefined", or generic strings like "Verschiedene Funktionen", "Erweiterte Formulare", "Individuelle Formular-Logik". -2. **Detail Loss**: The user mentioned specific terms (e.g., "110 kV", "HDD", "Timeline", "Instagram"). Are they present in the positionDescriptions or sitemap? If not, ADD THEM. +1. **Placeholder Leakage**: Catch "null", "undefined", or generic strings like "Verschiedene Funktionen", "Erweiterte Formulare". +2. **Detail Loss**: The user mentioned specific terms. Are they present? If not, ADD THEM. 3. **Consistency**: Ensure the count of pages in "Individuelle Seiten" matches the sitemap pages. 4. **Deadlines**: Ensure relative dates (e.g., "April / Mai") are resolved to the year 2026. -5. **Tone Drift**: Remove any marketing "fluff" or "sales-y" language. Maintain the "Industrial Design" persona. +5. **TONE & WORDING FAILURE**: + - FAIL if "Ich" or "Mein" is used in positionDescriptions. + - FAIL if "wir" or "unser" is used anywhere. + - FAIL if a sentence in briefingSummary is too long or marketing-heavy. + - FAIL if "möglicherweise", "grundsätzlich", "in der Regel" is used. + - FAIL if passive voice ("es wird") is used. +6. **MAPPING FAILURE**: + - FAIL if visual elements (Scroll-Effekte, Slider, Hover) are in "Logik-Funktionen". They MUST be in "Visuelle Inszenierung". + - FAIL if multi-step forms or calculators are in "Logik-Funktionen". They MUST be in "Komplexe Interaktion". +7. **PROMPT REWRITE**: If you find any of these errors, rewrite the field entirely to be 100% compliant. ### MISSION: Return updated fields ONLY. Specifically focus on hardening 'positionDescriptions', 'sitemap', and 'briefingSummary'. diff --git a/src/components/pdf/SharedUI.tsx b/src/components/pdf/SharedUI.tsx index eb6c2f4..467746f 100644 --- a/src/components/pdf/SharedUI.tsx +++ b/src/components/pdf/SharedUI.tsx @@ -130,6 +130,12 @@ export const pdfStyles = PDFStyleSheet.create({ borderTopWidth: 0.5, borderTopColor: '#cbd5e1', }, + divider: { + width: '100%', + height: 1, + backgroundColor: '#f1f5f9', + marginVertical: 12, + }, // Atoms industrialListItem: { flexDirection: 'row', @@ -219,6 +225,10 @@ export const IndustrialCard = ({ title, children, style = {} }: { title: string; export const FoldingMarks = () => (<>); +export const Divider = ({ style = {} }: { style?: any }) => ( + +); + export const Footer = ({ logo, companyData, bankData, showDetails = true, showPageNumber = true }: { logo?: string; companyData: any; bankData: any; showDetails?: boolean; showPageNumber?: boolean }) => ( {logo ? () : (marc mintel)}{showDetails && (<>{companyData.name}{"\n"}{companyData.address1}{"\n"}{companyData.address2}{"\n"}UST: {companyData.ustId}{showPageNumber && `${pageNumber} / ${totalPages}`} fixed />})}{!showDetails && ({showPageNumber && `${pageNumber} / ${totalPages}`} fixed />})} ); diff --git a/src/components/pdf/modules/BrandingModules.tsx b/src/components/pdf/modules/BrandingModules.tsx index 7ee7939..8f55768 100644 --- a/src/components/pdf/modules/BrandingModules.tsx +++ b/src/components/pdf/modules/BrandingModules.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { View as PDFView, Text as PDFText, StyleSheet } from '@react-pdf/renderer'; -import { IndustrialListItem, IndustrialCard } from '../SharedUI'; +import { IndustrialListItem, IndustrialCard, Divider } from '../SharedUI'; const styles = StyleSheet.create({ industrialTitle: { fontSize: 24, fontWeight: 'bold', color: '#0f172a', marginBottom: 6, letterSpacing: -0.5 }, @@ -27,28 +27,28 @@ export const AboutModule = () => ( <> Über mich Direkt. Sauber. Verantwortlich. + - Ich baue Websites und Systeme seit über 15 Jahren. Nicht weil ich Websites so liebe – sondern weil ich es hasse, wenn Dinge nicht funktionieren. - In diesen Jahren habe ich Agenturen von innen gesehen, Konzerne erlebt und Startups aufgebaut. Ich habe gelernt, dass das Problem selten die Technik ist – sondern die Zuständigkeit. + Ich entwickle Websysteme seit 15 Jahren. Ich kenne Agenturen, Konzerne und Startups. Ich arbeite alleine, weil ich Verantwortung nicht teilen will. + Technik scheitert selten an Bits und Bytes. Sie scheitert an unklaren Zuständigkeiten. Ich bin Ihr einziger Ansprechpartner. Ich treffe die Entscheidungen und ich löse die Probleme. - Meine Arbeitsweise: - schnell & stabil - "boring" (im besten Sinne) - erweiterbar & wartungsarm - unabhängig von Agenturen + Mein Standard: + Ich liefere Code ohne Altlasten. + Ich baue Systeme, die ohne mich laufen. + Ich arbeite ohne Overhead und Stille Post. - - Eine Person. Eine Verantwortung. - Direkte Kommunikation ohne Stille Post. - Code, der Ihnen gehört. + + Ich bin der einzige Entwickler. + Ich antworte direkt auf technische Fragen. + Ich garantiere die Umsetzung. - - Projektmanager - Ticket-Systeme - CMS-Drama & Update-Angst + + Keine Projektmanager. + Keine Vertriebler. + Kein Ticket-Chaos. @@ -57,40 +57,41 @@ export const AboutModule = () => ( export const CrossSellModule = ({ state }: any) => { const isWebsite = state.projectType === 'website'; - const title = isWebsite ? "Das könnte Sie auch interessieren" : "Websites & Ökosysteme"; - const subtitle = isWebsite ? "Kleine Helfer, die den Alltag entlasten" : "Digitale Visitenkarten mit Tiefe"; + const title = isWebsite ? "Digitale Routine" : "Websites & Ökosysteme"; + const subtitle = isWebsite ? "Automatisierung statt Fleißarbeit" : "Technische Infrastruktur ohne Kompromisse"; return ( <> - Das könnte Sie auch interessieren - Kleine helfer, die den alltag entlasten - + {title} + {subtitle} + + {isWebsite ? ( <> - Zusätzlich zur digitalen Präsenz fressen in vielen Unternehmen wiederkehrende Aufgaben unzählige Stunden: Daten abtippen, Formulare ausfüllen, Angebote anpassen. - Das ist keine wertschöpfende Arbeit. Das ist Routine. + Ich identifiziere manuelle Abläufe in Ihrem Unternehmen und ersetze sie durch Software. Ich eliminiere Tippfehler und Zeitfresser. + Ich schaffe Zeit für wertschöpfende Arbeit. Ich digitalisiere das Chaos. - Der schnelle Check - Wenn bei Ihnen gerade etwas "von Hand gemacht wird" oder "ewig dauert" – ich sage Ihnen in 1-2 Tagen, ob und wie schnell man das sinnvoll digitalisieren kann. + Direktes Feedback + Ich prüfe Ihren Prozess innerhalb von 48 Stunden. Ich sage Ihnen sofort, ob eine Automatisierung wirtschaftlich sinnvoll ist. - Kurze Eingaben via Formular → fertiges Angebot/Bericht. Von 60min auf 5min reduziert. + Ich automatisiere Angebote und Berichte. Ich reduziere den Zeitaufwand auf 5 Minuten. Ich garantiere fehlerfreie Exporte. - Verkaufszahlen, Lagerbestände oder Kundenlisten automatisch synchronisieren und auswerten. + Ich synchronisiere Ihre Datenbestände. Ich schaffe Echtzeit-Transparenz ohne manuelle Listenpflege. - - Rechnungen oder handschriftliche Notizen fotografieren → Daten landen direkt strukturiert in der Tabelle. + + Ich implementiere Schrifterkennung für analoge Dokumente. Ich übertrage Daten direkt in Ihre Systeme. ) : ( - Neben Automatisierung baue ich komplette digitale Ökosysteme für Unternehmen, die Wert auf Qualität legen. - Keine Baukästen. Keine langsamen WordPress-Themes. Sondern maßgeschneiderte Systeme, die technisch und optisch in der ersten Liga spielen. + Ich baue die technische Basis für Ihr Unternehmen. Ich meide Baukästen und Agentur-Abhängigkeiten. + Ich entwickle performante Frontends und stabile Backends. Ich liefere Code, den Sie besitzen und selbst kontrollieren. )} diff --git a/src/components/pdf/modules/BriefingModule.tsx b/src/components/pdf/modules/BriefingModule.tsx index 6c019e0..d2dda5f 100644 --- a/src/components/pdf/modules/BriefingModule.tsx +++ b/src/components/pdf/modules/BriefingModule.tsx @@ -26,10 +26,10 @@ export const BriefingModule = ({ state }: any) => ( Kern-Informationen - Ansprechpartner{state.personName || "Ihr Team"} - Status Quo{state.statusQuo || (state.existingWebsite ? 'Relaunch' : 'Neuentwicklung')} + Ansprechpartner{state.personName || "Sie"} + Projektart{state.statusQuo || (state.existingWebsite ? 'Relaunch' : 'Neuentwicklung')} Mitarbeiter{state.employeeCount || "—"} - Deadline / Zeitplan{state.deadline || 'Flexibel'} + Zeitplan{state.deadline || 'Flexibel'} {state.designVision && ( diff --git a/src/components/pdf/modules/CommonModules.tsx b/src/components/pdf/modules/CommonModules.tsx index d939e0b..f8dd7fe 100644 --- a/src/components/pdf/modules/CommonModules.tsx +++ b/src/components/pdf/modules/CommonModules.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { View as PDFView, Text as PDFText, StyleSheet, Image as PDFImage } from '@react-pdf/renderer'; -import { DocumentTitle } from '../SharedUI'; +import { DocumentTitle, Divider } from '../SharedUI'; const styles = StyleSheet.create({ section: { marginBottom: 24 }, @@ -38,47 +38,46 @@ export const TransparenzModule = ({ pricing }: any) => ( <> - Grundlage für kalkulierbare Investitionen - Digitaler Erfolg basiert auf Transparenz. Dieses Dokument dient als detaillierte Grundlage für Ihre Investitionsentscheidung. Es handelt sich um ein Festpreis-Modell für die beschriebenen Leistungen, um Ihnen maximale Planungssicherheit zu gewährleisten. + Festpreise statt Stundenabrechnung + Ich biete Planungssicherheit. Ich kalkuliere nach einem modularen Festpreis-System. Sie zahlen für Ergebnisse, nicht für die Zeit. Ich schließe versteckte Kosten aus. + - Warum dieser modulare Ansatz? - Meine Kalkulation basiert auf einem transparenten Festpreis-System. Sie zahlen nicht für Stunden, sondern für messbare Ergebnisse. Jeder Baustein ist darauf ausgelegt, Ihre digitale Präsenz zu stärken und den ROI Ihres Projekts zu maximieren. 1. Das Fundament - Infrastruktur, technisches SEO, Analytics und ein skalierbares Setup. Der Grundstein für eine Website, die technisch perfekt performt. + Ich richte die technische Infrastruktur ein. Ich installiere das Hosting, schaffe SEO-Basics und erstelle die Test-, Staging- und Live-Umgebungen. {pricing.BASE_WEBSITE?.toLocaleString('de-DE')} € - 2. Individuelle Erlebnisse - Pro Seite entwickeln wir ein UI/UX-Konzept, das Besucher führt und überzeugt. Keine Standard-Templates, sondern maßgeschneidertes Design. + 2. Seiten + Ich entwickle das individuelle Layout und die Struktur jeder Seite. Ich garantiere die korrekte Darstellung auf allen Endgeräten. {pricing.PAGE?.toLocaleString('de-DE')} € / Stk - 3. Smarte Content-Systeme - Automatisieren Sie Ihre Kommunikation. Ob Blog, Job-Board oder Case Studies – wir bauen Systeme, die sich einfach pflegen lassen. + 3. Features + Ich erstelle abgeschlossene technische Systeme (z. B. Blog oder News). Ich definiere die Datenfelder und die Pflege-Oberflächen. {pricing.FEATURE?.toLocaleString('de-DE')} € / Stk - 4. Funktionalität - Suche, Filter oder interaktive Formulare. Wir reduzieren Reibung und machen die Nutzung für Ihre Kunden zum Erlebnis. + 4. Funktionen + Ich programmiere Logik-Module wie Filter, Suchen oder Kontakt-Schnittstellen. Ich sorge für die fehlerfreie Verarbeitung Ihrer Daten. {pricing.FUNCTION?.toLocaleString('de-DE')} € / Stk - 5. High-End Inszenierung - Video-Integrationen, Mikro-Animationen und immersive Effekte. So heben Sie sich im Markt ab und wirken als Premium-Marke. + 5. Interaktion + Ich entwerfe komplexe UI-Abläufe und Konfiguratoren. Ich optimiere die Nutzerführung für maximale Abschlüsse. {pricing.COMPLEX_INTERACTION?.toLocaleString('de-DE')} € / Stk - 6. Autonomie & Vernetzung - Nahtlose Anbindung an Headless CMS oder Ihre Bestands-APIs (CRM, ERP). Maximale Freiheit bei voller Kontrolle. + 6. Integrationen + Ich binde Drittsysteme wie CRM, ERP oder Stripe an. Ich richte CMS-Schnittstellen zur unabhängigen Inhaltsverwaltung ein. ab {pricing.API_INTEGRATION?.toLocaleString('de-DE')} € - 7. Sorglos-Betrieb - Full-Service Hosting, tägliche Backups und proaktive Sicherheitsupdates. Damit Sie sich auf Ihr Kerngeschäft konzentrieren können. - {pricing.HOSTING_MONTHLY?.toLocaleString('de-DE')} € / Mon + 7. Betrieb (12 Monate) + Ich betreibe das Hosting, pflege Sicherheitsupdates ein und erstelle monatliche Berichte. Ich garantiere die Verfügbarkeit für ein Jahr. + 1.440 € diff --git a/src/components/pdf/modules/EstimationModule.tsx b/src/components/pdf/modules/EstimationModule.tsx index 7140f87..cbd1dc9 100644 --- a/src/components/pdf/modules/EstimationModule.tsx +++ b/src/components/pdf/modules/EstimationModule.tsx @@ -7,7 +7,7 @@ import { DocumentTitle } from '../SharedUI'; const styles = StyleSheet.create({ table: { marginTop: 12 }, tableHeader: { flexDirection: 'row', paddingBottom: 8, borderBottomWidth: 1, borderBottomColor: '#000000', marginBottom: 12 }, - tableRow: { flexDirection: 'row', paddingVertical: 6, borderBottomWidth: 1, borderBottomColor: '#eeeeee', alignItems: 'flex-start' }, + tableRow: { flexDirection: 'row', paddingVertical: 8, borderBottomWidth: 1, borderBottomColor: '#f8fafc', alignItems: 'flex-start' }, colPos: { width: '8%' }, colDesc: { width: '62%' }, colQty: { width: '10%', textAlign: 'center' }, @@ -47,9 +47,9 @@ export const EstimationModule = ({ state, positions, totalPrice, date }: any) => ))} - Zwischensumme (Netto){totalPrice.toLocaleString('de-DE')} € - zzgl. 19% MwSt.{(totalPrice * 0.19).toLocaleString('de-DE')} € - Gesamtsumme (Brutto){(totalPrice * 1.19).toLocaleString('de-DE')} € + Nettobetrag{totalPrice.toLocaleString('de-DE')} € + Umsatzsteuer (19%){(totalPrice * 0.19).toLocaleString('de-DE')} € + Gesamtbetrag (Brutto){(totalPrice * 1.19).toLocaleString('de-DE')} € ); diff --git a/src/components/pdf/modules/FrontPageModule.tsx b/src/components/pdf/modules/FrontPageModule.tsx index cf76165..4c396e6 100644 --- a/src/components/pdf/modules/FrontPageModule.tsx +++ b/src/components/pdf/modules/FrontPageModule.tsx @@ -64,10 +64,10 @@ export const FrontPageModule = ({ state, headerIcon, date }: any) => ( {headerIcon ? : M} - Kostenschätzung & Konzept + Konzept & Kostenschätzung {state.projectType === 'website' ? 'Digitale Präsenz' : 'Digitale Applikation'} - für {state.companyName || "Ihre Projektanfrage"} + für {state.companyName || "Ihr Projekt"} {date} | Marc Mintel ); diff --git a/src/components/pdf/modules/SitemapModule.tsx b/src/components/pdf/modules/SitemapModule.tsx index 7d51b28..acb4f15 100644 --- a/src/components/pdf/modules/SitemapModule.tsx +++ b/src/components/pdf/modules/SitemapModule.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { View as PDFView, Text as PDFText, StyleSheet } from '@react-pdf/renderer'; -import { DocumentTitle } from '../SharedUI'; +import { DocumentTitle, Divider } from '../SharedUI'; const styles = StyleSheet.create({ section: { marginBottom: 24 }, @@ -27,6 +27,7 @@ export const SitemapModule = ({ state }: any) => ( Die folgende Struktur bildet das Fundament für die Benutzerführung und Informationsarchitektur Ihres Projekts. + {state.websiteTopic || 'Digitales Ökosystem'} diff --git a/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json b/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json index 5279995..08b127e 100644 --- a/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json +++ b/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json @@ -3,23 +3,23 @@ "requestsFailed": 0, "requestsRetries": 0, "requestsFailedPerMinute": 0, - "requestsFinishedPerMinute": 109, - "requestMinDurationMillis": 572, - "requestMaxDurationMillis": 2979, + "requestsFinishedPerMinute": 142, + "requestMinDurationMillis": 287, + "requestMaxDurationMillis": 1881, "requestTotalFailedDurationMillis": 0, - "requestTotalFinishedDurationMillis": 15374, - "crawlerStartedAt": "2026-02-03T17:52:01.328Z", - "crawlerFinishedAt": "2026-02-03T17:52:05.723Z", - "statsPersistedAt": "2026-02-03T17:52:05.723Z", - "crawlerRuntimeMillis": 4407, - "crawlerLastStartTimestamp": 1770141121316, + "requestTotalFinishedDurationMillis": 11907, + "crawlerStartedAt": "2026-02-03T18:37:56.387Z", + "crawlerFinishedAt": "2026-02-03T18:37:59.745Z", + "statsPersistedAt": "2026-02-03T18:37:59.745Z", + "crawlerRuntimeMillis": 3370, + "crawlerLastStartTimestamp": 1770143876375, "requestRetryHistogram": [ 8 ], "statsId": 0, "requestAvgFailedDurationMillis": null, - "requestAvgFinishedDurationMillis": 1922, - "requestTotalDurationMillis": 15374, + "requestAvgFinishedDurationMillis": 1488, + "requestTotalDurationMillis": 11907, "requestsTotal": 8, "requestsWithStatusCode": {}, "errors": {}, diff --git a/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json b/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json index 2daf7b7..9f2fc1d 100644 --- a/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json +++ b/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json @@ -3,7 +3,7 @@ "retiredSessionsCount": 0, "sessions": [ { - "id": "session_d5YGFP9eEW", + "id": "session_cHq4dMfwXI", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -14,28 +14,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "0v9stk94l2has4gq4jejmkd3op", + "value": "pjedkv3ggc43er8m2edt6i3gqi", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:02.702Z", - "lastAccessed": "2026-02-03T17:52:02.702Z" + "creation": "2026-02-03T18:37:57.817Z", + "lastAccessed": "2026-02-03T18:37:57.817Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:01.370Z", - "createdAt": "2026-02-03T17:52:01.370Z", + "expiresAt": "2026-02-03T19:27:56.432Z", + "createdAt": "2026-02-03T18:37:56.432Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_TkPjda1ECD", + "id": "session_YbphnNZDOG", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -46,28 +46,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "tbb2pveomkq9ua23o1u71bjgv0", + "value": "ja7mdd60clptutmne95nsea0f4", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:03.289Z", - "lastAccessed": "2026-02-03T17:52:03.289Z" + "creation": "2026-02-03T18:37:58.124Z", + "lastAccessed": "2026-02-03T18:37:58.124Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.723Z", - "createdAt": "2026-02-03T17:52:02.723Z", + "expiresAt": "2026-02-03T19:27:57.842Z", + "createdAt": "2026-02-03T18:37:57.842Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_yh43IUCayx", + "id": "session_j4wCqQrHhE", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -78,28 +78,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "fd753scoscg0t7e1s2to2f9v7i", + "value": "bl0s9u6150j1fe56qq5p81raur", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:04.196Z", - "lastAccessed": "2026-02-03T17:52:04.196Z" + "creation": "2026-02-03T18:37:59.132Z", + "lastAccessed": "2026-02-03T18:37:59.132Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.725Z", - "createdAt": "2026-02-03T17:52:02.725Z", + "expiresAt": "2026-02-03T19:27:57.844Z", + "createdAt": "2026-02-03T18:37:57.844Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_S0J5fDWVY3", + "id": "session_km9kX8juX5", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -110,28 +110,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "1q9rudf8c5vv73cqq40rlfekur", + "value": "7kb8am8on70lsg0498u61mjh80", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:04.653Z", - "lastAccessed": "2026-02-03T17:52:04.653Z" + "creation": "2026-02-03T18:37:59.617Z", + "lastAccessed": "2026-02-03T18:37:59.617Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.726Z", - "createdAt": "2026-02-03T17:52:02.726Z", + "expiresAt": "2026-02-03T19:27:57.845Z", + "createdAt": "2026-02-03T18:37:57.845Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_r79Eqvg1Uq", + "id": "session_0LdWEWTmbd", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -142,28 +142,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "f840og9pek9msq9draobvo2u03", + "value": "67m4qccak2or4g35v85dghk7lo", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:04.787Z", - "lastAccessed": "2026-02-03T17:52:04.787Z" + "creation": "2026-02-03T18:37:59.603Z", + "lastAccessed": "2026-02-03T18:37:59.603Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.727Z", - "createdAt": "2026-02-03T17:52:02.727Z", + "expiresAt": "2026-02-03T19:27:57.846Z", + "createdAt": "2026-02-03T18:37:57.846Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_TQDqR0N6bh", + "id": "session_7tIybVMGvQ", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -174,28 +174,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "ad2e6u92rpajjh5vesgdqfc05b", + "value": "9tvsa0um2dbqqt64us08bjpugt", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:04.891Z", - "lastAccessed": "2026-02-03T17:52:04.891Z" + "creation": "2026-02-03T18:37:59.563Z", + "lastAccessed": "2026-02-03T18:37:59.563Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.728Z", - "createdAt": "2026-02-03T17:52:02.728Z", + "expiresAt": "2026-02-03T19:27:57.847Z", + "createdAt": "2026-02-03T18:37:57.847Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_GNNTPF8Zd1", + "id": "session_oFBMQoKZBM", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -206,28 +206,28 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "063l7o872dac686isv37sdf3of", + "value": "4oab9p5g0sjkpg0bad165hvss5", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:05.702Z", - "lastAccessed": "2026-02-03T17:52:05.702Z" + "creation": "2026-02-03T18:37:59.725Z", + "lastAccessed": "2026-02-03T18:37:59.725Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.729Z", - "createdAt": "2026-02-03T17:52:02.729Z", + "expiresAt": "2026-02-03T19:27:57.848Z", + "createdAt": "2026-02-03T18:37:57.848Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0 }, { - "id": "session_iHMY60Kcw5", + "id": "session_7tuITPzdEJ", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -238,22 +238,22 @@ "cookies": [ { "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "bdkvmq3k59es68k3u9h2ed5l4s", + "value": "l0i9ipa1hduoo18scpeb489ian", "domain": "www.schleicher-gruppe.de", "path": "/", "secure": true, "httpOnly": true, "hostOnly": true, - "creation": "2026-02-03T17:52:05.563Z", - "lastAccessed": "2026-02-03T17:52:05.563Z" + "creation": "2026-02-03T18:37:59.633Z", + "lastAccessed": "2026-02-03T18:37:59.633Z" } ] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T18:42:02.733Z", - "createdAt": "2026-02-03T17:52:02.733Z", + "expiresAt": "2026-02-03T19:27:57.853Z", + "createdAt": "2026-02-03T18:37:57.853Z", "usageCount": 1, "maxUsageCount": 50, "errorScore": 0