"use client"; import Link from "next/link"; import { useState } from "react"; import type { Evidence } from "@/lib/articles/evidence"; // "Add to video": the cited span as a new clip at the END of a linked // report-video project's timeline, through the structure route // (/api/report/timeline, op insert). That route snapshots the manifest first // (Undo on the project page restores it) and, on a GENERATED manifest, leaves // an `edit` note so the agent ports the clip into the generator's inputs. export type VideoProjectLink = { id: string; title: string; generatedBy: string | null }; export default function AddToVideo({ ev, projects }: { ev: Evidence; projects: VideoProjectLink[] }) { const [project, setProject] = useState(projects[0]?.id ?? ""); const [state, setState] = useState<{ busy: boolean; done?: { id: string; project: string }; error?: string }>({ busy: false }); if (!projects.length || !ev.record || ev.start === undefined || ev.end === undefined) return null; const chosen = projects.find((p) => p.id === project) ?? projects[0]; const add = async () => { setState({ busy: true }); try { const g = await fetch(`/api/report/timeline?project=${encodeURIComponent(chosen.id)}`, { cache: "no-store" }); const gj = await g.json(); if (!g.ok) throw new Error(gj.error ?? g.statusText); const last = gj.timeline.length ? gj.timeline[gj.timeline.length - 1] : null; const entry: Record = { type: "clip", channel: ev.record!.channel, video: ev.record!.id, start: ev.start, end: ev.end, quote: ev.quote, }; if (/^[A-Za-z0-9_-]{1,60}$/.test(ev.cite)) entry.id = `cite-${ev.cite}`; const r = await fetch("/api/report/timeline", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ project: chosen.id, token: gj.token, op: "insert", afterId: last?.id ?? null, at: last ? gj.timeline.length - 1 : null, entry }), }); const j = await r.json(); if (!r.ok) throw new Error(j.error ?? r.statusText); setState({ busy: false, done: { id: j.id ?? j.result?.id ?? "the clip", project: chosen.id } }); } catch (err) { setState({ busy: false, error: err instanceof Error ? err.message : String(err) }); } }; return (
{projects.length > 1 ? ( ) : ( {chosen.id} )} {chosen.generatedBy && generated; leaves an edit note} {state.done && ( added {state.done.id} —{" "} open )} {state.error && {state.error}}
); }