import Link from "next/link"; import { notFound } from "next/navigation"; import ProjectView from "@/components/projects/ProjectView"; import { projectRefs } from "@/lib/projects"; export const dynamic = "force-dynamic"; // --------------------------------------------------------------------------- // The escape hatch for a project that cannot be reached at its own URL. // // Two ways that happens, and both used to fail silently. A project whose first // path segment is a tool page name -- `find`, `trim`, `decisions` -- can never // win the route, because a static segment beats a dynamic one; it was listed, // linked, and the link rendered the phrase console. And a project whose name // isSegment() dislikes (a space is enough) simply vanished from the listing. // // `?path=` is validated by MEMBERSHIP of the current scan, not by inspecting the // string: it either is one of the projects the walk found or it is a 404. That // is the same rule every other name that crosses the wire in this app follows, // and it is why this page cannot be turned into a file reader. // --------------------------------------------------------------------------- export default async function AtPage({ searchParams, }: { searchParams: Promise>; }) { const search = await searchParams; const wanted = search.path; const project = wanted ? (await projectRefs()).find((p) => p.id === wanted) : null; if (!project) notFound(); const why = project.routing === "shadowed" ? `/browse/${project.id.split("/")[0]} is a tool page, so this project can never be opened at its own URL. Rename the directory, or work here.` : project.routing === "unroutable" ? "This directory's name cannot be a URL segment, so it has no address of its own. Rename it to letters, digits, dots, dashes and underscores to give it one." : null; return ( <> {why && (
{why}{" "} every project
)} ); }