'use client' /** * Screen Flow Visualization - Compliance SDK * * Visualisiert alle Screens aus: * - Admin Compliance (Port 3007): Verwaltung * - SDK Pipeline: Compliance-Module */ import { useCallback, useState, useMemo, useEffect } from 'react' import ReactFlow, { Node, Edge, Controls, Background, MiniMap, useNodesState, useEdgesState, BackgroundVariant, MarkerType, Panel, } from 'reactflow' import 'reactflow/dist/style.css' // ============================================ // TYPES // ============================================ interface ScreenDefinition { id: string name: string description: string category: string icon: string url?: string } interface ConnectionDef { source: string target: string label?: string } // ============================================ // ADMIN COMPLIANCE SCREENS (Port 3007) // ============================================ const SCREENS: ScreenDefinition[] = [ // === DASHBOARD & VERWALTUNG (Blue) === { id: 'dashboard', name: 'Dashboard', description: 'Uebersicht & Statistiken', category: 'dashboard', icon: '🏠', url: '/dashboard' }, { id: 'catalog-manager', name: 'Katalogverwaltung', description: 'SDK-Kataloge & Auswahltabellen', category: 'dashboard', icon: '📦', url: '/dashboard/catalog-manager' }, // === DSGVO-GRUNDLAGEN (Violet) === { id: 'vvt', name: 'VVT', description: 'Verarbeitungsverzeichnis Art. 30', category: 'dsgvo', icon: '📋', url: '/sdk/vvt' }, { id: 'dsfa', name: 'DSFA', description: 'Datenschutz-Folgenabschaetzung', category: 'dsgvo', icon: '⚖️', url: '/sdk/dsfa' }, { id: 'tom', name: 'TOMs', description: 'Technische & Org. Massnahmen', category: 'dsgvo', icon: '🛡️', url: '/sdk/tom' }, { id: 'tom-generator', name: 'TOM Generator', description: 'TOM-Erstellung mit Wizard', category: 'dsgvo', icon: '⚙️', url: '/sdk/tom-generator' }, { id: 'loeschfristen', name: 'Loeschfristen', description: 'Aufbewahrung & Deadlines', category: 'dsgvo', icon: '🗑️', url: '/sdk/loeschfristen' }, { id: 'einwilligungen', name: 'Einwilligungen', description: 'Nutzer-Consent Uebersicht', category: 'dsgvo', icon: '✅', url: '/sdk/einwilligungen' }, { id: 'dsr', name: 'Datenschutzanfragen', description: 'DSGVO Art. 15-21 (DSR)', category: 'dsgvo', icon: '🔒', url: '/sdk/dsr' }, { id: 'consent', name: 'Consent Verwaltung', description: 'Rechtliche Dokumente & Versionen', category: 'dsgvo', icon: '📄', url: '/sdk/consent' }, { id: 'consent-management', name: 'Consent Management', description: 'Einwilligungsmanagement', category: 'dsgvo', icon: '📝', url: '/sdk/consent-management' }, // === COMPLIANCE-MANAGEMENT (Purple) === { id: 'compliance-hub', name: 'Compliance Hub', description: 'Zentrales GRC Dashboard', category: 'compliance', icon: '✅', url: '/sdk/compliance-hub' }, { id: 'compliance-scope', name: 'Compliance Scope', description: 'Geltungsbereich definieren', category: 'compliance', icon: '🎯', url: '/sdk/compliance-scope' }, { id: 'requirements', name: 'Requirements', description: '558+ aus 19 Verordnungen', category: 'compliance', icon: '📜', url: '/sdk/requirements' }, { id: 'controls', name: 'Controls', description: '474 Control-Mappings', category: 'compliance', icon: '🎛️', url: '/sdk/controls' }, { id: 'evidence', name: 'Evidence', description: 'Nachweise & Dokumentation', category: 'compliance', icon: '📎', url: '/sdk/evidence' }, { id: 'risks', name: 'Risiken', description: 'Risk Matrix & Register', category: 'compliance', icon: '⚠️', url: '/sdk/risks' }, { id: 'audit-checklist', name: 'Audit Checkliste', description: '476 Anforderungen pruefen', category: 'compliance', icon: '📋', url: '/sdk/audit-checklist' }, { id: 'audit-report', name: 'Audit Report', description: 'PDF Audit-Berichte', category: 'compliance', icon: '📊', url: '/sdk/audit-report' }, { id: 'workflow', name: 'Workflow', description: 'Freigabe-Workflows', category: 'compliance', icon: '🔄', url: '/sdk/workflow' }, { id: 'modules', name: 'Service Registry', description: '30+ Service-Module', category: 'compliance', icon: '🔧', url: '/sdk/modules' }, // === KI & AUTOMATISIERUNG (Teal) === { id: 'ai-act', name: 'EU-AI-Act', description: 'KI-Risikoklassifizierung', category: 'ai', icon: '🤖', url: '/sdk/ai-act' }, { id: 'screening', name: 'Screening', description: 'Compliance-Screening & Pruefung', category: 'ai', icon: '🔍', url: '/sdk/screening' }, { id: 'rag', name: 'Daten & RAG', description: 'Training Data & RAG', category: 'ai', icon: '🗄️', url: '/sdk/rag' }, { id: 'quality', name: 'Qualitaet & Audit', description: 'Compliance-Audit & Traceability', category: 'ai', icon: '✨', url: '/sdk/quality' }, { id: 'advisory-board', name: 'Advisory Board', description: 'KI-Use-Case Pruefung', category: 'ai', icon: '🧑‍⚖️', url: '/sdk/advisory-board' }, { id: 'obligations', name: 'Pflichten', description: 'NIS2, DSGVO, AI Act', category: 'ai', icon: '⚡', url: '/sdk/obligations' }, { id: 'escalations', name: 'Eskalations-Queue', description: 'DSB Review & Freigabe', category: 'ai', icon: '🚨', url: '/sdk/escalations' }, // === DOKUMENTE & LEGAL (Orange) === { id: 'document-generator', name: 'Document Generator', description: 'Datenschutz-Dokumente erstellen', category: 'documents', icon: '📄', url: '/sdk/document-generator' }, { id: 'notfallplan', name: 'Notfallplan', description: 'Incident Response Plan', category: 'documents', icon: '🚨', url: '/sdk/notfallplan' }, { id: 'source-policy', name: 'Quellen-Policy', description: 'Datenquellen & Compliance', category: 'documents', icon: '📚', url: '/sdk/source-policy' }, { id: 'cookie-banner', name: 'Cookie-Banner', description: 'Cookie Consent Builder', category: 'documents', icon: '🍪', url: '/sdk/cookie-banner' }, { id: 'company-profile', name: 'Unternehmensprofil', description: 'Firmen-Stammdaten', category: 'documents', icon: '🏢', url: '/sdk/company-profile' }, { id: 'security-backlog', name: 'Security Backlog', description: 'Sicherheits-Massnahmen Tracking', category: 'documents', icon: '🔐', url: '/sdk/security-backlog' }, // === VENDOR & EXTERN (Green) === { id: 'vendor-compliance', name: 'Vendor Compliance', description: 'Lieferanten-Management', category: 'vendor', icon: '🏭', url: '/sdk/vendor-compliance' }, { id: 'vendor-vendors', name: 'Vendor-Liste', description: 'Lieferanten-Uebersicht', category: 'vendor', icon: '📋', url: '/sdk/vendor-compliance/vendors' }, { id: 'vendor-contracts', name: 'Vertraege', description: 'AVV & Vertragsmanagement', category: 'vendor', icon: '📝', url: '/sdk/vendor-compliance/contracts' }, { id: 'vendor-controls', name: 'Vendor Controls', description: 'Lieferanten-Kontrollen', category: 'vendor', icon: '🎛️', url: '/sdk/vendor-compliance/controls' }, { id: 'vendor-risks', name: 'Vendor Risiken', description: 'Lieferanten-Risikobewertung', category: 'vendor', icon: '⚠️', url: '/sdk/vendor-compliance/risks' }, { id: 'vendor-processing', name: 'Verarbeitungen', description: 'Auftragsverarbeitung', category: 'vendor', icon: '🔄', url: '/sdk/vendor-compliance/processing-activities' }, { id: 'vendor-reports', name: 'Vendor Reports', description: 'Lieferanten-Berichte', category: 'vendor', icon: '📊', url: '/sdk/vendor-compliance/reports' }, { id: 'dsms', name: 'DSMS', description: 'Datenschutz-Management-System', category: 'vendor', icon: '🏛️', url: '/sdk/dsms' }, { id: 'import', name: 'Import', description: 'Daten-Import', category: 'vendor', icon: '📥', url: '/sdk/import' }, // === ENTWICKLUNG (Slate) === { id: 'dev-docs', name: 'Developer Docs', description: 'API & Architektur', category: 'development', icon: '📖', url: '/development/docs' }, { id: 'dev-screen-flow', name: 'Screen Flow', description: 'UI Screen-Verbindungen', category: 'development', icon: '🔀', url: '/development/screen-flow' }, { id: 'dev-brandbook', name: 'Brandbook', description: 'Corporate Design', category: 'development', icon: '🎨', url: '/development/brandbook' }, ] const CONNECTIONS: ConnectionDef[] = [ // === DASHBOARD FLOW === { source: 'dashboard', target: 'catalog-manager', label: 'Kataloge' }, { source: 'dashboard', target: 'compliance-hub', label: 'Compliance' }, { source: 'dashboard', target: 'vvt', label: 'VVT' }, // === DSGVO FLOW === { source: 'consent-management', target: 'einwilligungen', label: 'Nutzer' }, { source: 'consent-management', target: 'dsr' }, { source: 'consent', target: 'consent-management' }, { source: 'consent', target: 'cookie-banner' }, { source: 'dsr', target: 'loeschfristen' }, { source: 'vvt', target: 'tom' }, { source: 'vvt', target: 'dsfa' }, { source: 'dsfa', target: 'tom' }, { source: 'tom', target: 'tom-generator', label: 'Wizard' }, { source: 'einwilligungen', target: 'consent' }, { source: 'einwilligungen', target: 'loeschfristen' }, // === COMPLIANCE FLOW === { source: 'compliance-hub', target: 'audit-checklist', label: 'Audit' }, { source: 'compliance-hub', target: 'requirements', label: 'Anforderungen' }, { source: 'compliance-hub', target: 'risks', label: 'Risiken' }, { source: 'compliance-hub', target: 'ai-act', label: 'AI Act' }, { source: 'compliance-hub', target: 'compliance-scope' }, { source: 'requirements', target: 'controls' }, { source: 'controls', target: 'evidence' }, { source: 'audit-checklist', target: 'audit-report', label: 'Report' }, { source: 'risks', target: 'controls' }, { source: 'modules', target: 'controls' }, { source: 'obligations', target: 'requirements' }, { source: 'dsms', target: 'workflow' }, { source: 'workflow', target: 'audit-report' }, // === KI & AUTOMATISIERUNG FLOW === { source: 'advisory-board', target: 'escalations', label: 'Eskalation' }, { source: 'advisory-board', target: 'dsfa', label: 'Risiko' }, { source: 'ai-act', target: 'screening' }, { source: 'screening', target: 'advisory-board' }, { source: 'source-policy', target: 'rag' }, { source: 'rag', target: 'quality' }, // === DOKUMENTE FLOW === { source: 'document-generator', target: 'notfallplan' }, { source: 'document-generator', target: 'audit-report' }, { source: 'security-backlog', target: 'tom' }, { source: 'company-profile', target: 'document-generator' }, // === VENDOR FLOW === { source: 'vendor-compliance', target: 'vendor-vendors' }, { source: 'vendor-compliance', target: 'vendor-contracts' }, { source: 'vendor-compliance', target: 'vendor-controls' }, { source: 'vendor-compliance', target: 'vendor-risks' }, { source: 'vendor-compliance', target: 'vendor-processing' }, { source: 'vendor-compliance', target: 'vendor-reports' }, { source: 'vendor-vendors', target: 'vendor-contracts' }, { source: 'vendor-risks', target: 'risks' }, { source: 'dsms', target: 'compliance-hub' }, { source: 'import', target: 'catalog-manager' }, // === ENTWICKLUNG FLOW === { source: 'dev-brandbook', target: 'dev-screen-flow' }, { source: 'dev-docs', target: 'dev-brandbook' }, ] // ============================================ // CATEGORY COLORS & LABELS // ============================================ const COLORS: Record = { dashboard: { bg: '#dbeafe', border: '#3b82f6', text: '#1e40af' }, dsgvo: { bg: '#ede9fe', border: '#7c3aed', text: '#5b21b6' }, compliance: { bg: '#f3e8ff', border: '#9333ea', text: '#6b21a8' }, ai: { bg: '#ccfbf1', border: '#14b8a6', text: '#0f766e' }, documents: { bg: '#ffedd5', border: '#f97316', text: '#c2410c' }, vendor: { bg: '#dcfce7', border: '#22c55e', text: '#166534' }, development: { bg: '#f1f5f9', border: '#64748b', text: '#334155' }, } const LABELS: Record = { dashboard: 'Dashboard & Verwaltung', dsgvo: 'DSGVO-Grundlagen', compliance: 'Compliance-Management', ai: 'KI & Automatisierung', documents: 'Dokumente & Legal', vendor: 'Vendor & Extern', development: 'Entwicklung', } // ============================================ // HELPER: Find all connected nodes // ============================================ function findConnectedNodes( startNodeId: string, connections: ConnectionDef[], direction: 'children' | 'parents' | 'both' = 'children' ): Set { const connected = new Set() connected.add(startNodeId) const queue = [startNodeId] while (queue.length > 0) { const current = queue.shift()! connections.forEach(conn => { if ((direction === 'children' || direction === 'both') && conn.source === current) { if (!connected.has(conn.target)) { connected.add(conn.target) queue.push(conn.target) } } if ((direction === 'parents' || direction === 'both') && conn.target === current) { if (!connected.has(conn.source)) { connected.add(conn.source) queue.push(conn.source) } } }) } return connected } // ============================================ // LAYOUT HELPERS // ============================================ const CATEGORY_POSITIONS: Record = { dashboard: { x: 400, y: 30 }, dsgvo: { x: 50, y: 150 }, compliance: { x: 700, y: 150 }, ai: { x: 50, y: 380 }, documents: { x: 400, y: 380 }, vendor: { x: 700, y: 380 }, development: { x: 400, y: 580 }, } const getNodePosition = (id: string, category: string) => { const base = CATEGORY_POSITIONS[category] || { x: 400, y: 300 } const categoryScreens = SCREENS.filter(s => s.category === category) const categoryIndex = categoryScreens.findIndex(s => s.id === id) const cols = Math.ceil(Math.sqrt(categoryScreens.length + 1)) const row = Math.floor(categoryIndex / cols) const col = categoryIndex % cols return { x: base.x + col * 160, y: base.y + row * 90, } } // ============================================ // MAIN COMPONENT // ============================================ export default function ScreenFlowPage() { const [selectedCategory, setSelectedCategory] = useState(null) const [selectedNode, setSelectedNode] = useState(null) const [previewScreen, setPreviewScreen] = useState(null) const baseUrl = 'https://macmini:3007' // Calculate connected nodes const connectedNodes = useMemo(() => { if (!selectedNode) return new Set() return findConnectedNodes(selectedNode, CONNECTIONS, 'children') }, [selectedNode]) // Create nodes with useMemo const initialNodes = useMemo((): Node[] => { return SCREENS.map((screen) => { const catColors = COLORS[screen.category] || { bg: '#f1f5f9', border: '#94a3b8', text: '#475569' } const position = getNodePosition(screen.id, screen.category) let opacity = 1 if (selectedNode) { opacity = connectedNodes.has(screen.id) ? 1 : 0.2 } else if (selectedCategory) { opacity = screen.category === selectedCategory ? 1 : 0.2 } const isSelected = selectedNode === screen.id return { id: screen.id, type: 'default', position, data: { label: (
{screen.icon}
{screen.name}
), }, style: { background: isSelected ? catColors.border : catColors.bg, color: isSelected ? 'white' : catColors.text, border: `2px solid ${catColors.border}`, borderRadius: '12px', padding: '6px', minWidth: '110px', opacity, cursor: 'pointer', boxShadow: isSelected ? `0 0 20px ${catColors.border}` : 'none', }, } }) }, [selectedCategory, selectedNode, connectedNodes]) // Create edges with useMemo const initialEdges = useMemo((): Edge[] => { return CONNECTIONS.map((conn, index) => { const isHighlighted = selectedNode && (conn.source === selectedNode || conn.target === selectedNode) const isInSubtree = selectedNode && connectedNodes.has(conn.source) && connectedNodes.has(conn.target) return { id: `e-${conn.source}-${conn.target}-${index}`, source: conn.source, target: conn.target, label: conn.label, type: 'smoothstep', animated: isHighlighted || false, style: { stroke: isHighlighted ? '#3b82f6' : (isInSubtree ? '#94a3b8' : '#e2e8f0'), strokeWidth: isHighlighted ? 3 : 1.5, opacity: selectedNode ? (isInSubtree ? 1 : 0.15) : 1, }, labelStyle: { fontSize: 9, fill: '#64748b' }, labelBgStyle: { fill: '#f8fafc' }, markerEnd: { type: MarkerType.ArrowClosed, color: isHighlighted ? '#3b82f6' : '#94a3b8', width: 15, height: 15 }, } }) }, [selectedNode, connectedNodes]) const [nodes, setNodes, onNodesChange] = useNodesState([]) const [edges, setEdges, onEdgesChange] = useEdgesState([]) // Update nodes/edges when dependencies change useEffect(() => { setNodes(initialNodes) setEdges(initialEdges) }, [initialNodes, initialEdges, setNodes, setEdges]) // Handle node click const onNodeClick = useCallback((_event: React.MouseEvent, node: Node) => { const screen = SCREENS.find(s => s.id === node.id) if (selectedNode === node.id) { if (screen?.url) { window.open(`${baseUrl}${screen.url}`, '_blank') } return } setSelectedNode(node.id) setSelectedCategory(null) if (screen) { setPreviewScreen(screen) } }, [selectedNode, baseUrl]) // Handle background click - deselect const onPaneClick = useCallback(() => { setSelectedNode(null) setPreviewScreen(null) }, []) // Stats const stats = { totalScreens: SCREENS.length, totalConnections: CONNECTIONS.length, connectedCount: connectedNodes.size, } const categories = Object.keys(LABELS) // Connected screens list const connectedScreens = selectedNode ? SCREENS.filter(s => connectedNodes.has(s.id)) : [] return (
{/* Header */}
🔀

