'use client' import React, { useState, useEffect } from 'react' import { useSDK, Requirement as SDKRequirement, RequirementStatus, RiskSeverity } from '@/lib/sdk' import { StepHeader, STEP_EXPLANATIONS } from '@/components/sdk/StepHeader' // ============================================================================= // TYPES // ============================================================================= type DisplayPriority = 'critical' | 'high' | 'medium' | 'low' type DisplayStatus = 'compliant' | 'partial' | 'non-compliant' | 'not-applicable' interface DisplayRequirement extends SDKRequirement { code: string source: string category: string priority: DisplayPriority displayStatus: DisplayStatus controlsLinked: number evidenceCount: number } // ============================================================================= // HELPER FUNCTIONS // ============================================================================= function mapCriticalityToPriority(criticality: RiskSeverity): DisplayPriority { switch (criticality) { case 'CRITICAL': return 'critical' case 'HIGH': return 'high' case 'MEDIUM': return 'medium' case 'LOW': return 'low' default: return 'medium' } } function mapStatusToDisplayStatus(status: RequirementStatus): DisplayStatus { switch (status) { case 'VERIFIED': case 'IMPLEMENTED': return 'compliant' case 'IN_PROGRESS': return 'partial' case 'NOT_STARTED': return 'non-compliant' default: return 'non-compliant' } } // ============================================================================= // AVAILABLE REQUIREMENTS (Templates) // ============================================================================= const requirementTemplates: Omit[] = [ { id: 'req-gdpr-6', regulation: 'DSGVO', article: 'Art. 6', code: 'GDPR-6.1', title: 'Rechtmaessigkeit der Verarbeitung', description: 'Personenbezogene Daten duerfen nur verarbeitet werden, wenn eine Rechtsgrundlage vorliegt.', source: 'DSGVO Art. 6', category: 'Rechtmaessigkeit', priority: 'critical', criticality: 'CRITICAL', applicableModules: ['mod-gdpr'], status: 'NOT_STARTED', controls: [], }, { id: 'req-gdpr-13', regulation: 'DSGVO', article: 'Art. 13/14', code: 'GDPR-13', title: 'Informationspflichten', description: 'Betroffene Personen muessen ueber die Datenverarbeitung informiert werden.', source: 'DSGVO Art. 13/14', category: 'Transparenz', priority: 'high', criticality: 'HIGH', applicableModules: ['mod-gdpr'], status: 'NOT_STARTED', controls: [], }, { id: 'req-ai-act-9', regulation: 'AI Act', article: 'Art. 9', code: 'AI-ACT-9', title: 'Risikomanagementsystem', description: 'Hochrisiko-KI-Systeme erfordern ein Risikomanagementsystem.', source: 'AI Act Art. 9', category: 'KI-Governance', priority: 'high', criticality: 'HIGH', applicableModules: ['mod-ai-act'], status: 'NOT_STARTED', controls: [], }, { id: 'req-gdpr-32', regulation: 'DSGVO', article: 'Art. 32', code: 'GDPR-32', title: 'Sicherheit der Verarbeitung', description: 'Geeignete technische und organisatorische Massnahmen zur Datensicherheit.', source: 'DSGVO Art. 32', category: 'Sicherheit', priority: 'critical', criticality: 'CRITICAL', applicableModules: ['mod-gdpr', 'mod-iso27001'], status: 'NOT_STARTED', controls: [], }, { id: 'req-gdpr-35', regulation: 'DSGVO', article: 'Art. 35', code: 'GDPR-35', title: 'Datenschutz-Folgenabschaetzung', description: 'Bei hohem Risiko ist eine DSFA durchzufuehren.', source: 'DSGVO Art. 35', category: 'Risikobewertung', priority: 'high', criticality: 'HIGH', applicableModules: ['mod-gdpr'], status: 'NOT_STARTED', controls: [], }, { id: 'req-ai-act-13', regulation: 'AI Act', article: 'Art. 13', code: 'AI-ACT-13', title: 'Transparenzanforderungen', description: 'KI-Systeme muessen fuer Nutzer nachvollziehbar und transparent sein.', source: 'AI Act Art. 13', category: 'Transparenz', priority: 'high', criticality: 'HIGH', applicableModules: ['mod-ai-act'], status: 'NOT_STARTED', controls: [], }, { id: 'req-nis2-21', regulation: 'NIS2', article: 'Art. 21', code: 'NIS2-21', title: 'Risikomanagementmassnahmen', description: 'Wesentliche und wichtige Einrichtungen muessen Cybersicherheitsmassnahmen implementieren.', source: 'NIS2 Art. 21', category: 'Cybersicherheit', priority: 'high', criticality: 'HIGH', applicableModules: ['mod-nis2'], status: 'NOT_STARTED', controls: [], }, ] // ============================================================================= // COMPONENTS // ============================================================================= function RequirementCard({ requirement, onStatusChange, }: { requirement: DisplayRequirement onStatusChange: (status: RequirementStatus) => void }) { const priorityColors = { critical: 'bg-red-100 text-red-700', high: 'bg-orange-100 text-orange-700', medium: 'bg-yellow-100 text-yellow-700', low: 'bg-green-100 text-green-700', } const statusColors = { compliant: 'bg-green-100 text-green-700 border-green-200', partial: 'bg-yellow-100 text-yellow-700 border-yellow-200', 'non-compliant': 'bg-red-100 text-red-700 border-red-200', 'not-applicable': 'bg-gray-100 text-gray-500 border-gray-200', } const statusLabels = { compliant: 'Konform', partial: 'Teilweise', 'non-compliant': 'Nicht konform', 'not-applicable': 'N/A', } return (
{requirement.code} {requirement.priority === 'critical' ? 'Kritisch' : requirement.priority === 'high' ? 'Hoch' : requirement.priority === 'medium' ? 'Mittel' : 'Niedrig'} {requirement.regulation}

