# ⚛️ NEXT.JS 13+ BEST PRACTICES ДЛЯ SFERA

> **Статус**: ✅ **ДЕЙСТВУЮЩИЙ**  
> **Применимо к**: Next.js 15 + TypeScript  
> **Дата создания**: 30.08.2025

---

## 🎯 КЛЮЧЕВЫЕ КОНЦЕПЦИИ

### 1. 'use client' ДИРЕКТИВА

#### ОБЯЗАТЕЛЬНО ИСПОЛЬЗОВАТЬ КОГДА:

- Используются React hooks (`useState`, `useEffect`, `useRouter`)
- Используются custom hooks (`useRoleGuard`, `useAuth`)
- Используются event handlers (`onClick`, `onSubmit`)
- Используются browser APIs (`localStorage`, `window`)

#### ПАТТЕРН ДЛЯ SFERA СТРАНИЦ:

```typescript
'use client'

import { AuthGuard } from '@/components/auth-guard'
import { ComponentDashboard } from '@/components/path/component-dashboard'
import { useRoleGuard } from '@/hooks/useRoleGuard'

export default function RolePage() {
  useRoleGuard('ROLE_NAME')

  return (
    <AuthGuard>
      <ComponentDashboard />
    </AuthGuard>
  )
}
```

### 2. APP ROUTER СТРУКТУРА

#### ФАЙЛОВАЯ СИСТЕМА:

```
src/app/
├── {role}/                    # Динамический сегмент роли
│   ├── page.tsx              # Главная роли (редирект)
│   ├── layout.tsx            # Layout для роли (опционально)
│   └── {domain}/
│       ├── page.tsx          # Главная домена
│       ├── layout.tsx        # Layout с табами
│       └── {section}/
│           ├── page.tsx      # Основная страница секции
│           └── {view}/
│               └── page.tsx  # Конкретное представление
```

#### ПРАВИЛА ИМЕНОВАНИЯ:

- **Роли**: `seller`, `fulfillment`, `wholesale`, `logistics`
- **Домены**: `supplies`, `warehouse`, `orders`, `statistics`
- **Секции**: `goods`, `consumables`, `marketplace`
- **Представления**: `cards`, `suppliers`, `new`, `receiving`

---

## 🛡️ SECURITY PATTERNS

### ЗАЩИТА СТРАНИЦ:

#### Базовый паттерн:

```typescript
'use client'

import { AuthGuard } from '@/components/auth-guard'
import { useRoleGuard } from '@/hooks/useRoleGuard'

export default function SecurePage() {
  useRoleGuard('REQUIRED_ROLE') // Проверка роли

  return (
    <AuthGuard> {/* Проверка авторизации */}
      <PageContent />
    </AuthGuard>
  )
}
```

#### Доступные роли:

- `'SELLER'` - селлеры
- `'FULFILLMENT'` - фулфилмент
- `'WHOLESALE'` - поставщики
- `'LOGIST'` - логистика

### MIDDLEWARE ЗАЩИТА:

```typescript
// middleware.ts - автоматическая проверка URL соответствия роли
export function middleware(request: NextRequest) {
  const url = request.nextUrl.pathname
  const userRole = getUserRole(request) // из JWT токена

  // Проверяем соответствие роли и URL
  if (url.startsWith('/seller/') && userRole !== 'SELLER') {
    return NextResponse.redirect('/unauthorized')
  }
  // аналогично для других ролей
}
```

---

## 🎨 LAYOUT PATTERNS

### LAYOUT С ТАБАМИ:

#### Структура файлов:

```
warehouse/
├── layout.tsx           # Tabs UI + активный таб по URL
├── fulfillment/page.tsx # /warehouse/fulfillment
├── wildberries/page.tsx # /warehouse/wildberries
└── storage/page.tsx     # /warehouse/storage
```

#### Реализация layout.tsx:

```typescript
'use client'

import { usePathname } from 'next/navigation'
import Link from 'next/link'

export default function WarehouseLayout({ children }: { children: React.ReactNode }) {
  const pathname = usePathname()

  // Автоматическое определение активного таба по URL
  const getActiveTab = () => {
    if (pathname.includes('/fulfillment')) return 'fulfillment'
    if (pathname.includes('/wildberries')) return 'wildberries'
    if (pathname.includes('/storage')) return 'storage'
    return 'fulfillment' // default
  }

  const activeTab = getActiveTab()

  return (
    <div className="space-y-6">
      {/* Tabs Header */}
      <div className="flex space-x-1 bg-gray-900 p-1 rounded-lg">
        <Link
          href="/seller/warehouse/fulfillment"
          className={`flex-1 py-2 px-4 text-center rounded-md transition-all whitespace-nowrap ${
            activeTab === 'fulfillment'
              ? 'bg-blue-600 text-white shadow-lg'
              : 'text-white/60 hover:bg-white/10'
          }`}
        >
          Склад фулфилмент
        </Link>
        {/* другие табы */}
      </div>

      {/* Tab Content */}
      {children}
    </div>
  )
}
```

### ПЕРЕИСПОЛЬЗУЕМЫЕ ХУКИ:

#### Паттерн извлечения данных:

