'use client' /** * Compliance Hub Page (SDK Version - Zusatzmodul) * * Central compliance management dashboard with: * - Compliance Score Overview * - Quick Access to all compliance modules (SDK paths) * - Control-Mappings with statistics * - Audit Findings * - Regulations overview */ import { useState, useEffect } from 'react' import Link from 'next/link' // Types interface DashboardData { compliance_score: number total_regulations: number total_requirements: number total_controls: number controls_by_status: Record controls_by_domain: Record> total_evidence: number evidence_by_status: Record total_risks: number risks_by_level: Record } interface Regulation { id: string code: string name: string full_name: string regulation_type: string effective_date: string | null description: string requirement_count: number } interface MappingsData { total: number by_regulation: Record } interface FindingsData { major_count: number minor_count: number ofi_count: number total: number open_majors: number open_minors: number } const DOMAIN_LABELS: Record = { gov: 'Governance', priv: 'Datenschutz', iam: 'Identity & Access', crypto: 'Kryptografie', sdlc: 'Secure Dev', ops: 'Operations', ai: 'KI-spezifisch', cra: 'Supply Chain', aud: 'Audit', } export default function ComplianceHubPage() { const [dashboard, setDashboard] = useState(null) const [regulations, setRegulations] = useState([]) const [mappings, setMappings] = useState(null) const [findings, setFindings] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [seeding, setSeeding] = useState(false) useEffect(() => { loadData() }, []) const loadData = async () => { setLoading(true) setError(null) try { const [dashboardRes, regulationsRes, mappingsRes, findingsRes] = await Promise.all([ fetch('/api/admin/compliance/dashboard'), fetch('/api/admin/compliance/regulations'), fetch('/api/admin/compliance/mappings'), fetch('/api/admin/compliance/isms/findings/summary'), ]) if (dashboardRes.ok) { setDashboard(await dashboardRes.json()) } if (regulationsRes.ok) { const data = await regulationsRes.json() setRegulations(data.regulations || []) } if (mappingsRes.ok) { const data = await mappingsRes.json() setMappings(data) } if (findingsRes.ok) { const data = await findingsRes.json() setFindings(data) } } catch (err) { console.error('Failed to load compliance data:', err) setError('Verbindung zum Backend fehlgeschlagen') } finally { setLoading(false) } } const seedDatabase = async () => { setSeeding(true) try { const res = await fetch('/api/admin/compliance/seed', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ force: false }), }) if (res.ok) { const result = await res.json() alert(`Datenbank erfolgreich initialisiert!\n\nRegulations: ${result.counts?.regulations || 0}\nControls: ${result.counts?.controls || 0}\nRequirements: ${result.counts?.requirements || 0}`) loadData() } else { const error = await res.text() alert(`Fehler beim Seeding: ${error}`) } } catch (err) { console.error('Seeding failed:', err) alert('Fehler beim Initialisieren der Datenbank') } finally { setSeeding(false) } } const score = dashboard?.compliance_score || 0 const scoreColor = score >= 80 ? 'text-green-600' : score >= 60 ? 'text-yellow-600' : 'text-red-600' const scoreBgColor = score >= 80 ? 'bg-green-500' : score >= 60 ? 'bg-yellow-500' : 'bg-red-500' return (
{/* Title Card (Zusatzmodul - no StepHeader) */}

Compliance Hub

Zentrale Verwaltung aller Compliance-Anforderungen nach DSGVO, AI Act, BSI TR-03161 und weiteren Regulierungen.

{/* Error Banner */} {error && (
{error}
)} {/* Seed Button if no data */} {!loading && (dashboard?.total_controls || 0) === 0 && (

Keine Compliance-Daten vorhanden

Initialisieren Sie die Datenbank mit den Seed-Daten.

)} {/* Quick Actions */}

Schnellzugriff

Audit Checkliste

{dashboard?.total_requirements || '...'} Anforderungen

Controls

{dashboard?.total_controls || '...'} Massnahmen

Evidence

Nachweise

Risk Matrix

5x5 Risiken

Service Registry

Module

Audit Report

PDF Export

{loading ? (
) : ( <> {/* Score and Stats Row */}

Compliance Score

{score.toFixed(0)}%

{dashboard?.controls_by_status?.pass || 0} von {dashboard?.total_controls || 0} Controls bestanden

Verordnungen

{dashboard?.total_regulations || 0}

{dashboard?.total_requirements || 0} Anforderungen

Controls

{dashboard?.total_controls || 0}

{dashboard?.controls_by_status?.pass || 0} bestanden

Nachweise

{dashboard?.total_evidence || 0}

{dashboard?.evidence_by_status?.valid || 0} aktiv

Risiken

{dashboard?.total_risks || 0}

{(dashboard?.risks_by_level?.high || 0) + (dashboard?.risks_by_level?.critical || 0)} kritisch

{/* Control-Mappings & Findings Row */}

Control-Mappings

Alle anzeigen →

{mappings?.total || 474}

Mappings gesamt

Nach Verordnung

{mappings?.by_regulation && Object.entries(mappings.by_regulation).slice(0, 5).map(([reg, count]) => ( {reg}: {count} ))} {!mappings?.by_regulation && ( <> GDPR: 180 AI Act: 95 BSI: 120 CRA: 79 )}

Automatisch generierte Verknuepfungen zwischen {dashboard?.total_controls || 44} Controls und {dashboard?.total_requirements || 558} Anforderungen aus {dashboard?.total_regulations || 19} Verordnungen.

Audit Findings

Audit Checkliste →
Hauptabweichungen

{findings?.open_majors || 0}

offen (blockiert Zertifizierung)

Nebenabweichungen

{findings?.open_minors || 0}

offen (erfordert CAPA)

Gesamt: {findings?.total || 0} Findings ({findings?.major_count || 0} Major, {findings?.minor_count || 0} Minor, {findings?.ofi_count || 0} OFI) {(findings?.open_majors || 0) === 0 ? ( Zertifizierung moeglich ) : ( Zertifizierung blockiert )}
{/* Domain Chart */}

Controls nach Domain

{Object.entries(dashboard?.controls_by_domain || {}).map(([domain, stats]) => { const total = stats.total || 0 const pass = stats.pass || 0 const partial = stats.partial || 0 const passPercent = total > 0 ? ((pass + partial * 0.5) / total) * 100 : 0 return (
{DOMAIN_LABELS[domain] || domain.toUpperCase()} {pass}/{total} ({passPercent.toFixed(0)}%)
) })}
{/* Regulations Table */}

Verordnungen & Standards ({regulations.length})

{regulations.slice(0, 15).map((reg) => ( ))}
Code Name Typ Anforderungen
{reg.code}

{reg.name}

{reg.regulation_type === 'eu_regulation' ? 'EU-VO' : reg.regulation_type === 'eu_directive' ? 'EU-RL' : reg.regulation_type === 'bsi_standard' ? 'BSI' : reg.regulation_type === 'de_law' ? 'DE' : reg.regulation_type} {reg.requirement_count}
)}
) }