import { useI18n } from "@/i18n/I18nProvider";
import type { TKey } from "@/i18n/dict";
import type { Severity, WorkerEvent } from "@/types";
import { formatDistanceToNow } from "date-fns";
import { Check, Undo2 } from "lucide-react";
const SEV_COLOR: Record<Severity, string> = {
info: "text-muted-foreground",
suggest: "text-cyan-600",
warn: "text-yellow-600",
block: "text-red-600",
};
type EventRowProps = {
event: WorkerEvent;
onAck?: (event: WorkerEvent) => void;
onUnack?: (event: WorkerEvent) => void;
};
export function EventRow({ event, onAck, onUnack }: EventRowProps) {
const { t } = useI18n();
const ts = formatDistanceToNow(new Date(event.created_at), { addSuffix: true });
const text = extractText(event);
const acked = !!event.acked_at;
const showAck = !!onAck && !acked;
const showUnack = !!onUnack && acked;
// Translate severity + event_type with safe fallback to raw value if no key.
const sevKey = `severity.${event.severity}` as TKey;
const evKey = `event.${event.event_type}` as TKey;
return (
<div
className={`border-b py-2 px-3 text-sm flex items-start gap-3 hover:bg-muted/40 ${
acked ? "opacity-60" : ""
}`}
>
<span
className={`text-[10px] uppercase font-semibold w-14 mt-0.5 ${
SEV_COLOR[event.severity] ?? "text-muted-foreground"
}`}
>
{t(sevKey)}
</span>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<span className={`font-medium ${acked ? "line-through" : ""}`}>
{t(evKey)}
</span>
{event.path && (
<span className="text-muted-foreground font-mono text-xs truncate">
{event.path}
</span>
)}
{acked && (
<span className="text-[10px] uppercase text-green-600 border border-green-300 rounded px-1">
{t("event.acked")}
</span>
)}
</div>
{text && <div className="text-muted-foreground mt-0.5">{text}</div>}
</div>
<div className="flex items-center gap-2 shrink-0">
<span className="text-xs text-muted-foreground whitespace-nowrap">{ts}</span>
{showAck && (
<button
type="button"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onAck?.(event);
}}
title={t("event.action.ack")}
className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground"
>
<Check size={14} />
</button>
)}
{showUnack && (
<button
type="button"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onUnack?.(event);
}}
title={t("event.action.unack")}
className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground"
>
<Undo2 size={14} />
</button>
)}
</div>
</div>
);
}
function extractText(ev: WorkerEvent): string | null {
const p = ev.payload as Record<string, unknown>;
if (typeof p?.text === "string") return p.text;
if (typeof p?.error === "string") return `error: ${p.error}`;
return null;
}