import Link from "next/link"; import { Card, CardContent, CardHeader, CardTitle, } from "yt-dlp-transcript-common/components/ui/card"; import { Separator } from "yt-dlp-transcript-common/components/ui/separator"; import type { StageId, StageStatus } from "yt-dlp-transcript-common/views/pipeline/stageStatus"; // THE LANDING PANEL. // // One panel is open at a time, and this is the one that is open when no stage is // selected. It is not a summary written by hand: every row is a straight render // of the `StageStatus` that computeStageStatuses already returns, so a stage's // summary line is legible here without opening anything and there is no second // copy of the wording to drift. const TONE_DOT: Record = { neutral: "bg-transparent border border-border-strong", ok: "bg-success", attention: "bg-warning", danger: "bg-destructive", running: "bg-info animate-pulse", }; export type ChannelEssentials = { handling: string; platform?: string; url?: string; cookieMode?: string; keepLatest?: number; }; export function OverviewPanel({ slug, stageOrder, stages, essentials, generatedAt, lastSyncedAt, }: { slug: string; stageOrder: StageId[]; stages: Record; essentials: ChannelEssentials; generatedAt: string; lastSyncedAt?: string; }) { return ( Every stage at a glance
    {stageOrder.map((id) => { const s = stages[id]; return (
  • ); })}

Channel

Edit
0 ? `${essentials.keepLatest}` : "off" } />

{generatedAt ? ( <> Report generated{" "} . ) : ( "No report has been generated for this channel yet." )}{" "} {lastSyncedAt ? `Last synced ${formatTimestamp(lastSyncedAt)}.` : "Never synced."}

); } function Field({ label, value, mono, }: { label: string; value: string; mono?: boolean; }) { return ( <>
{label}
{value}
); } function formatTimestamp(iso: string): string { try { return new Date(iso).toLocaleString(); } catch { return iso; } }