Self-hosted multi-platform broadcast newsroom for activist collectives: publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style column wall with hostile-content-safe rendering, live control room with Auto Director, bridged chat governance with polls and quorum, distributed sandboxed transcode workers, encrypted content-addressed archive, monthly analytics. MIT licensed. See README.md and docs/.
41 lines
1.5 KiB
TypeScript
41 lines
1.5 KiB
TypeScript
import { Button } from "../ui/primitives";
|
|
import { formatBytes } from "./format";
|
|
import type { VideoAssetDto } from "../../lib/video-types";
|
|
|
|
/** Confirm modal before DELETE /video/:id (media.manage-gated upstream). */
|
|
export function DeleteVideoModal({
|
|
asset,
|
|
busy,
|
|
onCancel,
|
|
onConfirm,
|
|
}: {
|
|
asset: VideoAssetDto;
|
|
busy: boolean;
|
|
onCancel: () => void;
|
|
onConfirm: () => void;
|
|
}): React.ReactElement {
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60" onClick={onCancel}>
|
|
<div
|
|
className="w-[440px] max-w-[90vw] rounded-lg border border-border bg-surface p-4 shadow-2xl"
|
|
onClick={(e: React.MouseEvent) => e.stopPropagation()}
|
|
>
|
|
<h2 className="text-sm font-semibold">Delete video</h2>
|
|
<p className="mt-2 text-xs leading-relaxed text-text-dim">
|
|
This removes the asset, its processing jobs, and its probe metadata from the workspace library.
|
|
Published posts that reference it are not deleted.
|
|
</p>
|
|
<p className="mt-3 truncate font-mono text-2xs text-text-faint" title={asset.storageKey}>
|
|
{asset.storageKey}
|
|
</p>
|
|
<p className="mt-1 text-2xs text-text-faint">{formatBytes(asset.sizeBytes)}</p>
|
|
<div className="mt-4 flex justify-end gap-2">
|
|
<Button variant="ghost" onClick={onCancel}>Cancel</Button>
|
|
<Button variant="danger" disabled={busy} onClick={onConfirm}>
|
|
{busy ? "Deleting…" : "Delete video"}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|