import React, { memo, useState, useEffect } from 'react'; import CatalogProductCard from './CatalogProductCard'; import CatalogProductCardSkeleton from './CatalogProductCardSkeleton'; import { useArticleImage } from '@/hooks/useArticleImage'; import { useCatalogPrices } from '@/hooks/useCatalogPrices'; import { PartsAPIArticle } from '@/types/partsapi'; import toast from 'react-hot-toast'; interface ArticleCardProps { article: PartsAPIArticle; index: number; onVisibilityChange?: (index: number, isVisible: boolean) => void; } const ArticleCard: React.FC = memo(({ article, index, onVisibilityChange }) => { const [shouldShow, setShouldShow] = useState(false); const [isChecking, setIsChecking] = useState(true); // Используем хук для получения изображения const { imageUrl, isLoading: imageLoading, error } = useArticleImage(article.artId, { enabled: !!article.artId }); // Проверяем и очищаем данные артикула и бренда const articleNumber = article.artArticleNr?.trim(); const brandName = article.artSupBrand?.trim(); // Используем хук для получения цен только если есть и артикул, и бренд const { getPriceData, addToCart } = useCatalogPrices(); const shouldFetchPrices = articleNumber && brandName && articleNumber !== '' && brandName !== ''; const priceData = shouldFetchPrices ? getPriceData(articleNumber, brandName) : { minPrice: null, cheapestOffer: null, isLoading: false, hasOffers: false }; // Определяем, должен ли отображаться товар useEffect(() => { if (!shouldFetchPrices) { // Если нет данных для поиска, не показываем товар setShouldShow(false); setIsChecking(false); onVisibilityChange?.(index, false); console.log('❌ ArticleCard: скрываем товар без данных:', { articleNumber, brandName }); return; } if (priceData.isLoading) { // Если данные загружаются, ждем setIsChecking(true); return; } // Данные загружены - проверяем результат if (priceData.hasOffers) { setShouldShow(true); setIsChecking(false); onVisibilityChange?.(index, true); console.log('✅ ArticleCard: показываем товар с предложениями:', { articleNumber, brandName, hasPrice: !!priceData.minPrice }); } else { setShouldShow(false); setIsChecking(false); onVisibilityChange?.(index, false); console.log('❌ ArticleCard: скрываем товар без предложений:', { articleNumber, brandName }); } }, [shouldFetchPrices, priceData.isLoading, priceData.hasOffers, articleNumber, brandName, priceData.minPrice, index, onVisibilityChange]); // Показываем скелетон если данные загружаются или проверяются if (isChecking || (shouldShow && (priceData.isLoading || imageLoading))) { return ; } // Не отображаем ничего если товар не должен показываться if (!shouldShow) { return null; } // Формируем название товара const title = [ brandName || 'N/A', articleNumber || 'N/A', ].filter(part => part !== 'N/A').join(', '); const brand = brandName || 'Unknown'; // Формируем цену для отображения let priceText = ''; if (priceData.isLoading) { priceText = 'Загрузка...'; } else if (priceData.minPrice && priceData.minPrice > 0) { priceText = `от ${priceData.minPrice.toLocaleString('ru-RU')} ₽`; } else { priceText = 'По запросу'; } // Обработчик добавления в корзину const handleAddToCart = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (!shouldFetchPrices) { toast.error('Недостаточно данных для добавления товара в корзину'); return; } await addToCart(articleNumber!, brandName!); }; return ( ); }); ArticleCard.displayName = 'ArticleCard'; export default ArticleCard;