Full website

This commit is contained in:
Your Name committed 2026-06-17 07:42:59 -04:00
1 parent 807c43ece5
commit ea9f33f60e
40 files changed
+4503 -1202

No files matched your search

+151
View File
@@ -0,0 +1,151 @@
# Website CMS Parity Plan
## Goal
Bring `apps/website` closer to the Page Builder CMS behavior already used by `apps/spa`, while preserving Next.js SSR/SEO behavior.
The website should not copy SPA client rendering wholesale. It should use CMS layout sections for editable marketing/content areas, and keep SEO-critical commerce data server-rendered.
## Scope
Allowed implementation scope:
- `apps/website/**`
- `docs/**`
- `implementation_plan.md`
Do not edit without separate approval:
- `apps/spa/**`
- `apps/admin/**`
- `apps/backend/**`
- `packages/types/**`
If a correct fix requires backend, admin, schema, or shared type changes, report it as a blocker instead of patching around it in website code.
## Current Website CMS Support
Supported in `apps/website`:
- `/` fetches `/pages/home`
- Website-local `DynamicPageRenderer`
- Supported SSR-safe blocks:
- `ANNOUNCEMENT_BAR`
- `HERO`
- `CATEGORIES`
- `PRODUCTS`
- `PRODUCT_CAROUSEL`
- `BANNER`
- `TEXT`
- `RICH_TEXT`
- `NEWSLETTER`
- `EDITORIAL_TILE`
- `EDITORIAL_CAROUSEL`
- `HERO_ARTICLE`
- `SCENT_NOTES_BREAKDOWN`
- `QUOTE_CALLOUT`
- `ACCORDION`
- `CONTACT_INFO`
Not fully supported yet:
- Client-island block:
- `CONTACT_FORM`
- Nested CMS custom pages such as `/campaign/summer`
- Route layout CMS parity for shop/category/product/search/coupons/scent guide
## Route Layout Matrix
| SPA route | Website route | CMS slug | Status | Implementation notes |
|---|---|---:|---|---|
| `/` | `/` | `home` | supported-m1 | Server-rendered CMS sections. |
| `/shop` | `/shop` | `shop-layout` | supported-m1 | Renders announcement/hero/bottom CMS sections around SSR product grid. |
| `/category/:id` | `/category/[id]` | `category-layout` | supported-m1 | Renders announcement/hero/bottom CMS sections around SSR category product grid. |
| `/products/:id` | `/products/[id]` | `product-detail-layout` | supported-m1 | Renders announcement/bottom CMS sections around SSR product detail. |
| `/search` | `/search` | `search-layout` | supported-m1 | Renders announcement/hero/bottom CMS sections around SSR search form and results. |
| `/scent-guide` | `/scent-guide` | `scent-guide-layout` | supported-m1 | Renders announcement/hero/bottom CMS sections around article index and exposes article API error state. |
| `/coupons` | `/coupons` | `coupons-layout` | supported-m1 | Renders announcement/hero/bottom CMS sections around SSR coupon grid and exposes coupon API error state. |
| `/track` | `/track` | `track-order-layout` | later-phase | Depends on track flow migration. |
| `/wishlist` | none | `wishlist-layout` | later-phase | Depends on wishlist route migration. |
| `/order/:id` | none | `order-success-layout` | later-phase | Depends on order success flow migration. |
| `/:slug` | `[slug]` | page slug | supported-m1 | Server-renders published CMS pages by slug with reserved route collision guard. |
## CMS Layout Rendering Pattern
For SEO-critical routes, use this structure:
1. Fetch route business data on the server.
2. Fetch optional CMS layout page on the server.
3. Render `ANNOUNCEMENT_BAR` sections above page content.
4. Render `HERO` and `BANNER` sections as editable page header when present.
5. Render a safe hardcoded SSR fallback header when CMS header sections are missing.
6. Render route business content as SSR HTML.
7. Render remaining CMS sections below the business content.
This keeps marketing-controlled content editable without making product/category/search content client-only.
## Custom CMS Page Policy
M1 supports single-segment CMS pages through `apps/website/src/app/[slug]/page.tsx`.
Reserved slugs are intentionally blocked from CMS catch-all rendering:
- `about`
- `article`
- `category`
- `contact`
- `coupons`
- `faq`
- `order`
- `products`
- `profile`
- `search`
- `scent-guide`
- `shop`
- `track`
- `wishlist`
Why:
- Existing Next routes should keep their route-specific SSR behavior and metadata.
- Commerce/auth routes should not be silently replaced by CMS content.
- Nested CMS paths need an explicit admin/backend slug policy before website supports them.
## Block Support Roadmap
### Batch A: Layout Blocks Already Present
Use existing website renderer:
- `ANNOUNCEMENT_BAR`
- `HERO`
- `BANNER`
- `TEXT`
- `NEWSLETTER`
- `CATEGORIES`
- `PRODUCTS`
- `PRODUCT_CAROUSEL`
### Batch B: Content Blocks To Port From SPA
Website-local SSR-safe equivalents added:
- `EDITORIAL_TILE`
- `EDITORIAL_CAROUSEL`
- `HERO_ARTICLE`
- `SCENT_NOTES_BREAKDOWN`
- `QUOTE_CALLOUT`
- `ACCORDION`
- `CONTACT_INFO`
### Batch C: Client-Island Blocks
Add only after explicit route needs are clear:
- `CONTACT_FORM`
- newsletter submit behavior
- any block requiring browser state, localStorage, LIFF, auth, or cart state
`CONTACT_FORM` should not simulate successful submission without a real API contract. Keep it unsupported until the website contact submission behavior is defined.
Decision:
- Defer `CONTACT_FORM` for now because the submission endpoint is not ready.
- Do not render a fake successful submission state.
- Do not create a website-only endpoint workaround.
- Revisit only when backend/admin/API ownership for contact submissions is confirmed.
## Acceptance Criteria
- `apps/website` route still renders SEO-critical content on the server.
- CMS layout failure does not break commerce content.
- Published single-segment CMS pages can render through `/:slug`.
- API/data failure for commerce content is visible and not collapsed into a fake empty state.
- Unsupported block types are logged in development and documented in this plan.
- Lint and production build pass for `apps/website`.
- No files outside allowed scope are modified.
## Current Next Step
Skip `CONTACT_FORM` for now and continue with missing website flows such as checkout, order success, tracking, wishlist, and profile.
+43
View File
@@ -0,0 +1,43 @@
# Website Route Parity Audit
Scope: read-only comparison of `apps/spa/src/App.tsx` against `apps/website/src/app/**`.
## Route Matrix
| SPA route | Website route | Status | Notes |
|---|---|---|---|
| `/` | `/` | upgraded-m1 | Server-rendered from the CMS page endpoint internally. |
| `/shop` | `/shop` | upgraded-m1 | Server-renders product/category content, preserves coupon handoff, and consumes `shop-layout` CMS sections around the product grid. |
| `/category/:id` | `/category/[id]` | upgraded-m1 | Server-renders category/product content with dynamic metadata and consumes `category-layout` CMS sections around the product grid. |
| `/products/:id` | `/products/[id]` | upgraded-m1 | Server-renders product details and metadata, and consumes `product-detail-layout` CMS sections around the product content. |
| `/coupons` | `/coupons` | upgraded-m1 | Uses internal links, consumes `coupons-layout` CMS sections, and exposes coupon API error state. |
| `/checkout` | `/checkout` | partial-m1 | Client checkout creates pending orders through `POST /orders`, supports settings shipping fee, promotions, coupon validation, saved addresses, points, local order history, and `checkout-layout` CMS sections. Payment/slip upload remains deferred to `/order/[id]` follow-up. |
| `/order/:id` | `/order/[id]` | partial-m1 | Server-renders order status, item summary, tracking number, and `order-success-layout` CMS sections. Payment/upload actions are intentionally deferred. |
| `/track` | `/track` | upgraded-m1 | Replaces redirect with order tracking form, `POST /orders/track`, device order history, and `track-order-layout` CMS sections. |
| `/wishlist` | `/wishlist` | upgraded-m1 | Client wishlist store now matches SPA storage key, supports add/remove from product cards, and consumes `wishlist-layout` CMS sections. |
| `/search` | `/search` | upgraded-m1 | Server-renders search results, guards repeated query params, and consumes `search-layout` CMS sections around the search UI. |
| `/scent-guide` | `/scent-guide` | upgraded-m1 | Server-renders article index, consumes `scent-guide-layout` CMS sections, and exposes article API error state. |
| `/article/:slug` | `/article/[slug]` | exists-needs-upgrade | Exists with dynamic metadata and `notFound`; needs HTML sanitization review. |
| `/profile` | `/profile` | partial-m1 | Client profile dashboard uses SPA-compatible auth storage, order history, address CRUD, contact settings, and `profile-layout` CMS sections. LIFF initialization for website remains a follow-up dependency. |
| `/:slug` | `/[slug]` | upgraded-m1 | Server-renders published single-segment CMS pages with reserved route collision guard. |
| `*` | default Next behavior | missing | No custom `not-found.tsx` currently exists. |
## Top Website-Only Risks
| Risk | Severity | Impact |
|---|---|---|
| Missing legacy classes/design tokens | High | M1 visual cleanup removed `night-*`, `cyan-glow`, and `glass` from website source classes; remaining visual risk is manual UI verification across breakpoints. |
| Hardcoded production URLs | Medium | Initial coupon page issue is fixed; continue checking remaining legacy pages during Phase 6. |
| Silent API fallbacks | High | M1 SEO routes now expose explicit error states in key product listing flows; remaining legacy pages still need review. |
| Client-only SEO weakness | High | M1 fixed `/shop`, `/category/[id]`, `/search`, `/track`, `/wishlist`, `/profile`, `/checkout`, and read-only `/order/[id]`; remaining auth/payment flows are still later-phase work. |
| Client-side pricing trust | High | Checkout follows the SPA contract, but backend still trusts client-provided subtotal, discounts, points, shipping, and total. Server-side pricing validation should be owned by backend before production-grade payment rollout. |
| Image optimization debt | Low | M1 intentionally keeps `<img>` until image hosting/CDN policy is finalized; `next/image` should be revisited after `images.remotePatterns` can be configured safely. |
## Recommended Order
1. Stabilize website-local data helpers.
2. Add website CMS renderer and upgrade `/`.
3. Upgrade `/products/[id]`.
4. Convert `/shop` and `/category/[id]` to SSR shell plus client islands.
5. Add CMS custom `/:slug` support with explicit collision rules.
6. Add missing commerce/client routes after SEO pages are stable.