import { notFound } from "next/navigation"; import type { ProjectRef } from "@/lib/project-types"; import SongProject from "./SongProject"; import CutPage from "./CutPage"; import ReportProject from "./ReportProject"; import ClipBenchPage from "./ClipBenchPage"; import ClaimBenchPage from "./ClaimBenchPage"; import SweepProject from "./SweepProject"; import TakesPage from "./TakesPage"; // --------------------------------------------------------------------------- // The one place a kind id is matched against a component. // // It is HERE rather than in app/browse/[...path]/page.tsx deliberately: the // rule is that adding a kind costs a registry entry and one view, and an e2e // spec enforces it by failing when a kind id appears as a string literal // anywhere outside lib/projects/ and components/projects/. A page that grew an // `if (kind === "report-video")` would break that rule silently, so the page // never learns what a kind is -- it resolves a path and renders this. // // `rest` is the segments after the project. [] is the project itself; anything // else is a VIEW the kind declares, and a view a kind does not declare is a 404 // rather than a page that ignores half its URL. // --------------------------------------------------------------------------- export default async function ProjectView({ project, rest, search, }: { project: ProjectRef; rest: string[]; search: Record; }) { switch (project.kind) { case "song": { if (rest.length === 0) return ; if (rest.length === 1) return ; return notFound(); } case "report-video": { if (rest.length === 0) return ; // `/browse//clip/` -- the bench. A view the kind does not // declare is a 404 rather than a page that silently drops half its URL. if (rest.length === 2 && rest[0] === "clip") { return ; } // `/browse//claim/` -- ruling on one ledger entry against // the audio, rather than editing a window. if (rest.length === 2 && rest[0] === "claim") { return ; } // `/browse//takes` -- alternative renders of one part of the // cut, side by side, each judged like / maybe / no. if (rest.length === 1 && rest[0] === "takes") return ; return notFound(); } case "sweep-report": { if (rest.length === 0) return ; return notFound(); } default: // A kind the registry knows and this file does not. That is exactly the // state a half-added kind is in, so it says so instead of 404ing. return (

{project.kind} is a registered kind with no view yet. Add one in components/projects/.

); } }