'use client' import { useState } from 'react' import { useAuditTimeline, type AuditEntry } from './_hooks/useAuditTimeline' import CIDHistoryModal from './_components/CIDHistoryModal' const ENTITY_LABELS: Record = { evidence: 'Nachweis', control: 'Control', document: 'Dokument', dsfa: 'DSFA', vvt: 'VVT', tom: 'TOM', policy: 'Richtlinie', dsms_archive: 'DSMS-Archiv', risk: 'Risiko', } const ACTION_COLORS: Record = { create: 'bg-green-500', update: 'bg-blue-500', delete: 'bg-red-500', approve: 'bg-purple-500', archive: 'bg-emerald-500', review: 'bg-yellow-500', sign: 'bg-indigo-500', reject: 'bg-red-400', } const FILTER_OPTIONS = ['all', 'evidence', 'dsms_archive', 'control', 'document', 'dsfa', 'vvt', 'tom'] // new_value may be a plain CID (from Python evidence flow) or a JSON envelope // {"cid":"X","filename":"...","size":"..."} (from the Go IACE tech-file flow). function extractCID(value: string): string { const trimmed = value.trim() if (trimmed.startsWith('{')) { try { const parsed = JSON.parse(trimmed) if (typeof parsed.cid === 'string') return parsed.cid } catch { // fall through } } return trimmed } export default function AuditTimelinePage() { const { entries, loading, filter, setFilter } = useAuditTimeline() const [historyCID, setHistoryCID] = useState(null) return (

Audit Timeline

Chronologische Compliance-Historie mit DSMS-Nachweisen

{/* Filter */}
{FILTER_OPTIONS.map((f) => ( ))}
{loading ? (
) : entries.length === 0 ? (
Keine Eintraege gefunden. Compliance-Aktionen werden automatisch protokolliert.
) : (
{/* Timeline line */}
{entries.map((entry) => ( ))}
)} {historyCID && setHistoryCID(null)} />}
) } function TimelineEntry({ entry, onShowHistory }: { entry: AuditEntry; onShowHistory: (cid: string) => void }) { const dotColor = ACTION_COLORS[entry.action] || 'bg-gray-400' const isCID = entry.field_changed === 'dsms_cid' || entry.action === 'archive' const date = new Date(entry.performed_at) return (
{/* Dot */}
{/* Content */}
{entry.entity_name} {ENTITY_LABELS[entry.entity_type] || entry.entity_type} {entry.action}
{entry.change_summary && (

{entry.change_summary}

)} {isCID && entry.new_value && (
{entry.new_value.length > 20 ? entry.new_value.slice(0, 8) + '...' + entry.new_value.slice(-6) : entry.new_value} DSMS/IPFS
)}
{date.toLocaleDateString('de-DE')}
{date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })}
{entry.performed_by}
) }