Compliance SDK Screen Flow

{stats.totalScreens} Screens mit {stats.totalConnections} Verbindungen

{/* Stats */}
{stats.totalScreens}
Screens
{stats.totalConnections}
Verbindungen
{selectedNode ? (
{previewScreen?.icon}
{previewScreen?.name}
{stats.connectedCount} verbundene Screen{stats.connectedCount !== 1 ? 's' : ''}
) : (
Klicke auf einen Screen um den Subtree zu sehen
)}
{/* Category Filter */}
{categories.map((key) => { const count = SCREENS.filter(s => s.category === key).length const catColors = COLORS[key] || { bg: '#f1f5f9', border: '#94a3b8', text: '#475569' } return ( ) })}
{/* Connected Screens List */} {selectedNode && connectedScreens.length > 1 && (
Verbundene Screens:
{connectedScreens.map((screen) => { const catColors = COLORS[screen.category] || { bg: '#f1f5f9', border: '#94a3b8', text: '#475569' } const isCurrentNode = screen.id === selectedNode return ( ) })}
)} {/* Flow Diagram */}
{ const screen = SCREENS.find(s => s.id === node.id) const catColors = screen ? COLORS[screen.category] : null return catColors?.border || '#94a3b8' }} maskColor="rgba(0, 0, 0, 0.1)" />
🛡️ Compliance SDK
{categories.slice(0, 5).map((key) => { const catColors = COLORS[key] || { bg: '#f1f5f9', border: '#94a3b8' } return (
{LABELS[key]}
) })}
Klick = Subtree
Doppelklick = Oeffnen
{/* Screen List */}

Alle Screens ({SCREENS.length})

{baseUrl}
{SCREENS .filter(s => !selectedCategory || s.category === selectedCategory) .map((screen) => { const catColors = COLORS[screen.category] || { bg: '#f1f5f9', border: '#94a3b8', text: '#475569' } return ( ) })}
) }