"use client"; import { useActionState, useState } from "react"; import Link from "next/link"; import { saveSettingsAction, type SaveResult, } from "../actions"; import type { SiteSettings } from "yt-dlp-transcript-common/lib/settings"; import { DOWNLOAD_FORMAT_LABELS, DOWNLOAD_FORMAT_PRESETS, SOURCE_VIDEO_QUALITIES, SOURCE_VIDEO_QUALITY_LABELS, } from "yt-dlp-transcript-common/ytdlp/downloadFormat"; import { Field, SeededInput, SeededSelect, } from "../../components/forms/Field"; import { seedChecked } from "../../lib/formState"; import { SocialLinksField, toSocialRow, type SocialRow, } from "../../components/SocialLinksField"; type Props = { initial: SiteSettings; }; export function SettingsForm({ initial }: Props) { const [state, formAction] = useActionState( saveSettingsAction, undefined, ); const [social, setSocial] = useState(() => initial.socialLinks.map(toSocialRow), ); return (
{/* THE COLD ROOT USED TO BE A TEXT BOX HERE. It is now a list of named locations with an id, a label, a root, an opt-in auto re-point and a volume identity — more than a settings field can hold, and edited on its own page. The link points at a route that does not exist yet: /storage is the next slice. That is deliberate rather than an oversight — the field's REPLACEMENT lands with the field's removal, so this form never carries an input whose value nothing reads. */}
Media locations The places a channel's media can live — the cold drive and anything beside it — are named, checked and re-pointed on{" "} Storage . Each channel's own Storage panel still runs the move.
Build pipeline

A single site builds in export/, one at a time on one queue. Build all sites builds every site at once, each in its own container (capped by Max parallel builds), then deploys them one by one, whenever a container engine answers, and serially on the host when none does. See PUBLISH.md.

Social links

Default social links shown in every site's footer. Each site can override these from its own page (Sites → a site → Social links).

{state?.ok === true && ( Saved. )} {state && state.ok === false && ( {state.error} )}
); }