"use client"; import { useEffect, useState } from "react"; import { reviewDuplicateClusterAction, type DuplicateClusterDecision, type ReviewDuplicateClusterResult, } from "../actions"; import type { DuplicateClusterOverride } from "yt-dlp-transcript-common/lib/duplicates"; type Status = | { kind: "idle" } | { kind: "running"; decision: DuplicateClusterDecision } | { kind: "done"; result: ReviewDuplicateClusterResult } | { kind: "error"; message: string }; // NOTE ON THE aria-labels BELOW: none of them may contain the substring // "duplicate cluster ". That is the CARD's own label, and Playwright's // getByLabel matches by SUBSTRING, so a button labelled "confirm duplicate // cluster " makes the card's own locator resolve to three elements and // every existing assertion on it dies with a strict-mode violation. That is // exactly what happened here, and this repo has now hit the same collision // three times (deploy-page's "Build & deploy" vs "Build & deploy all sites", // the settings placeholder collision, and this). export function DuplicateClusterReview({ clusterId, override, }: { clusterId: string; override: DuplicateClusterOverride | undefined; }) { const [status, setStatus] = useState({ kind: "idle" }); // Disabled until mounted, deliberately. A server-rendered button has no // handler until React hydrates, so a click before then fires NOTHING — no // request, no error, nothing to debug. That is the exact failure that made // the digest pilot's job look "un-created", and /review renders a page // heavy enough to hit the same window. See StreamActionLog. const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); async function decide(decision: DuplicateClusterDecision) { setStatus({ kind: "running", decision }); try { setStatus({ kind: "done", result: await reviewDuplicateClusterAction(clusterId, decision), }); } catch (e) { setStatus({ kind: "error", message: (e as Error).message }); } } const busy = status.kind === "running"; const disabled = busy || !mounted; const confirmed = override?.confirmed === true; const rejected = override?.notDuplicate === true; return (
{(confirmed || rejected) && ( )} {status.kind === "done" && status.result.ok && ( {status.result.shared > 0 || status.result.misaligned > 0 ? `${status.result.shared} digest(s) shared` + (status.result.misaligned > 0 ? `, ${status.result.misaligned} misaligned` : "") : "Saved."} )} {status.kind === "done" && !status.result.ok && ( {status.result.error} )} {status.kind === "error" && ( {status.message} )}
); }