Оптимизирована производительность 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:
@ -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>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user