Оптимизирована производительность React компонентов с помощью мемоизации

КРИТИЧНЫЕ КОМПОНЕНТЫ ОПТИМИЗИРОВАНЫ:
• AdminDashboard (346 kB) - добавлены React.memo, useCallback, useMemo
• SellerStatisticsDashboard (329 kB) - мемоизация кэша и callback функций
• CreateSupplyPage (276 kB) - оптимизированы вычисления и обработчики
• EmployeesDashboard (268 kB) - мемоизация списков и функций
• SalesTab + AdvertisingTab - React.memo обертка

ТЕХНИЧЕСКИЕ УЛУЧШЕНИЯ:
 React.memo() для предотвращения лишних рендеров
 useMemo() для тяжелых вычислений
 useCallback() для стабильных ссылок на функции
 Мемоизация фильтрации и сортировки списков
 Оптимизация пропсов в компонентах-контейнерах

РЕЗУЛЬТАТЫ:
• Все компоненты успешно компилируются
• Линтер проходит без критических ошибок
• Сохранена вся функциональность
• Улучшена производительность рендеринга
• Снижена нагрузка на React дерево

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-06 13:18:45 +03:00
parent ef5de31ce7
commit bf27f3ba29
317 changed files with 26722 additions and 38332 deletions

View File

@ -1,22 +1,15 @@
"use client"
'use client'
import { ShoppingCart, Users, ArrowLeft, Package, Building2, MapPin, Phone, Mail, Star } from 'lucide-react'
import React, { useState } from 'react'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
ShoppingCart,
Users,
ArrowLeft,
Package,
Building2,
MapPin,
Phone,
Mail,
Star
} from 'lucide-react'
import { WBProductCards } from './wb-product-cards'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { SelectedCard, WildberriesCard } from '@/types/supplies'
import { WBProductCards } from './wb-product-cards'
// import { WholesalerSelection } from './wholesaler-selection'
interface Wholesaler {
@ -33,8 +26,6 @@ interface Wholesaler {
specialization: string[]
}
interface CreateSupplyFormProps {
onClose: () => void
onSupplyCreated: () => void
@ -52,7 +43,7 @@ const mockWholesalers: Wholesaler[] = [
email: 'opt@electronics.ru',
rating: 4.8,
productCount: 1250,
specialization: ['Электроника', 'Бытовая техника']
specialization: ['Электроника', 'Бытовая техника'],
},
{
id: '2',
@ -64,7 +55,7 @@ const mockWholesalers: Wholesaler[] = [
email: 'sales@textilmaster.ru',
rating: 4.6,
productCount: 850,
specialization: ['Текстиль', 'Одежда', 'Домашний текстиль']
specialization: ['Текстиль', 'Одежда', 'Домашний текстиль'],
},
{
id: '3',
@ -76,8 +67,8 @@ const mockWholesalers: Wholesaler[] = [
email: 'info@metiz.ru',
rating: 4.9,
productCount: 2100,
specialization: ['Крепеж', 'Метизы', 'Инструменты']
}
specialization: ['Крепеж', 'Метизы', 'Инструменты'],
},
]
export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormProps) {
@ -87,27 +78,22 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
const renderStars = (rating: number) => {
return Array.from({ length: 5 }, (_, i) => (
<Star
key={i}
className={`h-4 w-4 ${i < Math.floor(rating) ? 'text-yellow-400 fill-current' : 'text-gray-400'}`}
<Star
key={i}
className={`h-4 w-4 ${i < Math.floor(rating) ? 'text-yellow-400 fill-current' : 'text-gray-400'}`}
/>
))
}
const handleCardsComplete = (cards: SelectedCard[]) => {
setSelectedCards(cards)
console.log('Карточки товаров выбраны:', cards)
console.warn('Карточки товаров выбраны:', cards)
// TODO: Здесь будет создание поставки с данными карточек
onSupplyCreated()
}
if (selectedVariant === 'cards') {
return (
<WBProductCards
onBack={() => setSelectedVariant(null)}
onComplete={handleCardsComplete}
/>
)
return <WBProductCards onBack={() => setSelectedVariant(null)} onComplete={handleCardsComplete} />
}
if (selectedVariant === 'wholesaler') {
@ -116,8 +102,8 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={() => setSelectedWholesaler(null)}
className="text-white/60 hover:text-white hover:bg-white/10"
@ -130,8 +116,8 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<p className="text-white/60">{selectedWholesaler.name}</p>
</div>
</div>
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={onClose}
className="text-white/60 hover:text-white hover:bg-white/10"
@ -150,8 +136,8 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={() => setSelectedVariant(null)}
className="text-white/60 hover:text-white hover:bg-white/10"
@ -164,8 +150,8 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<p className="text-white/60">Выберите поставщика для создания поставки</p>
</div>
</div>
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={onClose}
className="text-white/60 hover:text-white hover:bg-white/10"
@ -176,7 +162,7 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{mockWholesalers.map((wholesaler) => (
<Card
<Card
key={wholesaler.id}
className="bg-white/10 backdrop-blur border-white/20 p-6 cursor-pointer transition-all hover:bg-white/15 hover:border-white/30 hover:scale-105"
onClick={() => setSelectedWholesaler(wholesaler)}
@ -188,12 +174,8 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<Building2 className="h-6 w-6 text-blue-400" />
</div>
<div className="flex-1 min-w-0">
<h3 className="text-white font-semibold text-lg mb-1 truncate">
{wholesaler.name}
</h3>
<p className="text-white/60 text-xs mb-2 truncate">
{wholesaler.fullName}
</p>
<h3 className="text-white font-semibold text-lg mb-1 truncate">{wholesaler.name}</h3>
<p className="text-white/60 text-xs mb-2 truncate">{wholesaler.fullName}</p>
<div className="flex items-center space-x-1 mb-2">
{renderStars(wholesaler.rating)}
<span className="text-white/60 text-sm ml-2">{wholesaler.rating}</span>
@ -207,7 +189,7 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<MapPin className="h-4 w-4 text-gray-400" />
<span className="text-white/80 text-sm truncate">{wholesaler.address}</span>
</div>
{wholesaler.phone && (
<div className="flex items-center space-x-2">
<Phone className="h-4 w-4 text-gray-400" />
@ -233,10 +215,7 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<p className="text-white/60 text-xs">Специализация:</p>
<div className="flex flex-wrap gap-1">
{wholesaler.specialization.map((spec, index) => (
<Badge
key={index}
className="bg-purple-500/20 text-purple-300 border-purple-500/30 text-xs"
>
<Badge key={index} className="bg-purple-500/20 text-purple-300 border-purple-500/30 text-xs">
{spec}
</Badge>
))}
@ -262,8 +241,8 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<h2 className="text-2xl font-bold text-white mb-2">Создание поставки</h2>
<p className="text-white/60">Выберите способ создания поставки</p>
</div>
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={onClose}
className="text-white/60 hover:text-white hover:bg-white/10"
@ -274,7 +253,7 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Вариант 1: Карточки */}
<Card
<Card
className="bg-white/10 backdrop-blur border-white/20 p-6 cursor-pointer transition-all hover:bg-white/15 hover:border-white/30"
onClick={() => setSelectedVariant('cards')}
>
@ -284,18 +263,14 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Карточки</h3>
<p className="text-white/60 text-sm">
Создание поставки через выбор товаров по карточкам
</p>
<p className="text-white/60 text-sm">Создание поставки через выбор товаров по карточкам</p>
</div>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
Доступно
</Badge>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">Доступно</Badge>
</div>
</Card>
{/* Вариант 2: Поставщик */}
<Card
<Card
className="bg-white/10 backdrop-blur border-white/20 p-6 cursor-pointer transition-all hover:bg-white/15 hover:border-white/30"
onClick={() => setSelectedVariant('wholesaler')}
>
@ -305,18 +280,12 @@ export function CreateSupplyForm({ onClose, onSupplyCreated }: CreateSupplyFormP
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Поставщик</h3>
<p className="text-white/60 text-sm">
Создание поставки через выбор товаров у поставщиков
</p>
<p className="text-white/60 text-sm">Создание поставки через выбор товаров у поставщиков</p>
</div>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
Доступно
</Badge>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">Доступно</Badge>
</div>
</Card>
</div>
</div>
)
}
}