Revert Zustand persist middleware approach and restore AuthInitializer

- Remove persist middleware from authStore (causing hooks timing issues)
- Restore original AuthInitializer component pattern
- Keep good Phase 3 optimizations:
  - Theme FOUC fix (inline script)
  - React Query refetchOnWindowFocus disabled
  - Code splitting for dev/auth components
  - Shared form components (FormField, useFormError)
  - Store location in lib/stores
This commit is contained in:
2025-11-02 14:52:12 +01:00
parent 6d1b730ae7
commit 68e28e4c76
22 changed files with 2822 additions and 398 deletions

View File

@@ -0,0 +1,758 @@
# Page Structure Analysis: /dev/ Routes
## Executive Summary
The `/dev/` pages show **significant inconsistencies** in structure, header implementation, and layout patterns. While they share a common `DevLayout` wrapper through the parent `layout.tsx`, individual pages implement their own headers and footers inconsistently, leading to duplicated code and potential maintenance issues.
---
## Detailed Page Analysis
### 1. `/dev/page.tsx` (Design System Hub)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/page.tsx`
**Structure:**
- No `'use client'` directive (Server Component)
- No custom header (relies entirely on shared `DevLayout`)
- No footer
- Hero section with gradient background
- Multiple content sections separated by `<Separator />`
- 3 main content areas: Demo Pages Grid, Documentation Links, Key Features
**Breadcrumbs:** None
**Page Title:** None (relies on h1 in hero section: "Design System Hub")
**Footer:** None
**Header/Nav:** Inherited from `DevLayout` only
**Components Used:**
- Icon components (Palette, Layout, Ruler, FileText, BookOpen, ArrowRight, Sparkles)
- Card, CardContent, CardDescription, CardHeader, CardTitle
- Badge, Separator, Button
**Layout Pattern:**
```
DevLayout (sticky header with global nav)
├── Hero Section (gradient, py-12)
├── Main Content (container, px-4, py-12)
│ ├── Demo Pages Section (space-y-12)
│ │ └── Grid (md:grid-cols-2)
│ ├── Separator
│ ├── Documentation Links Section
│ │ └── Grid (sm:grid-cols-2, lg:grid-cols-4)
│ ├── Separator
│ └── Key Features Section
│ └── Grid (sm:grid-cols-2, lg:grid-cols-3)
```
---
### 2. `/dev/components/page.tsx` (Component Showcase)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/components/page.tsx`
**Structure:**
- No `'use client'` directive (Server Component)
- Dynamic imports with loading state
- No custom header
- No footer
- Minimal page structure - just renders `<ComponentShowcase />`
**Breadcrumbs:** None
**Page Title:** None
**Footer:** None
**Header/Nav:** Inherited from `DevLayout` only
**Components Used:**
- Dynamic `ComponentShowcase` (787 lines, code-split)
**Layout Pattern:**
```
DevLayout (sticky header with global nav)
├── Main Content
│ └── ComponentShowcase (dynamically loaded)
│ └── (787 lines of component examples)
```
**Issues:**
- Minimal structure - just a wrapper around ComponentShowcase
- No breadcrumbs to show navigation depth
- No page title/description
---
### 3. `/dev/forms/page.tsx` (Form Patterns Demo)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/forms/page.tsx`
**Structure:**
- `'use client'` directive (Client Component)
- Custom sticky header with back button and title
- Content organized in `ExampleSection` components
- Custom footer with documentation link
**Breadcrumbs:** Implicit (back button in header)
**Page Title:** "Form Patterns" (in sticky header)
**Footer:** Yes (mt-16, border-t, py-6)
**Header/Nav:** Custom implementation (does NOT use `DevLayout`)
**Components Used:**
- Custom sticky header with back button
- Example, ExampleSection, BeforeAfter
- Form components: Input, Label, Textarea, Select
- react-hook-form, Zod validation
- Card, Button, Badge, Alert
**Layout Pattern:**
```
Custom Sticky Header
├── Back button → /dev
├── Title: "Form Patterns"
├── Subtitle: "react-hook-form + Zod validation examples"
Main Content (container, mx-auto, px-4, py-8)
├── Introduction (max-w-3xl)
├── ExampleSection × 6
│ ├── Basic Form
│ ├── Complete Form
│ ├── Error States
│ ├── Loading States
│ ├── Zod Patterns
└── Footer (mt-16, border-t)
└── Link to /dev/docs/design-system/06-forms
```
**Unique Features:**
- Back button to return to hub
- Two-tab Example components (Preview/Code)
- BeforeAfter comparisons for accessibility patterns
- Custom state management (isSubmitting, submitSuccess)
---
### 4. `/dev/layouts/page.tsx` (Layout Patterns Demo)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/layouts/page.tsx`
**Structure:**
- Server Component (no `'use client'`)
- Custom sticky header with back button and title
- Content organized in `ExampleSection` components
- Custom footer with documentation link
**Breadcrumbs:** Implicit (back button in header)
**Page Title:** "Layout Patterns" (in sticky header)
**Footer:** Yes (mt-16, border-t, py-6)
**Header/Nav:** Custom implementation (NOT `DevLayout`)
**Components Used:**
- Custom sticky header (identical structure to forms page)
- Example, ExampleSection, BeforeAfter
- Card components, Badge, Button
- Grid3x3 icon
**Layout Pattern:**
```
Custom Sticky Header
├── Back button → /dev
├── Title: "Layout Patterns"
├── Subtitle: "Essential patterns for pages, dashboards, and forms"
Main Content (container, mx-auto, px-4, py-8)
├── Introduction (max-w-3xl)
├── ExampleSection × 7
│ ├── 1. Page Container
│ ├── 2. Dashboard Grid
│ ├── 3. Form Layout
│ ├── 4. Sidebar Layout
│ ├── 5. Centered Content
│ ├── Decision Tree (Grid vs Flex)
│ └── Responsive Patterns
└── Footer (mt-16, border-t)
└── Link to /dev/docs/design-system/03-layouts
```
**Issues:**
- Duplicates same header pattern as `/dev/forms/page.tsx`
- Both implement nearly identical sticky headers
---
### 5. `/dev/spacing/page.tsx` (Spacing Patterns Demo)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/spacing/page.tsx`
**Structure:**
- Server Component (no `'use client'`)
- Dynamic imports for heavy components (Example, ExampleSection, BeforeAfter)
- Custom sticky header with back button and title
- Content organized in `ExampleSection` components
- Custom footer with documentation link
**Breadcrumbs:** Implicit (back button in header)
**Page Title:** "Spacing Patterns" (in sticky header)
**Footer:** Yes (mt-16, border-t, py-6)
**Header/Nav:** Custom implementation (NOT `DevLayout`)
**Components Used:**
- Custom sticky header
- Dynamically loaded: Example, ExampleSection, BeforeAfter
- Card, Badge, Button
- Ruler icon
**Layout Pattern:**
```
Custom Sticky Header
├── Back button → /dev
├── Title: "Spacing Patterns"
├── Subtitle: "Parent-controlled spacing philosophy"
Main Content (container, mx-auto, px-4, py-8)
├── Introduction (max-w-3xl)
├── ExampleSection × 7
│ ├── Spacing Scale
│ ├── Gap for Flex/Grid
│ ├── Space-y for Vertical Stacks
│ ├── Anti-patterns
│ ├── Decision Tree
│ └── Common Patterns
└── Footer (mt-16, border-t)
└── Link to /dev/docs/design-system/04-spacing-philosophy
```
**Notable:**
- Uses dynamic imports with loading skeletons (performance optimization)
- Spacing page doesn't use `'use client'` but Example/ExampleSection ARE client components
---
### 6. `/dev/docs/page.tsx` (Documentation Hub)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/docs/page.tsx`
**Structure:**
- Server Component (no `'use client'`)
- No custom header (relies on `DevLayout`)
- No footer
- Hero section with gradient background
- Multiple documentation sections
**Breadcrumbs:** None
**Page Title:** None (relies on h2 in hero: "Design System Documentation")
**Footer:** None
**Header/Nav:** Inherited from `DevLayout` only
**Components Used:**
- Icon components (BookOpen, Sparkles, Layout, Palette, Code2, FileCode, Accessibility, Lightbulb, Search)
- Card, CardContent, CardDescription, CardHeader, CardTitle
- Badge, Button
**Layout Pattern:**
```
DevLayout (sticky header with global nav)
├── Hero Section (gradient, py-16)
│ ├── Title: "Design System Documentation"
│ ├── Description
│ └── CTA Buttons (3 variants)
├── Main Content (container, mx-auto, px-4, py-12)
│ └── Max-w-6xl
│ ├── Getting Started Section
│ │ └── Grid (md:grid-cols-2)
│ ├── Core Concepts Section
│ │ └── Grid (md:grid-cols-2, lg:grid-cols-3)
│ └── References Section
│ └── Grid (md:grid-cols-2)
```
---
### 7. `/dev/docs/design-system/[...slug]/page.tsx` (Dynamic Documentation)
**Path:** `/workdrive/workspace/Projects/HomeLab/fast-next-template/frontend/src/app/dev/docs/design-system/[...slug]/page.tsx`
**Structure:**
- Server Component with async rendering
- Reads markdown files from disk
- No custom header (relies on `DevLayout`)
- No footer
- Minimal wrapper structure
**Breadcrumbs:** None
**Page Title:** Extracted from markdown frontmatter
**Footer:** None
**Header/Nav:** Inherited from `DevLayout` only
**Components Used:**
- MarkdownContent (renders parsed markdown)
- gray-matter (for frontmatter parsing)
**Layout Pattern:**
```
DevLayout (sticky header with global nav)
├── Main Content (container, mx-auto, px-4, py-8)
│ └── Max-w-4xl
│ └── MarkdownContent
│ └── Rendered markdown from file system
```
**Notable:**
- Uses `generateStaticParams()` for static generation
- Minimal structure - just content wrapper
- No breadcrumbs despite being nested route
---
## Structure Comparison Table
| Aspect | Hub | Components | Forms | Layouts | Spacing | Docs | Docs Dynamic |
|--------|-----|-----------|-------|---------|---------|------|------|
| `'use client'` | No | No | YES | No | No | No | No |
| Custom Header | No | No | YES | YES | YES | No | No |
| Sticky Header | N/A | N/A | YES | YES | YES | N/A | N/A |
| Back Button | No | No | YES | YES | YES | No | No |
| Page Title Display | Hero only | None | Header | Header | Header | Hero only | Frontmatter |
| Breadcrumbs | None | None | Implicit | Implicit | Implicit | None | None |
| Custom Footer | No | No | YES | YES | YES | No | No |
| Hero Section | YES | No | No | No | No | YES | No |
| Footer Documentation Link | No | No | YES | YES | YES | No | No |
| ExampleSection Usage | No | No | YES | YES | YES | No | No |
| BeforeAfter Usage | No | No | YES | YES | YES | No | No |
| Dynamic Imports | No | YES | No | No | YES | No | No |
| Content Sections | 3 | 1 | 6 | 7 | 7 | 3 | 1 |
---
## Identified Inconsistencies
### 1. Header Implementation (CRITICAL)
**Problem:** Forms, Layouts, and Spacing pages implement duplicate custom sticky headers instead of using `DevLayout`.
**Current Pattern (Forms/Layouts/Spacing):**
```typescript
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur">
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
<Link href="/dev">
<Button variant="ghost" size="icon" aria-label="Back to hub">
<ArrowLeft className="h-5 w-5" />
</Button>
</Link>
<div>
<h1 className="text-xl font-bold">{title}</h1>
<p className="text-sm text-muted-foreground">{subtitle}</p>
</div>
</div>
</header>
```
**Problem:**
- Duplicated across 3 pages (DRY violation)
- DevLayout is ignored on these pages
- Breaking point: Sticky headers override global nav
**Expected:** Should use a shared pattern or component
---
### 2. Page Title/Breadcrumbs (CRITICAL)
**Problem:** No consistent pattern for breadcrumbs or page titles.
- Hub, Docs: Hero section titles
- Components: No title at all
- Forms, Layouts, Spacing: Header titles only
- Docs Dynamic: Frontmatter (if present)
**Missing:** True breadcrumb navigation for nested routes
---
### 3. Footer Implementation (INCONSISTENT)
**Problem:** Some pages have footers, others don't.
**Pages with footers:**
- Forms: `<footer className="mt-16 border-t py-6">`
- Layouts: `<footer className="mt-16 border-t py-6">`
- Spacing: `<footer className="mt-16 border-t py-6">`
**Pages without footers:**
- Hub: None
- Components: None
- Docs: None
- Docs Dynamic: None
**Issue:** Documentation link footers only on 3 pages creates inconsistent UX
---
### 4. Page Layout Wrapper (INCONSISTENT)
**Problem:** Inconsistent use of wrapper divs.
**Forms/Layouts/Spacing:**
```typescript
<div className="min-h-screen bg-background">
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
```
**Hub/Docs:**
```typescript
<div className="bg-background">
{/* Hero Section */}
<section>...</section>
<main>...</main>
</div>
```
**Components:**
No wrapper at all - just `<ComponentShowcase />`
---
### 5. Content Container Padding (MINOR)
**Problem:** Inconsistent container and padding patterns.
```
Hub/Docs: container mx-auto px-4 py-12
Forms/Layouts/Spacing: container mx-auto px-4 py-8
Docs Dynamic: container mx-auto px-4 py-8
```
**Expected:** Standardized to `py-8` or `py-12` across all
---
### 6. 'use client' Directive (INCONSISTENT)
**Problem:** Inconsistent use of client vs server components.
- Forms: `'use client'` (needs interactivity)
- Others: Server components (except those with dynamic imports)
- Spacing: Server component with dynamic client imports
**Question:** Should all pages be consistent?
---
### 7. Component Loading/Code Splitting (INCONSISTENT)
**Problem:** Inconsistent approach to component loading.
**Components Page:**
- Uses dynamic imports with loading state
**Spacing Page:**
- Uses dynamic imports with skeleton loading
**Forms/Layouts Pages:**
- No dynamic imports, inline all components
**Expected:** Consistent strategy across demo pages
---
### 8. ExampleSection Organization (INCONSISTENT)
**Problem:** Not all pages use `ExampleSection`.
- Hub: No ExampleSection (custom layout)
- Components: No ExampleSection (uses ComponentShowcase)
- Forms/Layouts/Spacing: All use ExampleSection
- Docs: No ExampleSection
- Docs Dynamic: No ExampleSection
---
## Common Patterns Found
### Pattern 1: Hero Section + Grid Layout (Hub, Docs)
```typescript
<section className="border-b bg-gradient-to-b from-background to-muted/20 py-12">
<div className="container mx-auto px-4">
{/* Content */}
</div>
</section>
<main className="container mx-auto px-4 py-12">
<div className="space-y-12">
{/* Multiple sections with grids */}
</div>
</main>
```
### Pattern 2: Sticky Header + Sections (Forms, Layouts, Spacing)
```typescript
<header className="sticky top-0 z-50...">
{/* Custom header with back button */}
</header>
<main className="container mx-auto px-4 py-8">
<div className="space-y-12">
<ExampleSection>{...}</ExampleSection>
</div>
</main>
<footer className="mt-16 border-t py-6">{...}</footer>
```
---
## Recommendations
### 1. CREATE SHARED HEADER COMPONENT (HIGH PRIORITY)
Create `/src/components/dev/DevPageHeader.tsx`:
```typescript
interface DevPageHeaderProps {
title: string;
subtitle?: string;
showBackButton?: boolean;
breadcrumbs?: Array<{ label: string; href: string }>;
}
export function DevPageHeader({ title, subtitle, showBackButton, breadcrumbs }: DevPageHeaderProps) {
// Replaces duplicated headers in forms, layouts, spacing pages
}
```
**Impact:** Reduces code duplication, standardizes header UX
---
### 2. ADD BREADCRUMBS COMPONENT (MEDIUM PRIORITY)
Create `/src/components/dev/DevBreadcrumbs.tsx`:
```typescript
interface Breadcrumb {
label: string;
href: string;
}
export function DevBreadcrumbs({ items }: { items: Breadcrumb[] }) {
// Renders: Home > Section > Current Page
}
```
**Usage:**
- Hub: None
- Components: `[{ label: 'Hub', href: '/dev' }, { label: 'Components' }]`
- Forms: `[{ label: 'Hub', href: '/dev' }, { label: 'Forms' }]`
- Layouts: `[{ label: 'Hub', href: '/dev' }, { label: 'Layouts' }]`
- Spacing: `[{ label: 'Hub', href: '/dev' }, { label: 'Spacing' }]`
- Docs: `[{ label: 'Hub', href: '/dev' }, { label: 'Docs' }]`
- Docs Dynamic: `[{ label: 'Docs', href: '/dev/docs' }, { label: currentTitle }]`
---
### 3. STANDARDIZE FOOTER (MEDIUM PRIORITY)
Create `/src/components/dev/DevPageFooter.tsx`:
```typescript
interface DevPageFooterProps {
documentationLink?: {
label: string;
href: string;
};
}
export function DevPageFooter({ documentationLink }: DevPageFooterProps) {
return (
<footer className="mt-16 border-t py-6">
{documentationLink && (
<div className="container mx-auto px-4 text-center">
<p className="text-sm text-muted-foreground">
Learn more:{' '}
<Link href={documentationLink.href} className="font-medium hover:text-foreground">
{documentationLink.label}
</Link>
</p>
</div>
)}
</footer>
);
}
```
**Add to ALL pages:** Hub, Components, Forms, Layouts, Spacing, Docs
---
### 4. CREATE DEVPAGE LAYOUT WRAPPER (HIGH PRIORITY)
Create `/src/components/dev/DevPageLayout.tsx`:
```typescript
interface DevPageLayoutProps {
title?: string;
subtitle?: string;
breadcrumbs?: Breadcrumb[];
showBackButton?: boolean;
footer?: { label: string; href: string };
children: React.ReactNode;
}
export function DevPageLayout({
title,
subtitle,
breadcrumbs,
showBackButton,
footer,
children,
}: DevPageLayoutProps) {
return (
<div className="min-h-screen bg-background">
{breadcrumbs && <DevBreadcrumbs items={breadcrumbs} />}
{title && (
<DevPageHeader
title={title}
subtitle={subtitle}
showBackButton={showBackButton}
breadcrumbs={breadcrumbs}
/>
)}
<main className="container mx-auto px-4 py-8">{children}</main>
{footer && <DevPageFooter documentationLink={footer} />}
</div>
);
}
```
---
### 5. STANDARDIZE COMPONENT LOADING (MEDIUM PRIORITY)
Use consistent pattern for code-splitting:
**Create loading skeleton component:**
```typescript
export function ExampleLoadingSkeleton() {
return <div className="animate-pulse h-64 bg-muted rounded-lg" />;
}
```
**Use in all heavy components:**
```typescript
const ComponentShowcase = dynamic(() => import('@/components/dev/ComponentShowcase'), {
loading: () => <ExampleLoadingSkeleton />,
});
```
---
### 6. UPDATE DevLayout TO NOT OVERRIDE (MEDIUM PRIORITY)
Current issue: Forms, Layouts, Spacing pages implement custom headers that hide global nav.
**Solution:** Update those pages to use DevLayout properly OR explicitly extend it:
```typescript
// Option A: Remove custom headers and use DevLayout's nav + page title
// Option B: Make DevLayout flexible to show page-specific titles
```
---
### 7. AUDIT Components PAGE (LOW PRIORITY)
The Components page is minimal - just a wrapper around ComponentShowcase.
**Consider:**
- Add breadcrumbs
- Add footer
- Add page title/subtitle
- Show 787-line warning or lazy load sections
---
### 8. ADD TABLE OF CONTENTS (LOW PRIORITY)
For longer pages (Layouts, Spacing), add sidebar with section navigation:
```typescript
const sections = [
{ id: 'spacing-scale', label: 'Spacing Scale' },
{ id: 'gap', label: 'Gap for Flex/Grid' },
// ...
];
<TableOfContents sections={sections} />
```
---
## Implementation Priority
**Phase 1 (Critical - Fixes inconsistencies):**
1. Create `DevPageHeader` component
2. Create `DevPageLayout` wrapper
3. Update Forms/Layouts/Spacing pages to use new components
**Phase 2 (Important - UX improvements):**
1. Create `DevBreadcrumbs` component
2. Create `DevPageFooter` component
3. Add breadcrumbs to all pages
4. Standardize footers
**Phase 3 (Nice to have - Polish):**
1. Add Table of Contents to long pages
2. Audit Components page structure
3. Standardize dynamic imports
4. Add loading states to all dynamic components
---
## Code Duplication Analysis
### Header Duplication (3 pages - 40 lines × 3)
```
/dev/forms/page.tsx: Lines 99-113
/dev/layouts/page.tsx: Lines 31-45
/dev/spacing/page.tsx: Lines 46-60
Total duplicated: ~40 lines × 3 = 120 lines of nearly identical code
```
### Footer Duplication (3 pages - 8 lines × 3)
```
/dev/forms/page.tsx: Lines 572-584
/dev/layouts/page.tsx: Lines 507-519
/dev/spacing/page.tsx: Lines 520-532
Total duplicated: ~8 lines × 3 = 24 lines of identical code
```
**Total Duplication:** 144 lines of code that could be extracted into components
---
## File Structure Refactor Proposal
```
frontend/src/components/dev/
├── DevLayout.tsx (current - global layout)
├── DevPageHeader.tsx (NEW - shared page header)
├── DevBreadcrumbs.tsx (NEW - breadcrumb navigation)
├── DevPageFooter.tsx (NEW - shared page footer)
├── DevPageLayout.tsx (NEW - complete page wrapper)
├── Example.tsx (current - example container)
├── ExampleSection.tsx (extracted from Example.tsx)
├── ExampleGrid.tsx (extracted from Example.tsx)
├── BeforeAfter.tsx (current)
├── CodeSnippet.tsx (current)
└── ComponentShowcase.tsx (current)
```
---
## Summary Table: What Each Page Should Have
| Element | Hub | Components | Forms | Layouts | Spacing | Docs | Docs Dyn |
|---------|-----|-----------|-------|---------|---------|------|----------|
| Breadcrumbs | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
| Page Title | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Hero Section | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ |
| Sticky Header | ✗ | ✗ | ✓ | ✓ | ✓ | ✗ | ✗ |
| Footer | ✗ | ✗ | ✓ | ✓ | ✓ | ✗ | ✗ |
| Back Button | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
| Content Sections | 3 | 1 | 6 | 7 | 7 | 3 | 1 |
**Proposed Target:**
| Element | Hub | Components | Forms | Layouts | Spacing | Docs | Docs Dyn |
|---------|-----|-----------|-------|---------|---------|------|----------|
| Breadcrumbs | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
| Page Title | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Hero Section | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ |
| Sticky Header | ✗ | ✗ | REMOVE | REMOVE | REMOVE | ✗ | ✗ |
| Footer | UPGRADE | UPGRADE | ✓ | ✓ | ✓ | UPGRADE | UPGRADE |
| Back Button | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |