Оптимизирована производительность 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

@ -38,43 +38,37 @@ export class MarketplaceService {
*/
async validateWildberriesApiKey(apiKey: string): Promise<MarketplaceValidationResult> {
try {
console.log('🔵 Starting Wildberries validation for key:', apiKey.substring(0, 20) + '...');
console.warn('🔵 Starting Wildberries validation for key:', apiKey.substring(0, 20) + '...')
// Сначала проверяем валидность ключа через ping (быстрее)
console.log('📡 Making ping request to:', `${this.wbApiUrl}/ping`);
const pingResponse = await axios.get(
`${this.wbApiUrl}/ping`,
{
headers: {
'Authorization': `Bearer ${apiKey}`
},
timeout: 5000
}
)
console.log('📡 Ping response:', {
console.warn('📡 Making ping request to:', `${this.wbApiUrl}/ping`)
const pingResponse = await axios.get(`${this.wbApiUrl}/ping`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
timeout: 5000,
})
console.warn('📡 Ping response:', {
status: pingResponse.status,
data: pingResponse.data
});
data: pingResponse.data,
})
if (pingResponse.status !== 200 || pingResponse.data?.Status !== 'OK') {
return {
isValid: false,
message: 'API ключ Wildberries невалиден'
message: 'API ключ Wildberries невалиден',
}
}
// Если ping прошёл, получаем информацию о продавце
const response = await axios.get(
`${this.wbApiUrl}/api/v1/seller-info`,
{
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
timeout: 10000
}
)
const response = await axios.get(`${this.wbApiUrl}/api/v1/seller-info`, {
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
timeout: 10000,
})
if (response.status === 200 && response.data) {
const sellerData = response.data
@ -85,60 +79,59 @@ export class MarketplaceService {
data: {
sellerId: sellerData.sid, // sid - это уникальный ID продавца
sellerName: sellerData.name, // обычное наименование продавца
tradeMark: sellerData.tradeMark // торговое наименование продавца
}
tradeMark: sellerData.tradeMark, // торговое наименование продавца
},
}
}
return {
isValid: false,
message: 'Не удалось получить информацию о продавце Wildberries'
message: 'Не удалось получить информацию о продавце Wildberries',
}
} catch (error) {
console.error('🔴 Wildberries API validation error:', error)
if (axios.isAxiosError(error)) {
console.log('🔴 Axios error details:', {
console.warn('🔴 Axios error details:', {
status: error.response?.status,
statusText: error.response?.statusText,
data: error.response?.data,
message: error.message,
code: error.code
});
code: error.code,
})
if (error.response?.status === 401) {
return {
isValid: false,
message: 'Неверный API ключ Wildberries'
message: 'Неверный API ключ Wildberries',
}
}
if (error.response?.status === 403) {
return {
isValid: false,
message: 'Доступ запрещён. Проверьте права API ключа Wildberries'
message: 'Доступ запрещён. Проверьте права API ключа Wildberries',
}
}
if (error.response?.status === 429) {
return {
isValid: false,
message: 'Слишком много запросов к Wildberries API. Попробуйте позже'
message: 'Слишком много запросов к Wildberries API. Попробуйте позже',
}
}
if (error.code === 'ECONNABORTED') {
return {
isValid: false,
message: 'Превышено время ожидания ответа от Wildberries API'
message: 'Превышено время ожидания ответа от Wildberries API',
}
}
}
return {
isValid: false,
message: 'Ошибка при проверке API ключа Wildberries'
message: 'Ошибка при проверке API ключа Wildberries',
}
}
}
@ -152,7 +145,7 @@ export class MarketplaceService {
if (!clientId) {
return {
isValid: false,
message: 'Для Ozon API требуется Client-Id'
message: 'Для Ozon API требуется Client-Id',
}
}
@ -164,10 +157,10 @@ export class MarketplaceService {
headers: {
'Api-Key': apiKey,
'Client-Id': clientId,
'Content-Type': 'application/json'
'Content-Type': 'application/json',
},
timeout: 10000
}
timeout: 10000,
},
)
if (response.status === 200 && response.data?.result) {
@ -179,45 +172,44 @@ export class MarketplaceService {
data: {
sellerId: sellerData.id?.toString(),
sellerName: sellerData.name,
status: sellerData.status
}
status: sellerData.status,
},
}
}
return {
isValid: false,
message: 'Не удалось получить информацию о продавце Ozon'
message: 'Не удалось получить информацию о продавце Ozon',
}
} catch (error) {
console.error('Ozon API validation error:', error)
if (axios.isAxiosError(error)) {
if (error.response?.status === 401) {
return {
isValid: false,
message: 'Неверный API ключ или Client-Id для Ozon'
message: 'Неверный API ключ или Client-Id для Ozon',
}
}
if (error.response?.status === 403) {
return {
isValid: false,
message: 'Доступ запрещён. Проверьте права API ключа Ozon'
message: 'Доступ запрещён. Проверьте права API ключа Ozon',
}
}
if (error.code === 'ECONNABORTED') {
return {
isValid: false,
message: 'Превышено время ожидания ответа от Ozon API'
message: 'Превышено время ожидания ответа от Ozon API',
}
}
}
return {
isValid: false,
message: 'Ошибка при проверке API ключа Ozon'
message: 'Ошибка при проверке API ключа Ozon',
}
}
}
@ -228,7 +220,7 @@ export class MarketplaceService {
async validateApiKey(
marketplace: 'WILDBERRIES' | 'OZON',
apiKey: string,
clientId?: string
clientId?: string,
): Promise<MarketplaceValidationResult> {
switch (marketplace) {
case 'WILDBERRIES':
@ -238,7 +230,7 @@ export class MarketplaceService {
default:
return {
isValid: false,
message: 'Неподдерживаемый тип маркетплейса'
message: 'Неподдерживаемый тип маркетплейса',
}
}
}
@ -262,4 +254,4 @@ export class MarketplaceService {
return false
}
}
}
}