Оптимизирована производительность 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,16 +1,11 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import { Plus, Minus, Eye, Heart, ShoppingCart } from 'lucide-react'
|
||||
import React from 'react'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import {
|
||||
Plus,
|
||||
Minus,
|
||||
Eye,
|
||||
Heart,
|
||||
ShoppingCart
|
||||
} from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
|
||||
import { WholesalerProduct } from './types'
|
||||
|
||||
@ -21,15 +16,8 @@ interface ProductCardProps {
|
||||
formatCurrency: (amount: number) => string
|
||||
}
|
||||
|
||||
export function ProductCard({
|
||||
product,
|
||||
selectedQuantity,
|
||||
onQuantityChange,
|
||||
formatCurrency
|
||||
}: ProductCardProps) {
|
||||
const discountedPrice = product.discount
|
||||
? product.price * (1 - product.discount / 100)
|
||||
: product.price
|
||||
export function ProductCard({ product, selectedQuantity, onQuantityChange, formatCurrency }: ProductCardProps) {
|
||||
const discountedPrice = product.discount ? product.price * (1 - product.discount / 100) : product.price
|
||||
|
||||
const handleQuantityChange = (newQuantity: number) => {
|
||||
const clampedQuantity = Math.max(0, Math.min(product.quantity, newQuantity))
|
||||
@ -44,16 +32,14 @@ export function ProductCard({
|
||||
alt={product.name}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
|
||||
/>
|
||||
|
||||
|
||||
{/* Количество в наличии */}
|
||||
<div className="absolute top-2 right-2">
|
||||
<Badge className={`${
|
||||
product.quantity > 50
|
||||
? 'bg-green-500/80'
|
||||
: product.quantity > 10
|
||||
? 'bg-yellow-500/80'
|
||||
: 'bg-red-500/80'
|
||||
} text-white border-0 backdrop-blur text-xs`}>
|
||||
<Badge
|
||||
className={`${
|
||||
product.quantity > 50 ? 'bg-green-500/80' : product.quantity > 10 ? 'bg-yellow-500/80' : 'bg-red-500/80'
|
||||
} text-white border-0 backdrop-blur text-xs`}
|
||||
>
|
||||
{product.quantity}
|
||||
</Badge>
|
||||
</div>
|
||||
@ -61,50 +47,48 @@ export function ProductCard({
|
||||
{/* Скидка */}
|
||||
{product.discount && (
|
||||
<div className="absolute top-2 left-2">
|
||||
<Badge className="bg-red-500/80 text-white border-0 backdrop-blur text-xs">
|
||||
-{product.discount}%
|
||||
</Badge>
|
||||
<Badge className="bg-red-500/80 text-white border-0 backdrop-blur text-xs">-{product.discount}%</Badge>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Overlay с кнопками */}
|
||||
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||
<div className="flex space-x-2">
|
||||
<Button size="sm" variant="secondary" className="bg-white/20 backdrop-blur text-white border-white/30 hover:bg-white/30">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
className="bg-white/20 backdrop-blur text-white border-white/30 hover:bg-white/30"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary" className="bg-white/20 backdrop-blur text-white border-white/30 hover:bg-white/30">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
className="bg-white/20 backdrop-blur text-white border-white/30 hover:bg-white/30"
|
||||
>
|
||||
<Heart className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="p-3 space-y-3">
|
||||
{/* Заголовок и бренд */}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
{product.brand && (
|
||||
<Badge className="bg-gray-500/20 text-gray-300 border-gray-500/30 text-xs">
|
||||
{product.brand}
|
||||
</Badge>
|
||||
<Badge className="bg-gray-500/20 text-gray-300 border-gray-500/30 text-xs">{product.brand}</Badge>
|
||||
)}
|
||||
<div className="flex items-center space-x-1">
|
||||
{product.isNew && (
|
||||
<Badge className="bg-green-500/20 text-green-300 border-green-500/30 text-xs">
|
||||
NEW
|
||||
</Badge>
|
||||
<Badge className="bg-green-500/20 text-green-300 border-green-500/30 text-xs">NEW</Badge>
|
||||
)}
|
||||
{product.isBestseller && (
|
||||
<Badge className="bg-orange-500/20 text-orange-300 border-orange-500/30 text-xs">
|
||||
HIT
|
||||
</Badge>
|
||||
<Badge className="bg-orange-500/20 text-orange-300 border-orange-500/30 text-xs">HIT</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-white font-semibold text-sm mb-1 line-clamp-2 leading-tight">
|
||||
{product.name}
|
||||
</h3>
|
||||
<h3 className="text-white font-semibold text-sm mb-1 line-clamp-2 leading-tight">{product.name}</h3>
|
||||
</div>
|
||||
|
||||
{/* Основная характеристика */}
|
||||
@ -116,13 +100,9 @@ export function ProductCard({
|
||||
{/* Цена */}
|
||||
<div className="pt-2 border-t border-white/10">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="text-white font-bold text-lg">
|
||||
{formatCurrency(discountedPrice)}
|
||||
</div>
|
||||
<div className="text-white font-bold text-lg">{formatCurrency(discountedPrice)}</div>
|
||||
{product.discount && (
|
||||
<div className="text-white/40 text-sm line-through">
|
||||
{formatCurrency(product.price)}
|
||||
</div>
|
||||
<div className="text-white/40 text-sm line-through">{formatCurrency(product.price)}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -160,7 +140,7 @@ export function ProductCard({
|
||||
>
|
||||
<Plus className="h-3 w-3" />
|
||||
</Button>
|
||||
|
||||
|
||||
{selectedQuantity > 0 && (
|
||||
<Badge className="bg-gradient-to-r from-purple-500 to-pink-500 text-white border-0 text-xs ml-auto">
|
||||
<ShoppingCart className="h-3 w-3 mr-1" />
|
||||
@ -180,4 +160,4 @@ export function ProductCard({
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user