"use client"; import Link from "next/link"; import { ExternalLink } from "lucide-react"; import { fmtDuration, fmtNum, truncate } from "@/lib/format"; import { SurfaceChips, Table, TypeTag } from "./ui"; export interface EntityRow { fingerprint: string; entity_type?: string; type?: string; platform: string; platform_id?: string | null; url?: string | null; name?: string | null; text_excerpt?: string | null; text?: string | null; author?: string | null; metrics?: Record | null; media?: { has_video?: boolean; duration_s?: number; thumbnail_url?: string } | null; fields?: Record | null; provenance?: { surface: string; confidence: number; detail?: string }[] | null; confidence?: number | null; seen_count?: number; last_seen?: string; last_step?: number; } export function provenanceOf(e: EntityRow) { if (e.provenance?.length) return e.provenance; if (e.fields) return Object.values(e.fields).flatMap((f) => f.provenance ?? []); return []; } export function EntityTable({ rows, showPlatform = false, dense = true }: { rows: EntityRow[]; showPlatform?: boolean; dense?: boolean }) { return ( {rows.map((e) => { const prov = provenanceOf(e); const conf = e.confidence ?? Math.max(0, ...prov.map((p) => p.confidence)); const type = e.entity_type ?? e.type ?? "?"; return ( ); })}
{showPlatform &&
{e.platform}
}
{truncate(e.name ?? e.text ?? e.text_excerpt ?? e.platform_id ?? e.fingerprint, 90)} {e.media?.has_video && e.media.duration_s ? {fmtDuration(e.media.duration_s)} : null}
{e.platform_id}
{truncate(e.author ?? "", 28)} {e.metrics && Object.keys(e.metrics).length ? Object.entries(e.metrics) .map(([k, v]) => `${fmtNum(v)} ${k}`) .join(" · ") : "—"} {conf ? conf.toFixed(2) : "—"} {e.url && ( )}
); }