'use client' import React, { useState, useEffect } from 'react' import { useSDK } from '@/lib/sdk' import { CompanyProfile, BusinessModel, OfferingType, TargetMarket, CompanySize, LegalForm, MachineBuilderProfile, MachineProductType, AIIntegrationType, HumanOversightLevel, CriticalSector, BUSINESS_MODEL_LABELS, OFFERING_TYPE_LABELS, TARGET_MARKET_LABELS, COMPANY_SIZE_LABELS, MACHINE_PRODUCT_TYPE_LABELS, AI_INTEGRATION_TYPE_LABELS, HUMAN_OVERSIGHT_LABELS, CRITICAL_SECTOR_LABELS, SDKCoverageAssessment, } from '@/lib/sdk/types' // ============================================================================= // WIZARD STEPS // ============================================================================= const BASE_WIZARD_STEPS = [ { id: 1, name: 'Basisinfos', description: 'Firmenname und Rechtsform' }, { id: 2, name: 'Geschaeftsmodell', description: 'B2B, B2C und Angebote' }, { id: 3, name: 'Firmengroesse', description: 'Mitarbeiter und Umsatz' }, { id: 4, name: 'Standorte', description: 'Hauptsitz und Zielmaerkte' }, { id: 5, name: 'Datenschutz', description: 'Rollen und KI-Nutzung' }, { id: 6, name: 'Systeme & KI', description: 'IT-Systeme und KI-Katalog' }, { id: 7, name: 'Rechtlicher Rahmen', description: 'Regulierungen und Prüfzyklen' }, ] const MACHINE_BUILDER_STEP = { id: 8, name: 'Produkt & Maschine', description: 'Software, KI und CE in Ihrem Produkt' } function getWizardSteps(industry: string) { if (isMachineBuilderIndustry(industry)) { return [...BASE_WIZARD_STEPS, MACHINE_BUILDER_STEP] } return BASE_WIZARD_STEPS } // Keep WIZARD_STEPS for backwards compat in static references const WIZARD_STEPS = BASE_WIZARD_STEPS // ============================================================================= // LEGAL FORMS // ============================================================================= const LEGAL_FORM_LABELS: Record = { einzelunternehmen: 'Einzelunternehmen', gbr: 'GbR', ohg: 'OHG', kg: 'KG', gmbh: 'GmbH', ug: 'UG (haftungsbeschränkt)', ag: 'AG', gmbh_co_kg: 'GmbH & Co. KG', ev: 'e.V. (Verein)', stiftung: 'Stiftung', other: 'Sonstige', } // ============================================================================= // INDUSTRIES // ============================================================================= const INDUSTRIES = [ 'Technologie / IT', 'E-Commerce / Handel', 'Finanzdienstleistungen', 'Gesundheitswesen', 'Bildung', 'Beratung / Consulting', 'Marketing / Agentur', 'Produktion / Industrie', 'Logistik / Transport', 'Immobilien', 'Maschinenbau', 'Anlagenbau', 'Automatisierung', 'Robotik', 'Messtechnik', 'Sonstige', ] const MACHINE_BUILDER_INDUSTRIES = [ 'Maschinenbau', 'Anlagenbau', 'Automatisierung', 'Robotik', 'Messtechnik', ] const isMachineBuilderIndustry = (industry: string) => MACHINE_BUILDER_INDUSTRIES.includes(industry) // ============================================================================= // HELPER: ASSESS SDK COVERAGE // ============================================================================= function assessSDKCoverage(profile: Partial): SDKCoverageAssessment { const coveredRegulations: string[] = ['DSGVO', 'BDSG', 'TTDSG', 'AI Act'] const partiallyCoveredRegulations: string[] = [] const notCoveredRegulations: string[] = [] const reasons: string[] = [] const recommendations: string[] = [] // Check target markets const targetMarkets = profile.targetMarkets || [] if (targetMarkets.includes('worldwide')) { notCoveredRegulations.push('CCPA (Kalifornien)', 'LGPD (Brasilien)', 'POPIA (Südafrika)') reasons.push('Weltweiter Betrieb erfordert Kenntnisse lokaler Datenschutzgesetze') recommendations.push('Für außereuropäische Märkte empfehlen wir die Konsultation lokaler Rechtsanwälte') } if (targetMarkets.includes('eu_uk')) { partiallyCoveredRegulations.push('UK GDPR', 'UK AI Framework') reasons.push('UK-Recht weicht nach Brexit teilweise von EU-Recht ab') recommendations.push('Prüfen Sie UK-spezifische Anpassungen Ihrer Datenschutzerklärung') } // Check company size if (profile.companySize === 'enterprise' || profile.companySize === 'large') { coveredRegulations.push('NIS2') reasons.push('Als größeres Unternehmen können NIS2-Pflichten relevant sein') } // Check offerings const offerings = profile.offerings || [] if (offerings.includes('webshop')) { coveredRegulations.push('Fernabsatzrecht') recommendations.push('Widerrufsbelehrung und AGB-Generator sind im SDK enthalten') } // Determine if fully covered const requiresLegalCounsel = notCoveredRegulations.length > 0 || targetMarkets.includes('worldwide') const isFullyCovered = !requiresLegalCounsel && notCoveredRegulations.length === 0 return { isFullyCovered, coveredRegulations, partiallyCoveredRegulations, notCoveredRegulations, requiresLegalCounsel, reasons, recommendations, } } // ============================================================================= // STEP COMPONENTS // ============================================================================= function StepBasicInfo({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { return (
onChange({ companyName: e.target.value })} placeholder="Ihre Firma GmbH" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
onChange({ foundedYear: parseInt(e.target.value) || null })} placeholder="2020" min="1800" max={new Date().getFullYear()} className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
) } function StepBusinessModel({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { const toggleOffering = (offering: OfferingType) => { const current = data.offerings || [] if (current.includes(offering)) { onChange({ offerings: current.filter(o => o !== offering) }) } else { onChange({ offerings: [...current, offering] }) } } return (
{Object.entries(BUSINESS_MODEL_LABELS).map(([value, label]) => ( ))}
{Object.entries(OFFERING_TYPE_LABELS).map(([value, { label, description }]) => ( ))}
) } function StepCompanySize({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { return (
{Object.entries(COMPANY_SIZE_LABELS).map(([value, label]) => ( ))}
) } function StepLocations({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { const toggleMarket = (market: TargetMarket) => { const current = data.targetMarkets || [] if (current.includes(market)) { onChange({ targetMarkets: current.filter(m => m !== market) }) } else { onChange({ targetMarkets: [...current, market] }) } } return (
onChange({ headquartersCity: e.target.value })} placeholder="z.B. Berlin" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
{Object.entries(TARGET_MARKET_LABELS).map(([value, { label, description, regulations }]) => ( ))}
) } function StepDataProtection({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { return (
onChange({ dpoName: e.target.value || null })} placeholder="Optional" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
onChange({ dpoEmail: e.target.value || null })} placeholder="dsb@firma.de" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
) } // ============================================================================= // STEP 6: SYSTEME & KI // ============================================================================= interface ProcessingSystem { name: string vendor: string hosting: string personal_data_categories: string[] } interface AISystem { name: string purpose: string risk_category: string vendor: string has_human_oversight: boolean } function StepSystemsAndAI({ data, onChange, }: { data: Partial & { processingSystems?: ProcessingSystem[]; aiSystems?: AISystem[] } onChange: (updates: Record) => void }) { const systems = (data as any).processingSystems || [] const aiSystems = (data as any).aiSystems || [] const addSystem = () => { onChange({ processingSystems: [...systems, { name: '', vendor: '', hosting: 'cloud', personal_data_categories: [] }] }) } const removeSystem = (i: number) => { onChange({ processingSystems: systems.filter((_: ProcessingSystem, idx: number) => idx !== i) }) } const updateSystem = (i: number, updates: Partial) => { const updated = [...systems] updated[i] = { ...updated[i], ...updates } onChange({ processingSystems: updated }) } const addAISystem = () => { onChange({ aiSystems: [...aiSystems, { name: '', purpose: '', risk_category: 'limited', vendor: '', has_human_oversight: true }] }) } const removeAISystem = (i: number) => { onChange({ aiSystems: aiSystems.filter((_: AISystem, idx: number) => idx !== i) }) } const updateAISystem = (i: number, updates: Partial) => { const updated = [...aiSystems] updated[i] = { ...updated[i], ...updates } onChange({ aiSystems: updated }) } return (
{/* Processing Systems */}

IT-Systeme mit personenbezogenen Daten

Systeme, die personenbezogene Daten verarbeiten (fuer VVT-Generierung)

{systems.length === 0 && (
Noch keine Systeme hinzugefuegt
)}
{systems.map((sys: ProcessingSystem, i: number) => (
System {i + 1}
updateSystem(i, { name: e.target.value })} placeholder="Name (z.B. SAP HR)" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" /> updateSystem(i, { vendor: e.target.value })} placeholder="Hersteller" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
updateSystem(i, { personal_data_categories: e.target.value.split(',').map(s => s.trim()).filter(Boolean) })} placeholder="Datenkategorien (kommagetrennt)" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
))}
{/* AI Systems */}

KI-Systeme

Strukturierter KI-Katalog fuer AI Act Compliance

{aiSystems.length === 0 && (
Noch keine KI-Systeme
)}
{aiSystems.map((ai: AISystem, i: number) => (
KI-System {i + 1}
updateAISystem(i, { name: e.target.value })} placeholder="Name (z.B. Chatbot)" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" /> updateAISystem(i, { vendor: e.target.value })} placeholder="Anbieter" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
updateAISystem(i, { purpose: e.target.value })} placeholder="Zweck (z.B. Kundensupport)" className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
))}
) } // ============================================================================= // STEP 7: RECHTLICHER RAHMEN // ============================================================================= function StepLegalFramework({ data, onChange, }: { data: Partial & { subjectToNis2?: boolean; subjectToAiAct?: boolean; subjectToIso27001?: boolean; supervisoryAuthority?: string; reviewCycleMonths?: number; technicalContacts?: { name: string; role: string; email: string }[] } onChange: (updates: Record) => void }) { const contacts = (data as any).technicalContacts || [] const addContact = () => { onChange({ technicalContacts: [...contacts, { name: '', role: '', email: '' }] }) } const removeContact = (i: number) => { onChange({ technicalContacts: contacts.filter((_: { name: string; role: string; email: string }, idx: number) => idx !== i) }) } const updateContact = (i: number, updates: Partial<{ name: string; role: string; email: string }>) => { const updated = [...contacts] updated[i] = { ...updated[i], ...updates } onChange({ technicalContacts: updated }) } return (
{/* Regulatory Flags */}