```typescript
// hooks/useWBWarehouseData.ts
export function useWBWarehouseData() {
  const { data, loading, error } = useQuery(GET_WB_WAREHOUSE_DATA, {
    fetchPolicy: 'cache-first',
    errorPolicy: 'ignore',
  })

  return {
    data: data?.getWBWarehouseData || [],
    loading,
    error,
    refetch: () => {
      /* логика обновления */
    },
  }
}

// Использование в компонентах:
const { data, loading } = useWBWarehouseData()
```

---

## 🔄 ROUTING PATTERNS

### ПРОГРАММНАЯ НАВИГАЦИЯ:

```typescript
import { useRouter } from 'next/navigation'

function NavigationComponent() {
  const router = useRouter()

  // ✅ Правильно: используем новые пути
  const handleNavigate = () => {
    router.push('/seller/warehouse/fulfillment')
  }

  // ❌ Неправильно: старые пути
  // router.push('/wb-warehouse')
}
```

### ОПРЕДЕЛЕНИЕ АКТИВНЫХ СОСТОЯНИЙ:

```typescript
import { usePathname } from 'next/navigation'

function ActiveStateComponent() {
  const pathname = usePathname()

  // ✅ Правильно: проверяем новые пути
  const isActive = pathname.startsWith('/seller/warehouse')

  // ✅ Конкретная секция:
  const isFulfillmentActive = pathname.includes('/warehouse/fulfillment')
}
```

---

## 📦 COMPONENT PATTERNS

### МОДУЛЬНАЯ АРХИТЕКТУРА:

#### Структура папки компонента:

```
ComponentName/
├── index.tsx              # Основной компонент
├── ComponentName.types.ts # TypeScript типы
├── ComponentName.hooks.ts # Custom hooks
├── ComponentName.utils.ts # Утилиты
└── components/            # Подкомпоненты
    ├── Header.tsx
    ├── Content.tsx
    └── Footer.tsx
```

#### Основной компонент:

```typescript
'use client'

import { ComponentNameProvider } from './ComponentName.context'
import { useComponentName } from './ComponentName.hooks'
import { Header } from './components/Header'
import { Content } from './components/Content'

export function ComponentName() {
  return (
    <ComponentNameProvider>
      <div className="space-y-6">
        <Header />
        <Content />
      </div>
    </ComponentNameProvider>
  )
}
```

---

## 🚨 ОШИБКИ И РЕШЕНИЯ

### ПРОБЛЕМА 1: "useRoleGuard from server"

**Ошибка:**

```
Error: Attempted to call useRoleGuard() from the server but useRoleGuard is on the client
```

**Причина**: Отсутствует 'use client' в page.tsx

**Решение:**

```typescript
'use client' // Добавить в начало файла

import { useRoleGuard } from '@/hooks/useRoleGuard'
```

### ПРОБЛЕМА 2: Redirect loops

**Ошибка**: Бесконечные редиректы между путями

**Причина**: Одновременно существуют старые и новые пути

**Решение**: Удалить старые директории:

```bash
rm -rf src/app/fulfillment-supplies/
rm -rf src/app/fulfillment-warehouse/
```

### ПРОБЛЕМА 3: Потеря активных состояний

**Ошибка**: Табы не показывают активное состояние

**Причина**: Проверка pathname на старые пути

**Решение**: Обновить логику проверки:

```typescript
// ✅ До:
const isActive = pathname.startsWith('/fulfillment-supplies')

// ✅ После:
const isActive = pathname.startsWith('/fulfillment/supplies')
```

---

## 📋 CHECKLIST ДЛЯ НОВЫХ КОМПОНЕНТОВ

### ПЕРЕД СОЗДАНИЕМ:

- [ ] Прочитал MODULAR_ARCHITECTURE_PATTERN.md
- [ ] Определил нужность модульной архитектуры
- [ ] Выбрал правильный URL путь по формуле `/{role}/{domain}/{section}/{view}`
- [ ] Добавил 'use client' если используются hooks

### ПРИ СОЗДАНИИ:

- [ ] Добавил useRoleGuard с правильной ролью
- [ ] Обернул в AuthGuard для проверки авторизации
- [ ] Использовал существующие компоненты и хуки
- [ ] Следовал naming conventions

### ПОСЛЕ СОЗДАНИЯ:

- [ ] Проверил `npm run typecheck`
- [ ] Проверил `npm run lint`
- [ ] Протестировал в браузере
- [ ] Убедился что navigation работает

---

## 🎯 ЗАКЛЮЧЕНИЕ

**NEXT.JS 13+ В SFERA: СТАБИЛЬНАЯ PRODUCTION-READY СИСТЕМА**

🎯 **ПРИНЦИПЫ:**

- 'use client' для всех interactive компонентов
- URL-based routing вместо внутренних состояний
- Модульная архитектура для сложных компонентов
- Систематическая структура путей по ролям

🚀 **РЕЗУЛЬТАТ:**

- 100% совместимость с Next.js 15
- Отсутствие server/client конфликтов
- SEO-оптимизированные URL
- Простая навигация и maintenance

**Данные практики обеспечивают стабильность и масштабируемость SFERA на Next.js 13+.**

---

_Создано: 30.08.2025_  
_На основе реального опыта разработки SFERA_
