Оптимизирована производительность 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,14 +1,14 @@
"use client"
'use client'
import { useState, useEffect } from "react"
import { PhoneStep } from "./phone-step"
import { SmsStep } from "./sms-step"
import { CabinetSelectStep } from "./cabinet-select-step"
import { InnStep } from "./inn-step"
import { MarketplaceApiStep } from "./marketplace-api-step"
import { ConfirmationStep } from "./confirmation-step"
import { CheckCircle } from "lucide-react"
import { CheckCircle } from 'lucide-react'
import { useState, useEffect } from 'react'
import { CabinetSelectStep } from './cabinet-select-step'
import { ConfirmationStep } from './confirmation-step'
import { InnStep } from './inn-step'
import { MarketplaceApiStep } from './marketplace-api-step'
import { PhoneStep } from './phone-step'
import { SmsStep } from './sms-step'
type AuthStep = 'phone' | 'sms' | 'cabinet-select' | 'inn' | 'marketplace-api' | 'confirmation' | 'complete'
type CabinetType = 'fulfillment' | 'seller' | 'logist' | 'wholesale'
@ -58,7 +58,7 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
ozonApiKey: '',
ozonApiValidation: null,
isAuthenticated: false,
partnerCode: partnerCode
partnerCode: partnerCode,
})
// При завершении авторизации инициируем проверку и перенаправление
@ -68,26 +68,26 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
// Принудительно перенаправляем в дашборд
window.location.href = '/dashboard'
}, 2000) // Задержка для показа сообщения о завершении
return () => clearTimeout(timer)
}
}, [step])
const handlePhoneNext = (phone: string) => {
setAuthData(prev => ({ ...prev, phone }))
setAuthData((prev) => ({ ...prev, phone }))
setStep('sms')
}
const handleSmsNext = async (smsCode: string) => {
setAuthData(prev => ({ ...prev, smsCode, isAuthenticated: true }))
setAuthData((prev) => ({ ...prev, smsCode, isAuthenticated: true }))
// SMS код уже проверен в SmsStep компоненте
// Просто переходим к следующему шагу
setStep('cabinet-select')
}
const handleCabinetNext = (cabinetType: CabinetType) => {
setAuthData(prev => ({ ...prev, cabinetType }))
setAuthData((prev) => ({ ...prev, cabinetType }))
if (cabinetType === 'fulfillment' || cabinetType === 'logist' || cabinetType === 'wholesale') {
setStep('inn')
} else {
@ -96,26 +96,26 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
}
const handleInnNext = (inn: string, organizationData?: OrganizationData) => {
setAuthData(prev => ({
...prev,
setAuthData((prev) => ({
...prev,
inn,
organizationData: organizationData || null
organizationData: organizationData || null,
}))
setStep('confirmation')
}
const handleMarketplaceApiNext = (apiData: {
const handleMarketplaceApiNext = (apiData: {
wbApiKey?: string
wbApiValidation?: ApiKeyValidation
ozonApiKey?: string
ozonApiValidation?: ApiKeyValidation
}) => {
setAuthData(prev => ({
...prev,
setAuthData((prev) => ({
...prev,
wbApiKey: apiData.wbApiKey || '',
wbApiValidation: apiData.wbApiValidation || null,
ozonApiKey: apiData.ozonApiKey || '',
ozonApiValidation: apiData.ozonApiValidation || null
ozonApiValidation: apiData.ozonApiValidation || null,
}))
setStep('confirmation')
}
@ -141,7 +141,11 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
}
const handleConfirmationBack = () => {
if (authData.cabinetType === 'fulfillment' || authData.cabinetType === 'logist' || authData.cabinetType === 'wholesale') {
if (
authData.cabinetType === 'fulfillment' ||
authData.cabinetType === 'logist' ||
authData.cabinetType === 'wholesale'
) {
setStep('inn')
} else {
setStep('marketplace-api')
@ -163,7 +167,7 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
<div className="particle"></div>
<div className="particle"></div>
</div>
<div className="text-center text-white max-w-md relative z-10">
<div className="bg-white/10 backdrop-blur rounded-2xl p-8 border border-white/20 glow-purple">
<CheckCircle className="h-20 w-20 mx-auto mb-6 text-green-400 animate-pulse" />
@ -172,12 +176,13 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
<div className="bg-white/5 rounded-lg p-4 mb-6">
<p className="text-white/60 text-sm mb-2">Тип кабинета:</p>
<p className="text-white font-medium">
{
authData.cabinetType === 'fulfillment' ? 'Фулфилмент' :
authData.cabinetType === 'logist' ? 'Логистика' :
authData.cabinetType === 'wholesale' ? 'Поставщик' :
'Селлер'
}
{authData.cabinetType === 'fulfillment'
? 'Фулфилмент'
: authData.cabinetType === 'logist'
? 'Логистика'
: authData.cabinetType === 'wholesale'
? 'Поставщик'
: 'Селлер'}
</p>
</div>
<div className="flex items-center justify-center gap-2 text-white/60 text-sm">
@ -193,30 +198,11 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
return (
<>
{step === 'phone' && <PhoneStep onNext={handlePhoneNext} />}
{step === 'sms' && (
<SmsStep
phone={authData.phone}
onNext={handleSmsNext}
onBack={handleSmsBack}
/>
)}
{step === 'cabinet-select' && (
<CabinetSelectStep
onNext={handleCabinetNext}
onBack={handleCabinetBack}
/>
)}
{step === 'inn' && (
<InnStep
onNext={handleInnNext}
onBack={handleInnBack}
/>
)}
{step === 'sms' && <SmsStep phone={authData.phone} onNext={handleSmsNext} onBack={handleSmsBack} />}
{step === 'cabinet-select' && <CabinetSelectStep onNext={handleCabinetNext} onBack={handleCabinetBack} />}
{step === 'inn' && <InnStep onNext={handleInnNext} onBack={handleInnBack} />}
{step === 'marketplace-api' && (
<MarketplaceApiStep
onNext={handleMarketplaceApiNext}
onBack={handleMarketplaceApiBack}
/>
<MarketplaceApiStep onNext={handleMarketplaceApiNext} onBack={handleMarketplaceApiBack} />
)}
{step === 'confirmation' && (
<ConfirmationStep
@ -228,7 +214,7 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
wbApiKey: authData.wbApiKey || undefined,
wbApiValidation: authData.wbApiValidation || undefined,
ozonApiKey: authData.ozonApiKey || undefined,
ozonApiValidation: authData.ozonApiValidation || undefined
ozonApiValidation: authData.ozonApiValidation || undefined,
}}
onConfirm={handleConfirmation}
onBack={handleConfirmationBack}
@ -242,23 +228,24 @@ export function AuthFlow({ partnerCode }: AuthFlowProps = {}) {
</div>
</div>
<div className="space-y-2">
<h2 className="text-2xl font-bold text-gray-900">
Регистрация завершена!
</h2>
<h2 className="text-2xl font-bold text-gray-900">Регистрация завершена!</h2>
<p className="text-gray-600">
Ваш {authData.cabinetType === 'fulfillment' ? 'фулфилмент кабинет' :
authData.cabinetType === 'seller' ? 'селлер кабинет' :
authData.cabinetType === 'logist' ? 'логистический кабинет' : 'оптовый кабинет'}
{' '}успешно создан
Ваш{' '}
{authData.cabinetType === 'fulfillment'
? 'фулфилмент кабинет'
: authData.cabinetType === 'seller'
? 'селлер кабинет'
: authData.cabinetType === 'logist'
? 'логистический кабинет'
: 'оптовый кабинет'}{' '}
успешно создан
</p>
</div>
<div className="animate-pulse">
<p className="text-sm text-gray-500">
Переход в личный кабинет...
</p>
<p className="text-sm text-gray-500">Переход в личный кабинет...</p>
</div>
</div>
)}
</>
)
}
}