Regulatorischer Rahmen

{[ { key: 'subjectToNis2', label: 'NIS2-Richtlinie', desc: 'Ihr Unternehmen fällt unter die NIS2-Richtlinie (Netzwerk- und Informationssicherheit)' }, { key: 'subjectToAiAct', label: 'EU AI Act', desc: 'Ihr Unternehmen setzt KI-Systeme ein, die unter den AI Act fallen' }, { key: 'subjectToIso27001', label: 'ISO 27001', desc: 'Ihr Unternehmen strebt ISO 27001 Zertifizierung an oder ist bereits zertifiziert' }, ].map(item => ( ))}
{/* Supervisory Authority & Review Cycle */}
{/* Technical Contacts */}

Technische Ansprechpartner

CISO, IT-Manager, DSB etc.

{contacts.length === 0 && (
Noch keine Kontakte
)}
{contacts.map((c: { name: string; role: string; email: string }, i: number) => (
updateContact(i, { name: e.target.value })} placeholder="Name" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" /> updateContact(i, { role: e.target.value })} placeholder="Rolle (z.B. CISO)" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" /> updateContact(i, { email: e.target.value })} placeholder="E-Mail" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
))}
) } // ============================================================================= // STEP 8: PRODUKT & MASCHINE (nur fuer Maschinenbauer) // ============================================================================= const EMPTY_MACHINE_BUILDER: MachineBuilderProfile = { productTypes: [], productDescription: '', productPride: '', containsSoftware: false, containsFirmware: false, containsAI: false, aiIntegrationType: [], hasSafetyFunction: false, safetyFunctionDescription: '', autonomousBehavior: false, humanOversightLevel: 'full', isNetworked: false, hasRemoteAccess: false, hasOTAUpdates: false, updateMechanism: '', exportMarkets: [], criticalSectorClients: false, criticalSectors: [], oemClients: false, ceMarkingRequired: false, existingCEProcess: false, hasRiskAssessment: false, } function StepMachineBuilder({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { const mb = data.machineBuilder || EMPTY_MACHINE_BUILDER const updateMB = (updates: Partial) => { onChange({ machineBuilder: { ...mb, ...updates } }) } const toggleProductType = (type: MachineProductType) => { const current = mb.productTypes || [] if (current.includes(type)) { updateMB({ productTypes: current.filter(t => t !== type) }) } else { updateMB({ productTypes: [...current, type] }) } } const toggleAIType = (type: AIIntegrationType) => { const current = mb.aiIntegrationType || [] if (current.includes(type)) { updateMB({ aiIntegrationType: current.filter(t => t !== type) }) } else { updateMB({ aiIntegrationType: [...current, type] }) } } const toggleCriticalSector = (sector: CriticalSector) => { const current = mb.criticalSectors || [] if (current.includes(sector)) { updateMB({ criticalSectors: current.filter(s => s !== sector) }) } else { updateMB({ criticalSectors: [...current, sector] }) } } return (
{/* Block 1: Erzaehlen Sie uns von Ihrer Anlage */}

Erzaehlen Sie uns von Ihrer Anlage

Je besser wir Ihr Produkt verstehen, desto praeziser koennen wir die relevanten Vorschriften identifizieren.