'use client' import { Incident, Deadline, downloadStageExport } from '../_hooks/useMeldewesen' const STATUS_STYLE: Record = { submitted: 'bg-green-100 text-green-800 border-green-300', overdue: 'bg-red-100 text-red-800 border-red-300', due_soon: 'bg-amber-100 text-amber-800 border-amber-300', pending: 'bg-gray-100 text-gray-700 border-gray-300', } const STATUS_LABEL: Record = { submitted: 'gemeldet', overdue: 'überfällig', due_soon: 'bald fällig', pending: 'offen', } const SEV_STYLE: Record = { critical: 'bg-red-600', high: 'bg-orange-500', medium: 'bg-amber-500', low: 'bg-gray-400', } function remaining(sec: number | null): string { if (sec === null) return '' const past = sec < 0 const a = Math.abs(sec) const h = Math.floor(a / 3600) const txt = h >= 48 ? `${Math.floor(h / 24)} Tage` : `${h} h` return past ? `seit ${txt} überfällig` : `noch ${txt}` } function fmt(iso: string | null): string { if (!iso) return '—' try { return new Date(iso).toLocaleString('de-DE', { dateStyle: 'medium', timeStyle: 'short' }) } catch { return iso } } function StageRow({ d, incidentId, summary, onSubmit }: { d: Deadline; incidentId: string; summary: string; onSubmit: (stage: string) => void }) { return (
{STATUS_LABEL[d.status]} {d.label} {d.article} Frist: {fmt(d.due_at)}{d.status !== 'submitted' && d.remaining_seconds !== null ? ` · ${remaining(d.remaining_seconds)}` : ''} {d.status === 'submitted' ? ` · übermittelt ${fmt(d.submitted_at)}` : ''}
{d.status !== 'submitted' && ( )}
) } export function IncidentCard({ inc, onSubmit }: { inc: Incident; onSubmit: (id: string, stage: string) => void }) { return (

{inc.summary || 'Vorfall'}

{inc.product_name} {inc.product_version} · {inc.kind === 'exploited_vulnerability' ? 'ausgenutzte Schwachstelle' : 'schwerer Vorfall'} · bekannt seit {fmt(inc.aware_at || null)}

Status: {inc.status}
{inc.deadlines.map((d) => ( onSubmit(inc.id, stage)} /> ))}

Übermittlung an die ENISA Single Reporting Platform erfolgt manuell mit dem Entwurf — keine automatische Übertragung.

) }