- 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
22 KiB
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
ExampleSectioncomponents - 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
ExampleSectioncomponents - 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
ExampleSectioncomponents - 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):
<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:
<div className="min-h-screen bg-background">
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
Hub/Docs:
<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)
<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)
<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:
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:
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:
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:
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:
export function ExampleLoadingSkeleton() {
return <div className="animate-pulse h-64 bg-muted rounded-lg" />;
}
Use in all heavy components:
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:
// 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:
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):
- Create
DevPageHeadercomponent - Create
DevPageLayoutwrapper - Update Forms/Layouts/Spacing pages to use new components
Phase 2 (Important - UX improvements):
- Create
DevBreadcrumbscomponent - Create
DevPageFootercomponent - Add breadcrumbs to all pages
- Standardize footers
Phase 3 (Nice to have - Polish):
- Add Table of Contents to long pages
- Audit Components page structure
- Standardize dynamic imports
- 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 | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |