# Component Architecture

This document defines the strict separation of concerns for all UI code in the website layer.

## The Three Layers

```
apps/website/
├── app/                    ← App Layer (Pages & Layouts)
├── components/            ← Component Layer (App Components)
├── ui/                    ← UI Layer (Pure Elements)
└── hooks/                 ← Shared Logic
```

---

## 1. App Layer (`app/`)

**Purpose**: Pages, layouts, and routing configuration.

**Characteristics**:
- ✅ Only page.tsx, layout.tsx, route.tsx files
- ✅ Can import from `components/`, `ui/`, `hooks/`
- ✅ Can use Next.js features (redirect, cookies, headers)
- ✅ Can use Server Components
- ❌ **NO raw HTML with styling**
- ❌ **NO business logic**
- ❌ **NO state management**

**Allowed**:
```typescript
// app/dashboard/page.tsx
export default function DashboardPage() {
  return (
    <DashboardLayout>
      <DashboardHeader />
      <DashboardStats />
      <DashboardActions />
    </DashboardLayout>
  );
}
```

**Forbidden**:
```typescript
// ❌ WRONG - Raw HTML in app/
export default function DashboardPage() {
  return (
    <div className="bg-white p-6">  {/* ❌ No raw HTML with styling */}
      <h1 className="text-2xl">Dashboard</h1>
      <button onClick={handleSubmit}>Click</button>  {/* ❌ No inline handlers */}
    </div>
  );
}
```

---

## 2. Component Layer (`components/`)

**Purpose**: App-level components that may contain state and business logic.

**Characteristics**:
- ✅ Can be stateful (useState, useReducer)
- ✅ Can have side effects (useEffect)
- ✅ Can use hooks
- ✅ Can contain business logic
- ✅ Can import from `ui/`, `hooks/`
- ❌ **NO Next.js imports** (navigation, routing)
- ❌ **NO raw HTML with styling** (use ui/ elements)

**Allowed**:
```typescript
// components/DashboardHeader.tsx
export function DashboardHeader() {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <header>
      <Button onClick={() => setIsOpen(!isOpen)}>Toggle</Button>
      {isOpen && <Menu />}
    </header>
  );
}
```

**Forbidden**:
```typescript
// ❌ WRONG - Next.js imports in components/
import { useRouter } from 'next/navigation';  // ❌

export function DashboardHeader() {
  const router = useRouter();  // ❌
  // ...
}
```

---

## 3. UI Layer (`ui/`)

**Purpose**: Pure, reusable, stateless UI elements.

**Characteristics**:
- ✅ Stateless (no useState, useReducer)
- ✅ No side effects (no useEffect)
- ✅ Pure functions based on props
- ✅ Maximum reusability
- ✅ Framework-agnostic
- ❌ **NO state management**
- ❌ **NO Next.js imports**
- ❌ **NO business logic**

**Allowed**:
```typescript
// ui/Button.tsx
export function Button({ children, onClick, variant = 'primary' }) {
  const className = variant === 'primary' 
    ? 'bg-blue-500 text-white' 
    : 'bg-gray-200 text-black';
  
  return (
    <button className={className} onClick={onClick}>
      {children}
    </button>
  );
}

// ui/Card.tsx
export function Card({ children, className = '' }) {
  return (
    <div className={`bg-white rounded-lg shadow ${className}`}>
      {children}
    </div>
  );
}
```

**Forbidden**:
```typescript
// ❌ WRONG - State in UI element
export function Button({ children }) {
  const [isLoading, setIsLoading] = useState(false);  // ❌
  
  return <button>{isLoading ? 'Loading...' : children}</button>;
}

// ❌ WRONG - Next.js imports
import { useRouter } from 'next/navigation';  // ❌

export function Link({ href, children }) {
  const router = useRouter();  // ❌
  // ...
}
```

---

## 4. Hooks Layer (`hooks/`)

**Purpose**: Shared stateful logic.

**Characteristics**:
- ✅ Can use all hooks
- ✅ Can contain business logic
- ✅ Can be used by components and pages
- ❌ **NO JSX**
- ❌ **NO UI rendering**

**Allowed**:
```typescript
// hooks/useDropdown.ts
export function useDropdown() {
  const [isOpen, setIsOpen] = useState(false);
  
  return {
    isOpen,
    open: () => setIsOpen(true),
    close: () => setIsOpen(false),
    toggle: () => setIsOpen(!isOpen),
  };
}
```

---

## ESLint Enforcement

### 1. **No Raw HTML in `app/`**
```json
{
  "files": ["app/**/*.tsx", "app/**/*.ts"],
  "rules": {
    "gridpilot-rules/no-raw-html-in-app": "error"
  }
}
```

