'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, } 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: 'Verarbeitung & KI', description: 'Verarbeitungstätigkeiten und KI-Systeme' }, { 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) // ============================================================================= // STEP COMPONENTS // ============================================================================= function StepBasicInfo({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { return (
onChange({ companyName: e.target.value })} placeholder="Ihre Firma (ohne Rechtsform)" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
{ const val = parseInt(e.target.value) onChange({ foundedYear: isNaN(val) ? null : val }) }} onFocus={e => { if (!data.foundedYear) onChange({ foundedYear: 2000 }) }} placeholder="2020" min="1900" 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" />
) } // URL fields shown when specific offerings are selected const OFFERING_URL_CONFIG: Partial> = { website: { label: 'Website-Domain', placeholder: 'https://www.beispiel.de', hint: 'Ihre Unternehmenswebsite' }, webshop: { label: 'Online-Shop URL', placeholder: 'https://shop.beispiel.de', hint: 'URL zu Ihrem Online-Shop' }, app_mobile: { label: 'App-Store Links', placeholder: 'https://apps.apple.com/... oder https://play.google.com/...', hint: 'Apple App Store und/oder Google Play Store Link' }, software_saas: { label: 'SaaS-Portal URL', placeholder: 'https://app.beispiel.de', hint: 'Login-/Registrierungsseite Ihres Kundenportals' }, app_web: { label: 'Web-App URL', placeholder: 'https://app.beispiel.de', hint: 'URL zu Ihrer Web-Anwendung' }, } // Step-specific explanations for "Warum diese Fragen?" const STEP_EXPLANATIONS: Record = { 1: 'Rechtsform und Gründungsjahr bestimmen, welche Meldepflichten und Schwellenwerte für Ihr Unternehmen gelten (z.B. NIS2, AI Act).', 2: 'Ihr Geschäftsmodell und Ihre Angebote bestimmen, welche DSGVO-Pflichten greifen: B2C erfordert z.B. strengere Einwilligungsregeln, Webshops brauchen Cookie-Banner und Datenschutzerklärungen, SaaS-Angebote eine Auftragsverarbeitung.', 3: 'Die Unternehmensgröße bestimmt, ob Sie einen DSB benennen müssen (ab 20 MA), ob NIS2-Pflichten greifen und welche Audit-Anforderungen gelten.', 4: 'Standorte und Zielmärkte bestimmen, welche nationalen Datenschutzgesetze zusätzlich zur DSGVO greifen (z.B. BDSG, DSG-AT, UK GDPR, CCPA).', 5: 'Ob Sie Verantwortlicher oder Auftragsverarbeiter sind, bestimmt Ihre DSGVO-Pflichten grundlegend. KI-Nutzung löst zusätzliche AI-Act-Pflichten aus.', 6: 'Ihre Verarbeitungstätigkeiten bilden die Grundlage für das Verarbeitungsverzeichnis (Art. 30 DSGVO). KI-Systeme werden für die AI-Act-Analyse erfasst — die Risikoeinstufung übernimmt unser Tool.', 7: 'Regulierungsrahmen und Prüfzyklen definieren, welche Compliance-Module für Sie aktiviert werden und in welchem Rhythmus Audits stattfinden.', 8: 'Als Maschinenbauer gelten zusätzliche Anforderungen: CE-Kennzeichnung, Maschinenverordnung, Produktsicherheit und ggf. Hochrisiko-KI im Sinne des AI Act.', } function StepBusinessModel({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { const toggleOffering = (offering: OfferingType) => { const current = data.offerings || [] if (current.includes(offering)) { // Remove offering and its URL const urls = { ...(data.offeringUrls || {}) } delete urls[offering] onChange({ offerings: current.filter(o => o !== offering), offeringUrls: urls }) } else { onChange({ offerings: [...current, offering] }) } } const updateOfferingUrl = (offering: string, url: string) => { onChange({ offeringUrls: { ...(data.offeringUrls || {}), [offering]: url } }) } // Offerings that are selected and have URL config const selectedWithUrls = (data.offerings || []).filter(o => o in OFFERING_URL_CONFIG) return (
{Object.entries(BUSINESS_MODEL_LABELS).map(([value, { short }]) => ( ))}
{data.businessModel && (

{BUSINESS_MODEL_LABELS[data.businessModel].description}

)}
{Object.entries(OFFERING_TYPE_LABELS).map(([value, { label, description }]) => ( ))}
{/* URL fields for selected offerings */} {selectedWithUrls.length > 0 && (
{selectedWithUrls.map(offering => { const config = OFFERING_URL_CONFIG[offering]! return (
updateOfferingUrl(offering, e.target.value)} placeholder={config.placeholder} className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />

{config.hint}

) })}
)}
) } function StepCompanySize({ data, onChange, }: { data: Partial onChange: (updates: Partial) => void }) { return (
{Object.entries(COMPANY_SIZE_LABELS).map(([value, label]) => ( ))}
{(data.companySize === 'medium' || data.companySize === 'large' || data.companySize === 'enterprise') && (

Geben Sie den konsolidierten Konzernumsatz an, wenn der Compliance-Check für Mutter- und Tochtergesellschaften gelten soll. Für eine einzelne Einheit eines Konzerns geben Sie nur deren Umsatz an.

)}
) } 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] }) } } const stateLabel = data.headquartersCountry === 'CH' ? 'Kanton' : data.headquartersCountry === 'AT' ? 'Bundesland' : data.headquartersCountry === 'DE' ? 'Bundesland' : 'Region / Provinz' return (
{/* Country */}
{/* Other country free text */} {data.headquartersCountry === 'other' && (
onChange({ headquartersCountryOther: e.target.value })} placeholder="z.B. Vereinigtes Königreich" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
)} {/* Street + House Number */}
onChange({ headquartersStreet: e.target.value })} placeholder="Musterstraße 42" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
{/* PLZ + City */}
onChange({ headquartersZip: e.target.value })} placeholder="10115" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
onChange({ headquartersCity: e.target.value })} placeholder="Berlin" className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
{/* State / Bundesland / Kanton */}
onChange({ headquartersState: e.target.value })} placeholder={data.headquartersCountry === 'CH' ? 'z.B. Zürich' : data.headquartersCountry === 'AT' ? 'z.B. Wien' : 'z.B. Bayern'} 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 }]) => ( ))}
) } 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: VERARBEITUNGSTAETIGKEITEN & KI // ============================================================================= // DSGVO-Standard Datenkategorien const DATA_CATEGORIES = [ { id: 'stammdaten', label: 'Stammdaten', desc: 'Name, Geburtsdatum, Geschlecht' }, { id: 'kontaktdaten', label: 'Kontaktdaten', desc: 'E-Mail, Telefon, Adresse' }, { id: 'vertragsdaten', label: 'Vertragsdaten', desc: 'Vertragsnummer, Laufzeit, Konditionen' }, { id: 'zahlungsdaten', label: 'Zahlungs-/Bankdaten', desc: 'IBAN, Kreditkarte, Rechnungen' }, { id: 'beschaeftigtendaten', label: 'Beschäftigtendaten', desc: 'Gehalt, Arbeitszeiten, Urlaub' }, { id: 'kommunikation', label: 'Kommunikationsdaten', desc: 'E-Mail-Inhalte, Chat-Verläufe' }, { id: 'nutzungsdaten', label: 'Nutzungs-/Logdaten', desc: 'IP-Adressen, Login-Zeiten, Klicks' }, { id: 'standortdaten', label: 'Standortdaten', desc: 'GPS, Check-in, Lieferadressen' }, { id: 'bilddaten', label: 'Bild-/Videodaten', desc: 'Fotos, Videoaufnahmen, Profilbilder' }, { id: 'bewerberdaten', label: 'Bewerberdaten', desc: 'Lebenslauf, Zeugnisse, Anschreiben' }, ] as const const SPECIAL_DATA_CATEGORIES = [ { id: 'gesundheit', label: 'Gesundheitsdaten', desc: 'Krankheitstage, Atteste, Diagnosen' }, { id: 'biometrie', label: 'Biometrische Daten', desc: 'Fingerabdruck, Gesichtserkennung' }, { id: 'religion', label: 'Religiöse Überzeugungen', desc: 'Konfession, Feiertage' }, { id: 'gewerkschaft', label: 'Gewerkschaftszugehörigkeit', desc: 'Mitgliedschaft' }, { id: 'genetik', label: 'Genetische Daten', desc: 'DNA, Erbkrankheiten' }, ] as const // Rechtsgrundlagen nach DSGVO Art. 6 const LEGAL_BASES = [ { id: 'consent', label: 'Einwilligung (Art. 6 Abs. 1a)' }, { id: 'contract', label: 'Vertragserfüllung (Art. 6 Abs. 1b)' }, { id: 'legal', label: 'Rechtliche Verpflichtung (Art. 6 Abs. 1c)' }, { id: 'interest', label: 'Berechtigtes Interesse (Art. 6 Abs. 1f)' }, ] as const // Verarbeitungstätigkeiten-Vorlagen nach Branche interface ProcessingActivityTemplate { id: string name: string purpose: string default_categories: string[] default_legal_basis: string } const COMMON_ACTIVITIES: ProcessingActivityTemplate[] = [ { id: 'personal', name: 'Personalverwaltung', purpose: 'Verwaltung von Mitarbeiterdaten, Gehaltsabrechnung, Arbeitszeitverwaltung', default_categories: ['stammdaten', 'kontaktdaten', 'beschaeftigtendaten', 'zahlungsdaten'], default_legal_basis: 'contract' }, { id: 'buchhaltung', name: 'Buchhaltung / Rechnungswesen', purpose: 'Rechnungsstellung, Zahlungsabwicklung, Steuerliche Pflichten', default_categories: ['stammdaten', 'kontaktdaten', 'vertragsdaten', 'zahlungsdaten'], default_legal_basis: 'legal' }, { id: 'bewerbung', name: 'Bewerbermanagement', purpose: 'Verwaltung von Bewerbungen und Auswahlverfahren', default_categories: ['stammdaten', 'kontaktdaten', 'bewerberdaten'], default_legal_basis: 'consent' }, { id: 'website', name: 'Website-Betrieb', purpose: 'Bereitstellung der Unternehmenswebsite, Analytics, Kontaktformulare', default_categories: ['nutzungsdaten', 'kontaktdaten'], default_legal_basis: 'interest' }, { id: 'email', name: 'E-Mail-Kommunikation', purpose: 'Geschäftliche E-Mail-Korrespondenz', default_categories: ['stammdaten', 'kontaktdaten', 'kommunikation'], default_legal_basis: 'interest' }, ] const INDUSTRY_ACTIVITIES: Record = { 'Technologie / IT': [ { id: 'crm', name: 'CRM / Kundenverwaltung', purpose: 'Pflege von Kundenbeziehungen, Vertriebspipeline', default_categories: ['stammdaten', 'kontaktdaten', 'vertragsdaten', 'kommunikation'], default_legal_basis: 'contract' }, { id: 'support', name: 'Support / Ticketsystem', purpose: 'Kundenanfragen bearbeiten, Fehlerbehebung', default_categories: ['stammdaten', 'kontaktdaten', 'kommunikation', 'nutzungsdaten'], default_legal_basis: 'contract' }, { id: 'saas', name: 'SaaS-Plattform / Nutzerkonten', purpose: 'Bereitstellung der Software, Nutzerverwaltung', default_categories: ['stammdaten', 'kontaktdaten', 'nutzungsdaten', 'vertragsdaten'], default_legal_basis: 'contract' }, ], 'E-Commerce / Handel': [ { id: 'bestellung', name: 'Bestellabwicklung', purpose: 'Bestellannahme, Zahlungsabwicklung, Versand', default_categories: ['stammdaten', 'kontaktdaten', 'zahlungsdaten', 'vertragsdaten', 'standortdaten'], default_legal_basis: 'contract' }, { id: 'kundenkonto', name: 'Kundenkonto-Verwaltung', purpose: 'Registrierung, Login, Bestellhistorie', default_categories: ['stammdaten', 'kontaktdaten', 'nutzungsdaten'], default_legal_basis: 'contract' }, { id: 'newsletter', name: 'Newsletter / Marketing', purpose: 'E-Mail-Marketing, Werbeaktionen', default_categories: ['stammdaten', 'kontaktdaten', 'nutzungsdaten'], default_legal_basis: 'consent' }, ], 'Finanzdienstleistungen': [ { id: 'konto', name: 'Kontoverwaltung', purpose: 'Kontoeröffnung, KYC, Kontopflege', default_categories: ['stammdaten', 'kontaktdaten', 'zahlungsdaten', 'vertragsdaten'], default_legal_basis: 'contract' }, { id: 'compliance_fin', name: 'Regulatorische Pflichten', purpose: 'Geldwäscheprävention, Meldepflichten', default_categories: ['stammdaten', 'zahlungsdaten'], default_legal_basis: 'legal' }, ], 'Gesundheitswesen': [ { id: 'patient', name: 'Patientenverwaltung', purpose: 'Aufnahme, Behandlung, Dokumentation', default_categories: ['stammdaten', 'kontaktdaten', 'gesundheit'], default_legal_basis: 'contract' }, { id: 'termin', name: 'Terminplanung', purpose: 'Terminvergabe und -verwaltung', default_categories: ['stammdaten', 'kontaktdaten'], default_legal_basis: 'contract' }, { id: 'abrechnung_kv', name: 'Abrechnung / KV', purpose: 'Kassenärztliche Abrechnung, Privatliquidation', default_categories: ['stammdaten', 'zahlungsdaten', 'gesundheit'], default_legal_basis: 'legal' }, ], 'Beratung / Consulting': [ { id: 'crm', name: 'CRM / Kundenverwaltung', purpose: 'Pflege von Kundenbeziehungen, Projekthistorie', default_categories: ['stammdaten', 'kontaktdaten', 'vertragsdaten', 'kommunikation'], default_legal_basis: 'contract' }, { id: 'projekt', name: 'Projektmanagement', purpose: 'Projektverwaltung, Zeiterfassung, Dokumentation', default_categories: ['stammdaten', 'beschaeftigtendaten', 'kommunikation'], default_legal_basis: 'contract' }, ], 'Bildung': [ { id: 'schueler', name: 'Schüler-/Teilnehmerverwaltung', purpose: 'Verwaltung von Lernenden, Noten, Anwesenheit', default_categories: ['stammdaten', 'kontaktdaten', 'nutzungsdaten'], default_legal_basis: 'contract' }, { id: 'lernplattform', name: 'Lernplattform / LMS', purpose: 'Bereitstellung von Lernmaterialien, Prüfungen', default_categories: ['stammdaten', 'nutzungsdaten', 'kommunikation'], default_legal_basis: 'contract' }, ], 'Marketing / Agentur': [ { id: 'crm', name: 'CRM / Kundenverwaltung', purpose: 'Pflege von Kundenbeziehungen, Kampagnen', default_categories: ['stammdaten', 'kontaktdaten', 'vertragsdaten', 'kommunikation'], default_legal_basis: 'contract' }, { id: 'campaign', name: 'Kampagnen / Analytics', purpose: 'Werbekampagnen, Tracking, Auswertung', default_categories: ['nutzungsdaten', 'kontaktdaten', 'standortdaten'], default_legal_basis: 'consent' }, ], 'Produktion / Industrie': [ { id: 'lieferanten', name: 'Lieferantenverwaltung', purpose: 'Bestellungen, Lieferantenqualifizierung', default_categories: ['stammdaten', 'kontaktdaten', 'vertragsdaten', 'zahlungsdaten'], default_legal_basis: 'contract' }, { id: 'zutrittskontrolle', name: 'Zutrittskontrolle', purpose: 'Werksgelände-Zugang, Besuchermanagement', default_categories: ['stammdaten', 'standortdaten', 'bilddaten'], default_legal_basis: 'interest' }, ], } // Get processing activity templates for the selected industry function getActivityTemplates(industry: string): ProcessingActivityTemplate[] { const industrySpecific = INDUSTRY_ACTIVITIES[industry] || [] // Merge common + industry-specific, avoiding duplicate IDs const existingIds = new Set(industrySpecific.map(a => a.id)) const common = COMMON_ACTIVITIES.filter(a => !existingIds.has(a.id)) return [...industrySpecific, ...common] } interface ProcessingActivity { id: string name: string purpose: string data_categories: string[] legal_basis: string custom?: boolean } interface AISystem { name: string vendor: string purpose: string processes_personal_data: boolean } function StepProcessingAndAI({ data, onChange, }: { data: Partial & { processingSystems?: ProcessingActivity[]; aiSystems?: AISystem[] } onChange: (updates: Record) => void }) { const activities: ProcessingActivity[] = (data as any).processingSystems || [] const aiSystems: AISystem[] = (data as any).aiSystems || [] const industry = data.industry || '' const [expandedActivity, setExpandedActivity] = useState(null) // Get suggested templates based on industry const templates = getActivityTemplates(industry) const activeIds = new Set(activities.map(a => a.id)) const toggleActivity = (template: ProcessingActivityTemplate) => { if (activeIds.has(template.id)) { onChange({ processingSystems: activities.filter(a => a.id !== template.id) }) } else { onChange({ processingSystems: [...activities, { id: template.id, name: template.name, purpose: template.purpose, data_categories: [...template.default_categories], legal_basis: template.default_legal_basis, }], }) } } const updateActivity = (id: string, updates: Partial) => { onChange({ processingSystems: activities.map(a => a.id === id ? { ...a, ...updates } : a), }) } const toggleDataCategory = (activityId: string, categoryId: string) => { const activity = activities.find(a => a.id === activityId) if (!activity) return const cats = activity.data_categories.includes(categoryId) ? activity.data_categories.filter(c => c !== categoryId) : [...activity.data_categories, categoryId] updateActivity(activityId, { data_categories: cats }) } const addCustomActivity = () => { const id = `custom_${Date.now()}` onChange({ processingSystems: [...activities, { id, name: '', purpose: '', data_categories: [], legal_basis: 'contract', custom: true, }], }) setExpandedActivity(id) } const removeActivity = (id: string) => { onChange({ processingSystems: activities.filter(a => a.id !== id) }) if (expandedActivity === id) setExpandedActivity(null) } // AI Systems const addAISystem = () => { onChange({ aiSystems: [...aiSystems, { name: '', vendor: '', purpose: '', processes_personal_data: false }] }) } 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 Activities */}

