'use client' import { useEffect, useState } from 'react' interface HistoryEntry { cid: string version: string | null document_type: string | null document_id: string | null parent_cid: string | null created_at: string | null checksum: string | null } interface DiffResponse { kind: 'text' | 'binary' cid_a: string cid_b: string metadata_diff: Record diff?: string added_lines?: number removed_lines?: number note?: string } interface Props { cid: string onClose: () => void } function shorten(cid: string): string { if (cid.length <= 14) return cid return cid.slice(0, 8) + '…' + cid.slice(-6) } export default function CIDHistoryModal({ cid, onClose }: Props) { const [history, setHistory] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [diffPair, setDiffPair] = useState<{ a: string; b: string } | null>(null) const [diff, setDiff] = useState(null) const [diffLoading, setDiffLoading] = useState(false) useEffect(() => { let cancel = false setLoading(true) setError(null) fetch(`/api/sdk/v1/dsms/documents/${encodeURIComponent(cid)}/history`) .then(async (r) => { if (!r.ok) throw new Error(`HTTP ${r.status}`) const json = await r.json() if (!cancel) setHistory(json.history || []) }) .catch((e) => { if (!cancel) setError(e?.message || 'Fehler beim Laden') }) .finally(() => { if (!cancel) setLoading(false) }) return () => { cancel = true } }, [cid]) async function loadDiff(a: string, b: string) { setDiffPair({ a, b }) setDiff(null) setDiffLoading(true) try { const res = await fetch( `/api/sdk/v1/dsms/documents/${encodeURIComponent(a)}/diff/${encodeURIComponent(b)}` ) if (res.ok) { const json = (await res.json()) as DiffResponse setDiff(json) } else { setDiff({ kind: 'binary', cid_a: a, cid_b: b, metadata_diff: {}, note: `HTTP ${res.status}` }) } } finally { setDiffLoading(false) } } return (
e.stopPropagation()} >

DSMS-Versionsverlauf

{shorten(cid)}
{loading &&
Verlauf wird geladen…
} {error &&
{error}
} {!loading && !error && history.length === 0 && (
Kein Versionsverlauf gefunden. Diese CID hat keine parent_cid-Kette.
)} {!loading && !error && history.length > 0 && ( <>
{history.length} Version{history.length > 1 ? 'en' : ''} in der Kette (neueste oben).
    {history.map((entry, idx) => { const next = history[idx + 1] return (
  1. Version {entry.version || '?'} {idx === 0 && AKTUELL}
    {entry.cid}
    {next && ( )}
    {entry.document_type && Typ: {entry.document_type}} {entry.document_id && Dok-ID: {entry.document_id}} {entry.created_at && {new Date(entry.created_at).toLocaleString('de-DE')}}
    {entry.checksum && (
    SHA-256: {entry.checksum.slice(0, 16)}…
    )}
  2. ) })}
)} {diffPair && (

Diff: {shorten(diffPair.a)} → {shorten(diffPair.b)}

{diffLoading &&
Diff wird geladen…
} {!diffLoading && diff && ( <> {Object.keys(diff.metadata_diff || {}).length > 0 && (
Metadaten-Aenderungen
{Object.entries(diff.metadata_diff).map(([field, { old, new: nv }]) => ( ))}
{field} {JSON.stringify(old)} {JSON.stringify(nv)}
)} {diff.kind === 'text' && diff.diff && ( <>
{diff.added_lines ?? 0} Zeilen hinzu, {diff.removed_lines ?? 0} entfernt
                        {diff.diff}
                      
)} {diff.kind === 'binary' && (
{diff.note || 'Binaere Datei — kein Text-Diff verfuegbar.'}
)} )}
)}
) }