docs(product): spec CMS public landing page (Phase 13)

Splash owns /, catalogue moves to /catalogue, authed users redirected
via HierarchicalRoleAuthorizeView. Skipper's public-layout pattern,
branded to DeepDrft. Adds Phase 13 to PLAN.md.
This commit is contained in:
daniel-c-harvey
2026-06-17 11:44:33 -04:00
parent 9009f2c8cf
commit 5fb46bf5eb
2 changed files with 381 additions and 0 deletions
+38
View File
@@ -387,6 +387,44 @@ a lava lamp on the landing page is no surprise.
---
## Phase 13 — CMS Public Landing
Give `DeepDrftManager` (the CMS) a true public face: an unauthenticated splash at `/` with DeepDrft
branding and a single **Login** CTA; authenticated admins are redirected past it to the catalogue.
Today `/` is the `[Authorize]`-gated catalogue, so an anonymous hit falls straight through to the login
form — there is no front door. Pattern borrowed from Skipper's `MainHomeLayout` / `Home.razor`
(dedicated public layout + `HierarchicalRoleAuthorizeView` redirect-the-authed-user idiom), branded to
the DeepDrft navy/green/off-white identity (`DeepDrftPalettes.Cms`), **not** Skipper's nautical look.
Additive — the admin experience is intact; only the catalogue's *route* moves. Full spec, routing-reshape
rationale, file responsibilities, hero/CTA composition, asset path, and acceptance criteria:
`product-notes/cms-public-landing.md`.
**Routing decision (recommended, spec §2): Option A — splash owns `/`, catalogue moves to `/catalogue`.**
A new `Home.razor` (`@page "/"`, no `[Authorize]`, new `CmsHomeLayout`) wraps its body in
`<HierarchicalRoleAuthorizeView>`: `Authorized` → redirect to `/catalogue`; `NotAuthorized` → hero +
Login CTA. `Index.razor` changes `@page "/"` → `@page "/catalogue"` (one-line; otherwise untouched).
`Routes.razor` and `Program.cs` need no change — the host is already `AllowAnonymous` at the endpoint and
page auth is owned by `AuthorizeRouteView`, so a no-`[Authorize]` page renders for everyone. The entire
cost of Option A is a small, mechanical link-repoint (every internal `/` that meant *catalogue* →
`/catalogue`; spec §6). Options B (layout-by-auth-state, conflates page concerns) and C (splash at a
side route, defeats the goal) were weighed and rejected.
- **New files:** `Components/Layout/CmsHomeLayout.razor` (lean public layout — same `DeepDrftPalettes.Cms`
theme, front-door AppBar, centered narrow `MudContainer`), `Components/Pages/Home.razor` (the splash),
`Components/RedirectToCatalogue.razor` (mirrors existing `RedirectToAccessDenied`; inline redirect
acceptable). **Changed:** `Index.razor` route line; `CmsLayout.razor` "Back to site" `Href="/"` →
`/catalogue`.
- **Hero asset (Daniel-supplied):** `DeepDrftManager/wwwroot/img/cms-hero.png` (creates the `wwwroot/img/`
dir, net-new); referenced `Src="img/cms-hero.png"`. The page must compile/render without it.
- **No new shared component, no new palette, no `@rendermode` override, no Register CTA** (CMS is
invite/seed-only — single Login button). DRY/MudBlazor-first throughout; the only bespoke CSS is the
layout's one viewport `min-height`.
- **One open copy question for Daniel (non-structural):** AppBar/title wording — "Deep Drft" vs.
"Deep Drft — Admin" (spec §4 recommends "Deep Drft — Admin" in the bar, "Deep Drft" as the hero title).
Implementable either way without rework.
---
## Working with this file
- **Add items by extending an existing phase first**; only create a new phase when the addition genuinely doesn't fit any of 15. Phase numbers are organisational, not sequencing.