'use client' /** * Requirements Page - Alle Compliance-Anforderungen mit Implementation-Status * * Features: * - Liste aller 19 Verordnungen mit URLs zu Originaldokumenten * - 558+ Requirements mit Implementation-Status * - Filterung nach Regulation, Status, Prioritaet * - Detail-Ansicht mit Breakpilot-Interpretation */ import { useState, useEffect } from 'react' import { PagePurpose } from '@/components/common/PagePurpose' // Types interface Regulation { id: string code: string name: string full_name: string regulation_type: string source_url: string local_pdf_path?: string effective_date?: string description: string is_active: boolean requirement_count: number } interface Requirement { id: string regulation_id: string regulation_code: string article: string paragraph?: string title: string description?: string requirement_text?: string breakpilot_interpretation?: string implementation_status: 'not_started' | 'in_progress' | 'implemented' | 'verified' | 'not_applicable' implementation_details?: string code_references?: Array<{ file: string; line?: number; description?: string }> evidence_description?: string priority: number is_applicable: boolean controls_count: number } const STATUS_CONFIG: Record = { not_started: { bg: 'bg-slate-100', text: 'text-slate-700', label: 'Nicht begonnen' }, in_progress: { bg: 'bg-yellow-100', text: 'text-yellow-700', label: 'In Arbeit' }, implemented: { bg: 'bg-blue-100', text: 'text-blue-700', label: 'Implementiert' }, verified: { bg: 'bg-green-100', text: 'text-green-700', label: 'Verifiziert' }, not_applicable: { bg: 'bg-slate-50', text: 'text-slate-500', label: 'N/A' }, } const PRIORITY_CONFIG: Record = { 1: { bg: 'bg-red-100', text: 'text-red-700', label: 'Kritisch' }, 2: { bg: 'bg-orange-100', text: 'text-orange-700', label: 'Hoch' }, 3: { bg: 'bg-yellow-100', text: 'text-yellow-700', label: 'Mittel' }, } const REGULATION_TYPE_LABELS: Record = { eu_regulation: 'EU-Verordnung', eu_directive: 'EU-Richtlinie', de_law: 'DE Gesetz', bsi_standard: 'BSI Standard', } export default function RequirementsPage() { const [regulations, setRegulations] = useState([]) const [requirements, setRequirements] = useState([]) const [selectedRegulation, setSelectedRegulation] = useState(null) const [selectedRequirement, setSelectedRequirement] = useState(null) const [loading, setLoading] = useState(true) const [requirementsLoading, setRequirementsLoading] = useState(false) // Filters const [statusFilter, setStatusFilter] = useState('') const [priorityFilter, setPriorityFilter] = useState('') const [searchQuery, setSearchQuery] = useState('') useEffect(() => { loadRegulations() }, []) useEffect(() => { if (selectedRegulation) { loadRequirements(selectedRegulation) } }, [selectedRegulation]) const loadRegulations = async () => { setLoading(true) try { const res = await fetch('/api/admin/compliance/regulations') if (res.ok) { const data = await res.json() setRegulations(data.regulations || data || []) } } catch (err) { console.error('Failed to load regulations:', err) } finally { setLoading(false) } } const loadRequirements = async (regulationCode: string) => { setRequirementsLoading(true) try { const params = new URLSearchParams({ regulation_code: regulationCode }) if (statusFilter) params.set('status', statusFilter) if (priorityFilter) params.set('priority', priorityFilter) if (searchQuery) params.set('search', searchQuery) const res = await fetch(`/api/admin/compliance/requirements?${params}`) if (res.ok) { const data = await res.json() setRequirements(data.requirements || data || []) } } catch (err) { console.error('Failed to load requirements:', err) } finally { setRequirementsLoading(false) } } const filteredRequirements = requirements.filter(req => { if (statusFilter && req.implementation_status !== statusFilter) return false if (priorityFilter && req.priority !== parseInt(priorityFilter)) return false if (searchQuery) { const query = searchQuery.toLowerCase() return ( req.title.toLowerCase().includes(query) || req.article.toLowerCase().includes(query) || req.description?.toLowerCase().includes(query) ) } return true }) const totalRequirements = regulations.reduce((sum, r) => sum + (r.requirement_count || 0), 0) return (
{/* Stats */}

{regulations.length}

Verordnungen

{totalRequirements}

Anforderungen

{regulations.filter(r => r.regulation_type === 'eu_regulation').length}

EU-Verordnungen

{regulations.filter(r => r.regulation_type === 'bsi_standard').length}

BSI Standards

{/* Regulations List */}

Verordnungen & Standards

{loading ? (
) : (
{regulations.map((reg) => (
setSelectedRegulation(reg.code)} className={`p-4 rounded-lg border cursor-pointer transition-colors ${ selectedRegulation === reg.code ? 'border-purple-500 bg-purple-50' : 'border-slate-200 hover:border-slate-300 bg-white' }`} >
{reg.code} {REGULATION_TYPE_LABELS[reg.regulation_type] || reg.regulation_type}

{reg.name}

{reg.description}

))}
)}
{/* Requirements List */}
{!selectedRegulation ? (

Waehlen Sie eine Verordnung

Waehlen Sie eine Verordnung aus der Liste um deren Anforderungen zu sehen.

) : ( <> {/* Filters */}
setSearchQuery(e.target.value)} placeholder="Suche in Anforderungen..." className="flex-1 min-w-[200px] px-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" />
{/* Requirements Table */}
{requirementsLoading ? (
) : filteredRequirements.length === 0 ? (
{requirements.length === 0 ? ( <>

Keine Anforderungen gefunden

Starten Sie den Scraper um Anforderungen zu extrahieren.

) : (

Keine Anforderungen entsprechen den Filterkriterien

)}
) : (
{filteredRequirements.map((req) => { const statusConfig = STATUS_CONFIG[req.implementation_status] || STATUS_CONFIG.not_started const priorityConfig = PRIORITY_CONFIG[req.priority] || PRIORITY_CONFIG[2] return (
setSelectedRequirement(selectedRequirement?.id === req.id ? null : req)} >
{req.article} {req.paragraph && ( ({req.paragraph}) )} {priorityConfig.label}

{req.title}

{req.description && (

{req.description}

)}
{statusConfig.label} {req.controls_count > 0 && ( {req.controls_count} Controls )}
{/* Expanded Details */} {selectedRequirement?.id === req.id && (
{req.requirement_text && (
Originaltext

{req.requirement_text}

)} {req.breakpilot_interpretation && (
Breakpilot Interpretation

{req.breakpilot_interpretation}

)} {req.implementation_details && (
Implementation

{req.implementation_details}

)} {req.code_references && req.code_references.length > 0 && (
Code-Referenzen
{req.code_references.map((ref, idx) => (
{ref.file} {ref.line && :{ref.line}} {ref.description && ( - {ref.description} )}
))}
)} {req.evidence_description && (
Nachweis

{req.evidence_description}

)}
)}
) })}
)}
{/* Summary */} {requirements.length > 0 && (

{filteredRequirements.length} von {requirements.length} Anforderungen angezeigt {statusFilter && (Status: {STATUS_CONFIG[statusFilter]?.label})} {priorityFilter && (Prioritaet: {PRIORITY_CONFIG[parseInt(priorityFilter)]?.label})}

)} )}
) }