feat: завершить полную миграцию V1→V2 с модульной архитектурой и документацией

АРХИТЕКТУРНЫЕ ИЗМЕНЕНИЯ:
- Полная миграция на URL структуру /{role}/{domain}/{section}/{view}
- Удаление всех старых директорий (/fulfillment-supplies/, /fulfillment-warehouse/, etc.)
- Модульная архитектура seller warehouse с URL-based routing
- Система rollback через комментарии для безопасных изменений

НОВЫЕ КОМПОНЕНТЫ И СТРАНИЦЫ:
- Создание всех недостающих страниц для FULFILLMENT, SELLER ролей
- Модульный layout для seller warehouse с 3 табами
- Извлечение переиспользуемого хука useWBWarehouseData

ИСПРАВЛЕНИЯ БЕЗОПАСНОСТИ:
- Добавление 'use client' директив во все WHOLESALE и LOGISTICS страницы
- Исправление отсутствующих security guards (useRoleGuard + AuthGuard)
- Обновление navigation конфигураций для всех ролей

ДОКУМЕНТАЦИЯ:
- Создание MIGRATION_GUIDE_V1_TO_V2.md: 8-этапное руководство по миграции
- Создание NEXTJS_BEST_PRACTICES.md: паттерны для Next.js 13+ в SFERA
- Обновление URL_ROUTING_RULES.md с seller warehouse и rollback системой
- Обновление SIDEBAR_ARCHITECTURE_IMPLEMENTATION.md с новыми метриками
- Обновление INDEX.md с новыми документами Development раздела

ИСПРАВЛЕНИЯ ESLINT:
- Удаление неиспользуемых импортов и переменных
- Исправление import/order ошибок в модульных компонентах
- Исправление react/no-unescaped-entities
- Перенос длинных строк для соответствия max-len

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-30 22:37:15 +03:00
parent b40ac083ab
commit 3f0cc933fc
76 changed files with 2060 additions and 609 deletions

View File

@ -0,0 +1,124 @@
'use client'
import { Home, Warehouse, Package } from 'lucide-react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { AuthGuard } from '@/components/auth-guard'
import { Sidebar } from '@/components/dashboard/sidebar'
import { useRoleGuard } from '@/hooks/useRoleGuard'
import { useSidebar } from '@/hooks/useSidebar'
// Компонент Breadcrumbs
function Breadcrumbs({ pathname }: { pathname: string }) {
const segments = pathname.split('/').filter(Boolean)
const breadcrumbs = [{ name: 'Главная', href: '/dashboard', icon: Home }]
if (segments[0] === 'seller' && segments[1] === 'warehouse') {
breadcrumbs.push({ name: 'Склад', href: '/seller/warehouse', icon: Warehouse })
if (segments[2]) {
const sectionMap: Record<string, string> = {
fulfillment: 'Склад фулфилмент',
wildberries: 'Склад Wildberries',
storage: 'Мой склад',
}
const section = sectionMap[segments[2]]
if (section) {
breadcrumbs.push({
name: section,
href: `/seller/warehouse/${segments[2]}`,
icon: Package,
})
}
}
}
return (
<nav className="flex items-center space-x-2 text-sm text-white/60 mb-6">
{breadcrumbs.map((crumb, index) => (
<div key={crumb.href} className="flex items-center">
{index > 0 && <span className="mx-2 text-white/40">/</span>}
<Link href={crumb.href} className="flex items-center gap-1 hover:text-white transition-colors">
<crumb.icon className="h-4 w-4" />
{crumb.name}
</Link>
</div>
))}
</nav>
)
}
export default function SellerWarehouseLayout({ children }: { children: React.ReactNode }) {
useRoleGuard('SELLER')
const { getSidebarMargin } = useSidebar()
const pathname = usePathname()
// Определяем активный таб
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 (
<AuthGuard>
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main className={`flex-1 ${getSidebarMargin()} px-6 py-4 overflow-hidden transition-all duration-300`}>
<div className="h-full w-full flex flex-col space-y-4">
{/* Breadcrumbs */}
<Breadcrumbs pathname={pathname} />
{/* Табы навигация - точно как в WBWarehouseDashboard */}
<div className="mb-6">
<div className="grid grid-cols-3 w-full max-w-md bg-white/5 border border-white/10 rounded-lg p-1">
<Link
href="/seller/warehouse/fulfillment"
className={`flex items-center justify-center gap-2 text-sm font-medium
transition-all duration-200 rounded-md px-3 py-2 whitespace-nowrap ${
activeTab === 'fulfillment'
? 'bg-blue-600 text-white shadow-lg'
: 'text-white/60 hover:text-white hover:bg-white/5'
}`}
>
Склад фулфилмент
</Link>
<Link
href="/seller/warehouse/wildberries"
className={`flex items-center justify-center gap-2 text-sm font-medium
transition-all duration-200 rounded-md px-3 py-2 ${
activeTab === 'wildberries'
? 'bg-blue-600 text-white shadow-lg'
: 'text-white/60 hover:text-white hover:bg-white/5'
}`}
>
Склад Wildberries
</Link>
<Link
href="/seller/warehouse/storage"
className={`flex items-center justify-center gap-2 text-sm font-medium
transition-all duration-200 rounded-md px-3 py-2 ${
activeTab === 'storage'
? 'bg-blue-600 text-white shadow-lg'
: 'text-white/60 hover:text-white hover:bg-white/5'
}`}
>
Мой склад
</Link>
</div>
</div>
{/* Контент страницы */}
<div className="flex-1 overflow-hidden min-h-0">{children}</div>
</div>
</main>
</div>
</AuthGuard>
)
}