import { useState } from 'react' import { AlertCircle, AlertTriangle, ChevronDown, ChevronRight, X } from 'lucide-react' /** * ValidationPanel - Zeigt Fehler und Warnungen mit Details * * Features: * - Aufklappbar (collapsible) * - Click-to-Jump zu betroffener Node * - Gruppierung nach Severity * - Klare visuelle Trennung */ export function ValidationPanel({ errors, warnings, onNodeClick, onClose }) { const [isExpanded, setIsExpanded] = useState(true) const [showErrors, setShowErrors] = useState(true) const [showWarnings, setShowWarnings] = useState(true) const totalCount = errors.length + warnings.length if (totalCount === 0) return null const handleItemClick = (item) => { if (item.nodeId && onNodeClick) { onNodeClick(item.nodeId) } } return (
{/* Header */}
setIsExpanded(!isExpanded)} style={{ padding: '12px 16px', borderBottom: isExpanded ? '1px solid var(--border)' : 'none', display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'pointer', userSelect: 'none', background: errors.length > 0 ? 'rgba(216, 90, 48, 0.1)' : 'rgba(255, 193, 7, 0.1)' }} >
{isExpanded ? : } 0 ? 'var(--danger)' : '#f59e0b'} /> Validierung {errors.length > 0 && `${errors.length} Fehler`} {errors.length > 0 && warnings.length > 0 && ', '} {warnings.length > 0 && `${warnings.length} Warnung${warnings.length > 1 ? 'en' : ''}`}
{/* Content */} {isExpanded && (
{/* Errors */} {errors.length > 0 && (
setShowErrors(!showErrors)} style={{ padding: '8px 16px', background: 'rgba(216, 90, 48, 0.05)', display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', userSelect: 'none', borderBottom: '1px solid var(--border)' }} > {showErrors ? : } Fehler ({errors.length})
{showErrors && (
{errors.map((error, idx) => (
handleItemClick(error)} style={{ padding: '10px 16px', borderBottom: idx < errors.length - 1 ? '1px solid var(--border)' : 'none', cursor: error.nodeId ? 'pointer' : 'default', background: error.nodeId ? 'transparent' : 'transparent', transition: 'background 0.15s', }} onMouseEnter={(e) => { if (error.nodeId) e.currentTarget.style.background = 'rgba(216, 90, 48, 0.05)' }} onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent' }} >
{error.message}
{error.nodeId && (
→ Klicken um zu Node zu springen
)} {error.type && (
{error.type}
)}
))}
)}
)} {/* Warnings */} {warnings.length > 0 && (
setShowWarnings(!showWarnings)} style={{ padding: '8px 16px', background: 'rgba(255, 193, 7, 0.05)', display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', userSelect: 'none', borderBottom: '1px solid var(--border)' }} > {showWarnings ? : } Warnungen ({warnings.length})
{showWarnings && (
{warnings.map((warning, idx) => (
handleItemClick(warning)} style={{ padding: '10px 16px', borderBottom: idx < warnings.length - 1 ? '1px solid var(--border)' : 'none', cursor: warning.nodeId ? 'pointer' : 'default', background: 'transparent', transition: 'background 0.15s', }} onMouseEnter={(e) => { if (warning.nodeId) e.currentTarget.style.background = 'rgba(255, 193, 7, 0.05)' }} onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent' }} >
{warning.message}
{warning.nodeId && (
→ Klicken um zu Node zu springen
)} {warning.type && (
{warning.type}
)}
))}
)}
)}
)}
) }