"use client"; import { useState } from "react"; import { StreamActionLog } from "yt-dlp-transcript-common/components/StreamActionLog"; import { MAX_PREVIEW_BRANCH, previewAliasUrl, previewBranchProblem, } from "yt-dlp-transcript-common/lib/pagesDeploy"; import { cancelPublishRunAction, deployTargetAction } from "../lib/publishActions"; type Props = { // The site whose Publish tab this is — always a real site. siteId: string; siteTitle: string; // The Cloudflare Pages project, when the site has one. Needed to SHOW the // preview alias, which is a function of project + branch — so with no project // there is no preview to offer, and the control says that instead of linking // a hostname that cannot exist. cloudflareProject?: string | null; // settings.publish.previewBranch: the preview box starts on it. previewBranch?: string; }; const DEFAULT_PREVIEW_BRANCH = "preview"; // Two deploys of the site's built bundle (`export/.export-builds//out`): // to production, or to a Cloudflare Pages preview branch — each a deploy // stage on the publish queue, forced (a click always deploys). // // THE PRODUCTION BUTTON SAYS "PRODUCTION" NOW. With a preview control beside // it, a button labelled only "Deploy" is the one an operator clicks by reflex // when they meant the safe one; the extra word is the whole cost of not doing // that. export function DeployButton({ siteId, siteTitle, cloudflareProject, previewBranch }: Props) { return (
deployTargetAction(siteId, { where: "production" })} cancelAction={cancelPublishRunAction} buttonLabel="Deploy to production" runningLabel="Deploying…" label="Deploy export" extraControls={

Deploying {siteTitle} ({siteId}).

} />
); } function PreviewDeploy({ siteId, cloudflareProject, initialBranch, }: { siteId: string; cloudflareProject: string | null; initialBranch: string; }) { const [branch, setBranch] = useState(initialBranch); const [deployed, setDeployed] = useState(null); // The SAME function the action and the ops route refuse with, so the button // greys out on exactly the names the server would have rejected and the // sentence an operator reads here is the sentence they would have got back. const problem = previewBranchProblem(branch); // The alias is knowable the moment the name is valid — project + branch and // nothing else — so it is shown before the deploy rather than fished out of // the finished log afterwards. const alias = problem === null && cloudflareProject ? previewAliasUrl(cloudflareProject, branch) : null; return (

Deploy a preview

Publishes the same bundle to a Cloudflare Pages branch instead of production, so you can look at it first. The live site is untouched. Previews share the production archive bucket.

deployTargetAction(siteId, { where: "preview", preview: branch })} cancelAction={cancelPublishRunAction} buttonLabel="Deploy preview" runningLabel="Deploying preview…" label="Deploy preview" disabled={problem !== null} // `started` only says a job began — the link's wording is all that // changes, and a failed deploy leaves the PREVIOUS preview at the same // address, so the link is never a lie about what is there. onSettled={(started) => { if (started && alias) setDeployed(alias); }} extraControls={ } /> {problem ? (

{problem}

) : alias ? (

{deployed === alias ? "Deployed to " : "Will deploy to "} {alias}

) : (

Set a Cloudflare Pages project for this site to preview it.

)}
); }