**Catches**:
- `<div className="...">` in app/
- `<button style={{...}}>` in app/
- `<span onClick={...}>` in app/

### 2. **UI Element Purity**
```json
{
  "files": ["ui/**/*.tsx", "ui/**/*.ts"],
  "rules": {
    "gridpilot-rules/ui-element-purity": "error"
  }
}
```

**Catches**:
- `useState` in ui/
- `useEffect` in ui/
- `useContext` in ui/

### 3. **No Next.js in UI/Components**
```json
{
  "files": ["ui/**/*", "components/**/*"],
  "rules": {
    "gridpilot-rules/no-nextjs-imports-in-ui": "error"
  }
}
```

**Catches**:
- `import { useRouter } from 'next/navigation'`
- `import { redirect } from 'next/navigation'`
- `import Link from 'next/link'`

### 4. **Component Classification (Suggestions)**
```json
{
  "files": ["components/**/*", "ui/**/*"],
  "rules": {
    "gridpilot-rules/component-classification": "warn"
  }
}
```

**Suggests**:
- Move pure components to ui/
- Move stateful elements to components/

---

## Dependency Flow

```
app/ (pages)
  ↓ imports from
components/ (stateful)
  ↓ imports from
ui/ (pure)
  ↓ imports from
hooks/ (logic)
```

**Never**:
- app/ → hooks/ (pages don't need hooks directly)
- ui/ → components/ (ui must stay pure)
- ui/ → next/navigation (ui must be framework-agnostic)
- components/ → next/navigation (navigation should be passed from pages)

---

## Examples

### ✅ Correct Architecture

```typescript
// app/dashboard/page.tsx
export default function DashboardPage() {
  return (
    <DashboardLayout>
      <DashboardHeader />
      <DashboardStats />
    </DashboardLayout>
  );
}

// components/DashboardHeader.tsx
export function DashboardHeader() {
  const [search, setSearch] = useState('');
  
  return (
    <header>
      <SearchInput value={search} onChange={setSearch} />
      <Button onClick={handleSearch}>Search</Button>
    </header>
  );
}

// ui/SearchInput.tsx
export function SearchInput({ value, onChange }) {
  return (
    <input 
      value={value} 
      onChange={e => onChange(e.target.value)}
      className="border p-2"
    />
  );
}

// ui/Button.tsx
export function Button({ children, onClick }) {
  return (
    <button onClick={onClick} className="bg-blue-500 text-white">
      {children}
    </button>
  );
}
```

### ❌ Wrong Architecture

```typescript
// app/dashboard/page.tsx
export default function DashboardPage() {
  const [search, setSearch] = useState('');  // ❌ State in page
  
  return (
    <div className="p-6">  {/* ❌ Raw HTML */}
      <input 
        value={search}
        onChange={e => setSearch(e.target.value)}  // ❌ State logic
      />
      <button onClick={() => router.push('/search')}>  {/* ❌ Router in page */}
        Search
      </button>
    </div>
  );
}
```

---

## Benefits

1. **Reusability**: UI elements can be used anywhere
2. **Testability**: Pure functions are easy to test
3. **Maintainability**: Clear separation of concerns
4. **Performance**: No unnecessary re-renders
5. **Type Safety**: Each layer has clear contracts

---

## Migration Guide

If you have existing code that violates these rules:

1. **Extract UI elements** from app/ to ui/
2. **Move stateful logic** from ui/ to components/
3. **Remove Next.js imports** from components/ui (pass callbacks from pages)
4. **Use hooks/** for shared logic

**Example migration**:
```typescript
// Before
// app/page.tsx
export default function Page() {
  return <div className="bg-white p-6">...</div>;
}

// After
// app/page.tsx
export default function Page() {
  return <HomePage />;
}

// components/HomePage.tsx
export function HomePage() {
  return (
    <PageContainer>
      <HomeContent />
    </PageContainer>
  );
}

// ui/PageContainer.tsx
export function PageContainer({ children }) {
  return <div className="bg-white p-6">{children}</div>;
}
```

---

## Summary

| Layer | State | Next.js | HTML | Purpose |
|-------|-------|---------|------|---------|
| **app/** | ❌ No | ✅ Yes | ❌ No | Pages & layouts |
| **components/** | ✅ Yes | ❌ No | ❌ No | App components |
| **ui/** | ❌ No | ❌ No | ✅ Yes | Pure elements |
| **hooks/** | ✅ Yes | ❌ No | ❌ No | Shared logic |

**Golden Rule**: Each layer should only depend on layers below it.