'use client' /** * Strukturierte Finding-Anzeige. * Layout: * [Severity-Badge] [Methodik-Badge(s)] * [Titel] * ┌ Gesetzliche Basis / Norm ─────────┐ * │ § 5 Abs. 1 Nr. 1 TMG │ * └────────────────────────────────────┘ * ┌ Befund / Wörtlich ───────────────┐ * │ "Vorstand: …" │ * └────────────────────────────────────┘ * ┌ Empfehlung / Best Practice ──────┐ * │ → Konkrete Maßnahme │ * └────────────────────────────────────┘ */ import React from 'react' import type { Finding, SourceType } from './_agentTypes' import { METHODIK_COLOR, METHODIK_LABEL, METHODIK_SHORT, SEVERITY_BG, SEVERITY_COLOR, } from './_agentTypes' export function AgentFindingCard({ f }: { f: Finding }) { const sev = f.severity const color = SEVERITY_COLOR[sev] const bg = SEVERITY_BG[sev] const sources = f.sources || [] return (
{sev} {f.check_id} {sources.map((s, i) => ( ))} {f.confidence !== undefined && ( Konfidenz {(f.confidence * 100).toFixed(0)}% )}
{f.title}
{f.norm && ( {f.norm} )} {f.evidence && ( „{f.evidence}" )} {f.action && ( s.source_type === 'llm_local' || s.source_type === 'llm_local_big' || s.source_type === 'llm_cloud' ) ? 'Empfehlung (LLM-Vorschlag)' : sev === 'HIGH' ? 'Pflicht-Maßnahme' : 'Best-Practice-Empfehlung' } tone="green" > {f.action} )}
) } function MethodikBadge({ src, sourceId, }: { src: SourceType; sourceId?: string }) { const { bg, fg } = METHODIK_COLOR[src] || { bg: '#e5e7eb', fg: '#374151' } const title = `${METHODIK_LABEL[src]}${sourceId ? ` · ${sourceId}` : ''}` return ( {METHODIK_SHORT[src]} ) } function Block({ label, tone, children, }: { label: string tone: 'purple' | 'amber' | 'green' children: React.ReactNode }) { const toneMap = { purple: { border: '#a78bfa', bg: '#f5f3ff', label: '#5b21b6' }, amber: { border: '#fbbf24', bg: '#fffbeb', label: '#92400e' }, green: { border: '#34d399', bg: '#ecfdf5', label: '#065f46' }, } as const const t = toneMap[tone] return (
{label}
{children}
) }