'use client' import { useState, useEffect } from 'react' import Link from 'next/link' interface ComplianceTrigger { id: string regulation: string article: string title: string severity: 'high' | 'medium' | 'low' reason: string affected_hazard_count?: number module_path: string module_label: string } interface TriggersResponse { triggers: ComplianceTrigger[] total: number } const SEVERITY_CONFIG: Record = { high: { border: 'border-red-200 dark:border-red-800', bg: 'bg-red-50 dark:bg-red-900/20', text: 'text-red-700 dark:text-red-400', badge: 'bg-red-100 text-red-800 dark:bg-red-900/50 dark:text-red-300', icon: 'text-red-500', }, medium: { border: 'border-yellow-200 dark:border-yellow-800', bg: 'bg-yellow-50 dark:bg-yellow-900/20', text: 'text-yellow-700 dark:text-yellow-400', badge: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/50 dark:text-yellow-300', icon: 'text-yellow-500', }, low: { border: 'border-blue-200 dark:border-blue-800', bg: 'bg-blue-50 dark:bg-blue-900/20', text: 'text-blue-700 dark:text-blue-400', badge: 'bg-blue-100 text-blue-800 dark:bg-blue-900/50 dark:text-blue-300', icon: 'text-blue-500', }, } const SEVERITY_LABELS: Record = { high: 'HOCH', medium: 'MITTEL', low: 'NIEDRIG', } const REGULATION_BADGES: { key: string; label: string; activeColor: string }[] = [ { key: 'DSGVO', label: 'DSGVO', activeColor: 'bg-red-100 text-red-800 border-red-300' }, { key: 'AI Act', label: 'AI Act', activeColor: 'bg-orange-100 text-orange-800 border-orange-300' }, { key: 'CRA', label: 'CRA', activeColor: 'bg-yellow-100 text-yellow-800 border-yellow-300' }, { key: 'NIS2', label: 'NIS2', activeColor: 'bg-indigo-100 text-indigo-800 border-indigo-300' }, { key: 'Data Act', label: 'Data Act', activeColor: 'bg-amber-100 text-amber-800 border-amber-300' }, ] function WarningIcon({ className }: { className?: string }) { return ( ) } function ChevronIcon({ open }: { open: boolean }) { return ( ) } export function ComplianceAlerts({ projectId }: { projectId: string }) { const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [collapsed, setCollapsed] = useState(false) const [expandedIds, setExpandedIds] = useState>(new Set()) useEffect(() => { fetch(`/api/sdk/v1/iace/projects/${projectId}/compliance-triggers`) .then((r) => (r.ok ? r.json() : null)) .then((json) => { if (!json) return // Map API format (nested trigger object) to flat frontend format const raw = json.triggers || [] const mapped: ComplianceTrigger[] = raw.map((t: Record, i: number) => { const inner = (t.trigger || t) as Record const reg = (inner.regulation || '') as string return { id: (t.hazard_id as string) || `trigger-${i}`, regulation: reg.split(' ')[0] || reg, article: reg.includes(' ') ? reg.split(' ').slice(1).join(' ') : '', title: (inner.action_de || inner.trigger_cond_de || '') as string, severity: ((inner.severity || 'medium') as string) as 'high' | 'medium' | 'low', reason: (inner.trigger_cond_de || '') as string, affected_hazard_count: 1, module_path: (inner.module_link || '/sdk') as string, module_label: ((inner.module || 'Modul') as string).toUpperCase(), } }) setData({ triggers: mapped, total: mapped.length }) }) .catch(() => {}) .finally(() => setLoading(false)) }, [projectId]) if (loading) return null if (!data || data.triggers.length === 0) return null const triggers = data.triggers const activeRegulations = new Set(triggers.map((t) => t.regulation)) function toggleExpanded(id: string) { setExpandedIds((prev) => { const next = new Set(prev) if (next.has(id)) next.delete(id) else next.add(id) return next }) } return (
{/* Header */} {!collapsed && (
{/* Regulation summary badges */}
{REGULATION_BADGES.map((reg) => { const active = activeRegulations.has(reg.key) return ( {reg.label} ) })}
{/* Trigger list */}
{triggers.map((trigger) => { const sev = SEVERITY_CONFIG[trigger.severity] || SEVERITY_CONFIG.low const isOpen = expandedIds.has(trigger.id) return (
{/* Trigger header row */} {/* Expanded detail */} {isOpen && (

Grund: {trigger.reason}

{trigger.affected_hazard_count != null && trigger.affected_hazard_count > 0 && (

Betroffene Gefaehrdungen: {trigger.affected_hazard_count}

)} {trigger.module_label} oeffnen
)}
) })}
{/* Disclaimer */}
Hinweis: Diese Compliance-Hinweise werden automatisch aus den Gefaehrdungen und Klassifikationen abgeleitet. Der CE-Fachmann muss die regulatorischen Anforderungen im jeweiligen Modul verifizieren.
)}
) }