Оптимизирована производительность 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,14 @@
"use client";
'use client'
import React from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import {
ArrowLeft,
Search,
Filter,
BarChart3,
Grid3X3,
List,
Download,
RotateCcw,
Layers,
} from "lucide-react";
import { SuppliesHeaderProps } from "./types";
import { ArrowLeft, Search, Filter, BarChart3, Grid3X3, List, Download, RotateCcw, Layers } from 'lucide-react'
import { useRouter } from 'next/navigation'
import React from 'react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { SuppliesHeaderProps } from './types'
export function SuppliesHeader({
viewMode,
@ -30,11 +22,11 @@ export function SuppliesHeader({
onExport,
onRefresh,
}: SuppliesHeaderProps) {
const router = useRouter();
const router = useRouter()
const handleFilterChange = (key: keyof typeof filters, value: any) => {
onFiltersChange({ ...filters, [key]: value });
};
onFiltersChange({ ...filters, [key]: value })
}
return (
<div className="space-y-6">
@ -52,12 +44,8 @@ export function SuppliesHeader({
</Button>
<div>
<h1 className="text-2xl font-bold text-white mb-1">
Расходники фулфилмента
</h1>
<p className="text-white/60 text-sm">
Управление расходными материалами фулфилмент-центра
</p>
<h1 className="text-2xl font-bold text-white mb-1">Расходники фулфилмента</h1>
<p className="text-white/60 text-sm">Управление расходными материалами фулфилмент-центра</p>
</div>
</div>
@ -94,7 +82,7 @@ export function SuppliesHeader({
<Input
placeholder="Поиск расходников..."
value={filters.search}
onChange={(e) => handleFilterChange("search", e.target.value)}
onChange={(e) => handleFilterChange('search', e.target.value)}
className="pl-10 w-64 bg-white/5 border-white/20 text-white placeholder:text-white/40 focus:border-blue-400"
/>
</div>
@ -105,26 +93,14 @@ export function SuppliesHeader({
size="sm"
onClick={onToggleFilters}
className={`border-white/20 ${
showFilters
? "bg-white/10 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
showFilters ? 'bg-white/10 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'
}`}
>
<Filter className="h-4 w-4 mr-2" />
Фильтры
{(filters.category ||
filters.status ||
filters.supplier ||
filters.lowStock) && (
{(filters.category || filters.status || filters.supplier || filters.lowStock) && (
<Badge className="ml-2 bg-blue-500/20 text-blue-300 text-xs">
{
[
filters.category,
filters.status,
filters.supplier,
filters.lowStock,
].filter(Boolean).length
}
{[filters.category, filters.status, filters.supplier, filters.lowStock].filter(Boolean).length}
</Badge>
)}
</Button>
@ -134,37 +110,31 @@ export function SuppliesHeader({
{/* Переключатель режимов просмотра */}
<div className="flex items-center bg-white/5 rounded-lg p-1">
<Button
variant={viewMode === "grid" ? "default" : "ghost"}
variant={viewMode === 'grid' ? 'default' : 'ghost'}
size="sm"
onClick={() => onViewModeChange("grid")}
onClick={() => onViewModeChange('grid')}
className={`h-8 px-3 ${
viewMode === "grid"
? "bg-blue-500 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
viewMode === 'grid' ? 'bg-blue-500 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'
}`}
>
<Grid3X3 className="h-4 w-4" />
</Button>
<Button
variant={viewMode === "list" ? "default" : "ghost"}
variant={viewMode === 'list' ? 'default' : 'ghost'}
size="sm"
onClick={() => onViewModeChange("list")}
onClick={() => onViewModeChange('list')}
className={`h-8 px-3 ${
viewMode === "list"
? "bg-blue-500 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
viewMode === 'list' ? 'bg-blue-500 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'
}`}
>
<List className="h-4 w-4" />
</Button>
<Button
variant={viewMode === "analytics" ? "default" : "ghost"}
variant={viewMode === 'analytics' ? 'default' : 'ghost'}
size="sm"
onClick={() => onViewModeChange("analytics")}
onClick={() => onViewModeChange('analytics')}
className={`h-8 px-3 ${
viewMode === "analytics"
? "bg-blue-500 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
viewMode === 'analytics' ? 'bg-blue-500 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'
}`}
>
<BarChart3 className="h-4 w-4" />
@ -172,7 +142,7 @@ export function SuppliesHeader({
</div>
{/* Группировка */}
{viewMode !== "analytics" && (
{viewMode !== 'analytics' && (
<div className="flex items-center space-x-2">
<Layers className="h-4 w-4 text-white/60" />
<select
@ -195,12 +165,10 @@ export function SuppliesHeader({
<div className="bg-white/5 rounded-lg p-4 space-y-4">
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<label className="block text-sm font-medium text-white/70 mb-2">
Категория
</label>
<label className="block text-sm font-medium text-white/70 mb-2">Категория</label>
<select
value={filters.category}
onChange={(e) => handleFilterChange("category", e.target.value)}
onChange={(e) => handleFilterChange('category', e.target.value)}
className="w-full bg-white/5 border border-white/20 rounded-md px-3 py-2 text-sm text-white focus:border-blue-400 focus:outline-none"
>
<option value="">Все категории</option>
@ -212,12 +180,10 @@ export function SuppliesHeader({
</div>
<div>
<label className="block text-sm font-medium text-white/70 mb-2">
Статус
</label>
<label className="block text-sm font-medium text-white/70 mb-2">Статус</label>
<select
value={filters.status}
onChange={(e) => handleFilterChange("status", e.target.value)}
onChange={(e) => handleFilterChange('status', e.target.value)}
className="w-full bg-white/5 border border-white/20 rounded-md px-3 py-2 text-sm text-white focus:border-blue-400 focus:outline-none"
>
<option value="">Все статусы</option>
@ -230,13 +196,11 @@ export function SuppliesHeader({
</div>
<div>
<label className="block text-sm font-medium text-white/70 mb-2">
Поставщик
</label>
<label className="block text-sm font-medium text-white/70 mb-2">Поставщик</label>
<Input
placeholder="Поставщик..."
value={filters.supplier}
onChange={(e) => handleFilterChange("supplier", e.target.value)}
onChange={(e) => handleFilterChange('supplier', e.target.value)}
className="bg-white/5 border-white/20 text-white placeholder:text-white/40 focus:border-blue-400"
/>
</div>
@ -246,9 +210,7 @@ export function SuppliesHeader({
type="checkbox"
id="lowStock"
checked={filters.lowStock}
onChange={(e) =>
handleFilterChange("lowStock", e.target.checked)
}
onChange={(e) => handleFilterChange('lowStock', e.target.checked)}
className="rounded border-white/20 bg-white/5 text-blue-500 focus:ring-blue-400"
/>
<label htmlFor="lowStock" className="text-sm text-white/70">
@ -259,5 +221,5 @@ export function SuppliesHeader({
</div>
)}
</div>
);
)
}