Verarbeitungstätigkeiten

Wählen Sie aus, welche Verarbeitungstätigkeiten in Ihrem Unternehmen stattfinden. Diese bilden die Grundlage für Ihr Verarbeitungsverzeichnis (VVT) nach Art. 30 DSGVO.

{/* Template checkboxes */}
{templates.map(template => { const isActive = activeIds.has(template.id) const activity = activities.find(a => a.id === template.id) const isExpanded = expandedActivity === template.id return (
{ if (!isActive) { toggleActivity(template) setExpandedActivity(template.id) } else { setExpandedActivity(isExpanded ? null : template.id) } }} > { e.stopPropagation() toggleActivity(template) }} className="w-4 h-4 text-purple-600 rounded focus:ring-purple-500 flex-shrink-0" />
{template.name}

{template.purpose}

{isActive && ( {activity?.data_categories.length || 0} Kategorien )} {isActive && ( )}
{/* Expanded detail: data categories + legal basis */} {isActive && isExpanded && activity && (
{/* Data Categories */}
{DATA_CATEGORIES.map(cat => ( ))}
{/* Special Categories (Art. 9) */}
{SPECIAL_DATA_CATEGORIES.map(cat => ( ))}
{/* Legal Basis */}
{/* Remove button for template-based activities */}
)}
) })}
{/* Custom activities */} {activities.filter(a => a.custom).map(activity => (
setExpandedActivity(expandedActivity === activity.id ? null : activity.id)} >
{activity.name || 'Neue Verarbeitungstätigkeit'}
{expandedActivity === activity.id && (
updateActivity(activity.id, { name: e.target.value })} placeholder="Name der Verarbeitungstätigkeit" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" /> updateActivity(activity.id, { purpose: e.target.value })} placeholder="Zweck der Verarbeitung" className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
{/* Data Categories */}
{DATA_CATEGORIES.map(cat => ( ))}
{/* Special Categories */}
{SPECIAL_DATA_CATEGORIES.map(cat => ( ))}
{/* Legal Basis */}
)}
))} {/* Add custom activity button */}
{/* AI Systems — simplified */}

KI-Systeme

Welche KI-Systeme setzen Sie ein? Die Risikoeinstufung nach AI Act ermittelt unser Tool automatisch.

{aiSystems.length === 0 && (
Noch keine KI-Systeme — falls Sie keine einsetzen, einfach leer lassen
)}
{aiSystems.map((ai: AISystem, i: number) => (
KI-System {i + 1}
updateAISystem(i, { name: e.target.value })} placeholder="Name (z.B. ChatGPT, Copilot)" 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 (z.B. OpenAI, Microsoft)" 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="Einsatzzweck (z.B. Kundensupport, Code-Assistenz)" 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.