'use client' interface GuidelineItem { req_id: string title: string annex_anchor: string measures: { id: string; name: string }[] source?: string } interface EvidenceItem { key: string; label: string } export interface ReadinessResult { in_scope: boolean classification: string rationale: string[] conformity_path_hint: string regulations: string[] guideline: { code: GuidelineItem[]; process: GuidelineItem[]; document: GuidelineItem[] } counts: { code: number; process: number; document: number } total_effort_days: number deadlines: { date: string; label: string }[] verdict?: { tier: string label: string in_scope: boolean market_pull: boolean cra_class: string cutoff: string reasons: string[] } maturity?: { pct: number; present: EvidenceItem[]; missing: EvidenceItem[]; total: number } digital_elements?: string[] producer_type?: string } const CLASS_LABEL: Record = { CRITICAL: 'Kritisch', IMPORTANT_II: 'Wichtig (Klasse II)', IMPORTANT_I: 'Wichtig (Klasse I)', STANDARD: 'Standard', NOT_IN_SCOPE: 'Nicht im CRA-Anwendungsbereich', } const BUCKETS: { key: 'code' | 'process' | 'document'; label: string; hint: string }[] = [ { key: 'code', label: 'Code / Technik', hint: 'im Produkt umzusetzen' }, { key: 'process', label: 'Prozesse', hint: 'organisatorisch zu etablieren' }, { key: 'document', label: 'Dokumentation', hint: 'nachzuweisen / beizulegen' }, ] // Neutral, Co-Pilot tone — no panic red. zwingend = attention (amber), ratsam = // advisory (blue), nicht betroffen = positive (emerald). const TIER_STYLE: Record = { zwingend: 'border-amber-300 bg-amber-50 dark:bg-amber-900/20 text-amber-900 dark:text-amber-200', ratsam: 'border-blue-300 bg-blue-50 dark:bg-blue-900/20 text-blue-900 dark:text-blue-200', nicht_betroffen: 'border-emerald-300 bg-emerald-50 dark:bg-emerald-900/20 text-emerald-900 dark:text-emerald-200', } export function ReadinessResultView({ result, onCreateProject }: { result: ReadinessResult; onCreateProject?: () => void }) { const v = result.verdict const m = result.maturity return (
{/* Neutrales Verdict — Rechtspflicht vs. Marktzwang */} {v && (
{v.label} {v.market_pull && ( Markt-Druck: Kunden fordern Nachweise )}
    {v.reasons.map((r, i) =>
  • • {r}
  • )}

Hinweis: Maßgeblich ist das Inverkehrbringen (ab {v.cutoff}), nicht der Entwicklungszeitpunkt. Das ist eine erste Einschätzung zur Klärung mit DSB/Anwalt — keine Rechtsberatung.

)} {/* Reifegrad + digitale Elemente */}
{m && (

Reifegrad (CRA-Nachweise)

{m.pct}%
{m.missing.length > 0 && (

Fehlende Nachweise:

    {m.missing.map((e) => (
  • • {e.label}
  • ))}
)}
)} {result.digital_elements && result.digital_elements.length > 0 && (

Gefundene digitale Elemente ({result.digital_elements.length})

{result.digital_elements.map((d) => ( {d} ))}
)}
{/* Einstufung + Pflichten-Übersicht (wie bisher) */} {result.in_scope && ( <>
CRA-Einstufung: {CLASS_LABEL[result.classification] || result.classification} · Konformität: {result.conformity_path_hint} {result.regulations.map((r) => ( {r} ))}

{result.counts.code + result.counts.process + result.counts.document} Pflichten · grobe Schätzung ~{result.total_effort_days} Personentage.

{BUCKETS.map((b) => (

{b.label} ({result.counts[b.key]} · {b.hint})

    {result.guideline[b.key].map((it) => (
  • {it.source === 'Maschinen-VO' && ( MaschVO )} {it.title} · {it.annex_anchor}
  • ))}
))}
CRA-Fristen: {result.deadlines.map((d) => ( {d.date} {d.label} ))}
)} {onCreateProject && ( )}
) }