b5dac8886f
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
32 lines
1.4 KiB
TypeScript
32 lines
1.4 KiB
TypeScript
// Hash routing for admin sections (SD-0002 §5). The URL is the durable handle on a
|
|
// section (PUC-8: run detail can be left and returned to); the SD-0001 entry-routing
|
|
// rule (routing.ts) still decides whether the admin renders at all.
|
|
export type AdminView =
|
|
| { view: "home" }
|
|
| { view: "products" }
|
|
| { view: "import-upload" }
|
|
| { view: "import-preview"; draftId: number }
|
|
| { view: "run-detail"; runId: number };
|
|
|
|
export function adminViewFor(hash: string): AdminView {
|
|
const parts = hash.replace(/^#\/?/, "").split("/").filter(Boolean);
|
|
if (parts[0] !== "products") return { view: "home" };
|
|
if (parts.length === 1) return { view: "products" };
|
|
if (parts[1] === "import" && parts.length === 2) return { view: "import-upload" };
|
|
if (parts[1] === "imports" && parts[2] === "drafts" && /^\d+$/.test(parts[3] ?? ""))
|
|
return { view: "import-preview", draftId: Number(parts[3]) };
|
|
if (parts[1] === "imports" && parts[2] === "runs" && /^\d+$/.test(parts[3] ?? ""))
|
|
return { view: "run-detail", runId: Number(parts[3]) };
|
|
return { view: "products" };
|
|
}
|
|
|
|
export function hashFor(v: AdminView): string {
|
|
switch (v.view) {
|
|
case "home": return "#/";
|
|
case "products": return "#/products";
|
|
case "import-upload": return "#/products/import";
|
|
case "import-preview": return `#/products/imports/drafts/${v.draftId}`;
|
|
case "run-detail": return `#/products/imports/runs/${v.runId}`;
|
|
}
|
|
}
|