import { useState } from "react"; import { disableSiteHosting, saveSiteAccess, saveSiteSettings } from "~/fns/sites"; import type { getSite } from "~/fns/sites"; import { useAction } from "~/hooks/use-action"; import { Badge } from "~/ui/Badge"; import { Panel } from "~/ui/Panel"; import { Button } from "~/ui/Button"; import { CheckboxField, SelectField, TextField } from "~/ui/Field"; import { ErrorBanner } from "~/ui/Callout"; export type SiteData = Awaited>; export type RepoParams = { owner: string; repo: string }; type Access = "public" | "password" | "gitfor" | "oidc"; const SOURCES = [ { value: "branch", label: "Deploy from a branch" }, { value: "workflow", label: "Deploy from a workflow artifact" }, ] as const; const ACCESS_OPTIONS = [ { value: "public", label: "Public" }, { value: "password", label: "Password" }, { value: "gitfor", label: "Sign in with this forge" }, { value: "oidc", label: "External OpenID Connect provider" }, ] as const; const AUDIENCES = [ { value: "readers", label: "Anyone who can read the repository" }, { value: "members", label: "Organization members and collaborators with write access" }, ] as const; function text(form: FormData, key: string): string { return String(form.get(key) ?? "").trim(); } export function SiteSourceForm({ data, params }: { data: SiteData; params: RepoParams }) { const save = useAction(saveSiteSettings); const disable = useAction(disableSiteHosting); const [source, setSource] = useState<"branch" | "workflow">(data.site?.source ?? "branch"); const branchOptions = (data.branches.length ? data.branches : [data.defaultBranch]).map((name) => ({ value: name, label: name, })); return ( Enabled}>
{ event.preventDefault(); const form = new FormData(event.currentTarget); await save.run({ data: { ...params, source, branch: text(form, "branch") || data.defaultBranch, folder: text(form, "folder"), artifactName: text(form, "artifactName") || "site", spa: form.get("spa") === "on", previews: form.get("previews") === "on", previewEnv: form.get("previewEnv") === "on", commitPreviews: form.get("commitPreviews") === "on", }, }); }} > setSource(value === "workflow" ? "workflow" : "branch")} /> {source === "workflow" && ( )}
{data.site && ( )}
); } export function SiteAccessForm({ data, params }: { data: SiteData; params: RepoParams }) { const save = useAction(saveSiteAccess); const site = data.site; const [access, setAccess] = useState(site?.access ?? "public"); if (!site) return null; return (
{ event.preventDefault(); const form = new FormData(event.currentTarget); await save.run({ data: { ...params, access, audience: text(form, "audience") === "members" ? "members" : "readers", password: text(form, "password") || null, oidc: access === "oidc" ? { issuer: text(form, "issuer"), clientId: text(form, "clientId"), clientSecret: text(form, "clientSecret") || null, allowed: text(form, "allowed"), } : null, }, }); }} > setAccess(value as Access)} hint="Checked before your site's code runs. Changing it signs every visitor out." /> {access === "password" && ( )} {access === "gitfor" && ( )} {access === "oidc" && ( <> "}__gitfor/callback`} /> )}
); }