// §22 three-tier — project + collection-scoped path builders. The canonical // entry route now carries the collection segment: `/p//c//…`. // In S1 each project has a single (default) collection and serving stays // project-scoped, so the builders emit the default collection segment; the // collection-aware link layer (named collections) lands in S2. Components build // links via these helpers so that flip happens in one place. import { useParams, useLocation } from 'react-router-dom' import { useProject } from '../components/ProjectLayout.jsx' import { useDeployment } from '../context/DeploymentProvider' // The default collection id (migration 029 seeds one per project at this id). export const DEFAULT_COLLECTION = 'default' export function entryPath(pid, slug, cid = DEFAULT_COLLECTION) { return `/p/${pid}/c/${cid}/e/${slug}` } export function entryPrPath(pid, slug, prNumber, cid = DEFAULT_COLLECTION) { return `/p/${pid}/c/${cid}/e/${slug}/pr/${prNumber}` } export function proposalPath(pid, prNumber, cid = DEFAULT_COLLECTION) { return `/p/${pid}/c/${cid}/proposals/${prNumber}` } export function collectionHome(pid, cid = DEFAULT_COLLECTION) { return `/p/${pid}/c/${cid}/` } export function projectHome(pid) { return `/p/${pid}/` } // The project id a component should build links against: the contextual // project when inside a `/p/:projectId/*` subtree, else the deployment default. export function useProjectId() { const ctx = useProject() const { defaultProjectId } = useDeployment() return (ctx && ctx.projectId) || defaultProjectId } // §22 S2 — the collection id a component should scope to: the `/c/:collectionId/` // route segment when present, else the project's default collection. // // The route param is only in scope for components rendered *under* the // `c/:collectionId` route (e.g. RFCView). The Catalog renders one level up at // `/p/:projectId/*` — a sibling of that route — so `useParams().collectionId` // is undefined there and it would wrongly fall back to the default collection // (the faceted/bulk catalog UI would then never scope to a named collection). // Fall back to parsing the `/c//` segment from the pathname so the Catalog // scopes correctly regardless of its position in the route tree. export function useCollectionId() { const { collectionId } = useParams() const { pathname } = useLocation() const fromPath = pathname.match(/\/c\/([^/]+)/) return collectionId || (fromPath && fromPath[1]) || DEFAULT_COLLECTION }