Files
pragma-stack/DEV_PAGES_STRUCTURE_ANALYSIS.md
Felipe Cardoso 68e28e4c76 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
2025-11-02 14:52:12 +01:00

759 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |