'use client' import { useState, useEffect } from 'react' import { ArrowLeft, ChevronLeft, SkipForward, Scale, } from 'lucide-react' import { CanonicalControl, BACKEND_URL } from './helpers' import { ControlPanel } from './ReviewCompare' interface V1Match { matched_control_id: string matched_title: string matched_objective: string matched_severity: string matched_category: string matched_source: string | null matched_article: string | null matched_source_citation: Record | null similarity_score: number match_rank: number match_method: string } interface V1CompareViewProps { v1Control: CanonicalControl matches: V1Match[] onBack: () => void onNavigateToControl?: (controlId: string) => void } export function V1CompareView({ v1Control, matches, onBack, onNavigateToControl }: V1CompareViewProps) { const [currentMatchIndex, setCurrentMatchIndex] = useState(0) const [matchedControl, setMatchedControl] = useState(null) const [loading, setLoading] = useState(false) const currentMatch = matches[currentMatchIndex] // Load the full matched control when index changes useEffect(() => { if (!currentMatch) return const load = async () => { setLoading(true) try { const res = await fetch(`${BACKEND_URL}?endpoint=control&id=${encodeURIComponent(currentMatch.matched_control_id)}`) if (res.ok) { setMatchedControl(await res.json()) } else { setMatchedControl(null) } } catch { setMatchedControl(null) } finally { setLoading(false) } } load() }, [currentMatch]) return (
{/* Header */}
V1-Vergleich {currentMatch && ( = 0.85 ? 'bg-green-100 text-green-700' : currentMatch.similarity_score >= 0.80 ? 'bg-yellow-100 text-yellow-700' : 'bg-gray-100 text-gray-600' }`}> {(currentMatch.similarity_score * 100).toFixed(1)}% Aehnlichkeit )}
{/* Navigation */}
{currentMatchIndex + 1} / {matches.length}
{/* Navigate to matched control */} {onNavigateToControl && matchedControl && ( )}
{/* Source info bar */} {currentMatch && (currentMatch.matched_source || currentMatch.matched_article) && (
{currentMatch.matched_source && ( {currentMatch.matched_source} )} {currentMatch.matched_article && ( {currentMatch.matched_article} )}
)} {/* Side-by-Side Panels */}
{/* Left: V1 Eigenentwicklung */}
{/* Right: Regulatory match */}
{loading ? (
) : matchedControl ? ( ) : (
Control konnte nicht geladen werden
)}
) }