{requirement.title}

{requirement.description}

Quelle: {requirement.source}

{requirement.controlsLinked} Kontrollen {requirement.evidenceCount} Nachweise
) } // ============================================================================= // MAIN PAGE // ============================================================================= export default function RequirementsPage() { const { state, dispatch } = useSDK() const [filter, setFilter] = useState('all') const [searchQuery, setSearchQuery] = useState('') // Load requirements based on active modules useEffect(() => { // Only add requirements if there are active modules and no requirements yet if (state.modules.length > 0 && state.requirements.length === 0) { const activeModuleIds = state.modules.map(m => m.id) const relevantRequirements = requirementTemplates.filter(r => r.applicableModules.some(m => activeModuleIds.includes(m)) ) relevantRequirements.forEach(req => { const sdkRequirement: SDKRequirement = { id: req.id, regulation: req.regulation, article: req.article, title: req.title, description: req.description, criticality: req.criticality, applicableModules: req.applicableModules, status: 'NOT_STARTED', controls: [], } dispatch({ type: 'ADD_REQUIREMENT', payload: sdkRequirement }) }) } }, [state.modules, state.requirements.length, dispatch]) // Convert SDK requirements to display requirements const displayRequirements: DisplayRequirement[] = state.requirements.map(req => { const template = requirementTemplates.find(t => t.id === req.id) const linkedControls = state.controls.filter(c => c.evidence.includes(req.id)) const linkedEvidence = state.evidence.filter(e => e.controlId && linkedControls.some(c => c.id === e.controlId)) return { ...req, code: template?.code || req.id, source: template?.source || `${req.regulation} ${req.article}`, category: template?.category || req.regulation, priority: mapCriticalityToPriority(req.criticality), displayStatus: mapStatusToDisplayStatus(req.status), controlsLinked: linkedControls.length, evidenceCount: linkedEvidence.length, } }) const filteredRequirements = displayRequirements.filter(req => { const matchesFilter = filter === 'all' || req.displayStatus === filter || req.priority === filter const matchesSearch = searchQuery === '' || req.title.toLowerCase().includes(searchQuery.toLowerCase()) || req.code.toLowerCase().includes(searchQuery.toLowerCase()) return matchesFilter && matchesSearch }) const compliantCount = displayRequirements.filter(r => r.displayStatus === 'compliant').length const partialCount = displayRequirements.filter(r => r.displayStatus === 'partial').length const nonCompliantCount = displayRequirements.filter(r => r.displayStatus === 'non-compliant').length const handleStatusChange = (requirementId: string, status: RequirementStatus) => { dispatch({ type: 'UPDATE_REQUIREMENT', payload: { id: requirementId, data: { status } }, }) } const stepInfo = STEP_EXPLANATIONS['requirements'] return (
{/* Step Header */} {/* Module Alert */} {state.modules.length === 0 && (

Keine Module aktiviert

Bitte aktivieren Sie zuerst Compliance-Module, um die zugehoerigen Anforderungen zu laden.

)} {/* Stats */}
Gesamt
{displayRequirements.length}
Konform
{compliantCount}
In Bearbeitung
{partialCount}
Offen
{nonCompliantCount}
{/* Search and Filter */}
setSearchQuery(e.target.value)} placeholder="Anforderungen durchsuchen..." className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" />
{['all', 'compliant', 'partial', 'non-compliant', 'critical'].map(f => ( ))}
{/* Requirements List */}
{filteredRequirements.map(requirement => ( handleStatusChange(requirement.id, status)} /> ))}
{filteredRequirements.length === 0 && state.modules.length > 0 && (

Keine Anforderungen gefunden

Passen Sie die Suche oder den Filter an.

)}
) }