From 80ed5826e25a2c7fcb493334e714be85e6071fd0 Mon Sep 17 00:00:00 2001 From: 54CHA Date: Wed, 30 Jul 2025 15:25:18 +0300 Subject: [PATCH] novyie parvki --- src/components/ArticleCard.tsx | 10 +++++++++ src/components/BestPriceItem.tsx | 24 +++++++++++++-------- src/components/TopSalesItem.tsx | 9 ++++---- src/components/index/CategoryNavSection.tsx | 15 +++++++++++-- src/pages/catalog.tsx | 6 ++++-- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/components/ArticleCard.tsx b/src/components/ArticleCard.tsx index 3bd263c..e587084 100644 --- a/src/components/ArticleCard.tsx +++ b/src/components/ArticleCard.tsx @@ -5,6 +5,7 @@ import { useArticleImage } from '@/hooks/useArticleImage'; import { useCatalogPrices } from '@/hooks/useCatalogPrices'; import { PartsAPIArticle } from '@/types/partsapi'; import toast from 'react-hot-toast'; +import { useCart } from '@/contexts/CartContext'; interface ArticleCardProps { article: PartsAPIArticle; @@ -17,6 +18,9 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi const [shouldShow, setShouldShow] = useState(false); const [isChecking, setIsChecking] = useState(true); + // Cart context + const { isInCart: isItemInCart } = useCart(); + // Используем хук для получения изображения const { imageUrl, isLoading: imageLoading, error } = useArticleImage(article.artId, { enabled: !!article.artId @@ -85,6 +89,8 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi const title = [brandName || 'N/A', articleNumber || 'N/A'].filter(part => part !== 'N/A').join(', '); const brand = brandName || 'Unknown'; let priceText = 'от 17 087 ₽'; + const isInCartFlag = isItemInCart(undefined, undefined, articleNumber, brandName); + return ( = memo(({ article, index, onVisibi brandName={brandName} artId={article.artId} onAddToCart={() => {}} + isInCart={isInCartFlag} /> ); } @@ -109,6 +116,8 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi const brand = brandName || 'Unknown'; + const isInCartFlag = isItemInCart(undefined, undefined, articleNumber, brandName); + // Формируем цену для отображения let priceText = ''; if (priceData.isLoading) { @@ -144,6 +153,7 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi brandName={brandName} artId={article.artId} onAddToCart={handleAddToCart} + isInCart={isInCartFlag} /> ); }); diff --git a/src/components/BestPriceItem.tsx b/src/components/BestPriceItem.tsx index dd69e5a..a5c0c2c 100644 --- a/src/components/BestPriceItem.tsx +++ b/src/components/BestPriceItem.tsx @@ -28,10 +28,15 @@ const BestPriceItem: React.FC = ({ onAddToCart, isInCart = false, }) => { - const { addItem } = useCart(); + const { addItem, isInCart: isItemInCart, state: cartState } = useCart(); const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites(); const [localInCart, setLocalInCart] = useState(false); + // Determine inCart via context if not provided + const inCartContext = isItemInCart(productId, undefined, article, brand); + + const inCart = isInCart || inCartContext; + // Проверяем, есть ли товар в избранном const isItemFavorite = isFavorite(productId, undefined, article, brand); @@ -172,15 +177,16 @@ const BestPriceItem: React.FC = ({
{title}
diff --git a/src/components/TopSalesItem.tsx b/src/components/TopSalesItem.tsx index 79b37e7..dcce271 100644 --- a/src/components/TopSalesItem.tsx +++ b/src/components/TopSalesItem.tsx @@ -27,15 +27,13 @@ const TopSalesItem: React.FC = ({ discount = 'Топ продаж', // По умолчанию как раньше // isInCart = false, // Удаляем из пропсов }) => { - const { addItem, cartItems = [] } = useCart(); + const { addItem, isInCart: isItemInCart } = useCart(); const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites(); const [localInCart, setLocalInCart] = useState(false); const isItemFavorite = isFavorite(productId, undefined, article, brand); - const isInCart = cartItems.some(item => - (productId && item.productId === productId) || - (article && brand && item.article === article && item.brand === brand) - ); + + const isInCart = isItemInCart(productId, undefined, article, brand); const parsePrice = (priceStr: string): number => { const cleanPrice = priceStr.replace(/[^\d.,]/g, '').replace(',', '.'); @@ -152,6 +150,7 @@ const TopSalesItem: React.FC = ({ filter: isInCart || localInCart ? 'grayscale(1)' : 'none' }} aria-label={isInCart ? 'В корзине' : (localInCart ? 'Добавлено' : 'Добавить в корзину')} + title={isInCart ? 'Товар уже в корзине - нажмите для добавления еще' : 'Добавить в корзину'} >
diff --git a/src/components/index/CategoryNavSection.tsx b/src/components/index/CategoryNavSection.tsx index 3f38f83..51cabde 100644 --- a/src/components/index/CategoryNavSection.tsx +++ b/src/components/index/CategoryNavSection.tsx @@ -3,10 +3,17 @@ import { useQuery } from '@apollo/client'; import { GET_PARTSINDEX_CATEGORIES } from '@/lib/graphql'; import { useRouter } from 'next/router'; +interface CategoryNavGroup { + id: string; + name: string; + image?: string; +} + interface CategoryNavItem { id: string; name: string; image?: string; + groups?: CategoryNavGroup[]; } const FALLBACK_CATEGORIES: CategoryNavItem[] = [ @@ -38,11 +45,15 @@ const CategoryNavSection: React.FC = () => { : FALLBACK_CATEGORIES; const handleCategoryClick = (category: CategoryNavItem) => { + // Получаем первую доступную группу для навигации в PartsIndex режим + const firstGroupId = category.groups && category.groups.length > 0 ? category.groups[0].id : undefined; + router.push({ pathname: '/catalog', query: { - categoryId: category.id, - categoryName: encodeURIComponent(category.name) + partsIndexCatalog: category.id, + categoryName: encodeURIComponent(category.name), + ...(firstGroupId && { partsIndexCategory: firstGroupId }) } }); }; diff --git a/src/pages/catalog.tsx b/src/pages/catalog.tsx index 14a4653..515fd2b 100644 --- a/src/pages/catalog.tsx +++ b/src/pages/catalog.tsx @@ -44,7 +44,7 @@ export default function Catalog() { const MAX_BRANDS_DISPLAY = 24; // Сколько брендов показывать изначально const [visibleCount, setVisibleCount] = useState(ITEMS_PER_PAGE); const router = useRouter(); - const { addItem } = useCart(); + const { addItem, isInCart: isItemInCart } = useCart(); const { partsApiCategory: strId, categoryName, @@ -1141,6 +1141,8 @@ export default function Catalog() { const productForPrice = { id: entity.id, code: entity.code, brand: entity.brand.name }; const priceData = getPrice(productForPrice); const isLoadingPriceData = isLoadingPrice(productForPrice); + // Fallback cart check via frontend context + const inCartFallback = isItemInCart(entity.id, priceData?.offerKey, entity.code, entity.brand.name); // Определяем цену для отображения (все товары уже отфильтрованы на сервере) let displayPrice = ""; @@ -1174,7 +1176,7 @@ export default function Catalog() { productId={entity.id} artId={entity.id} offerKey={priceData?.offerKey} - isInCart={priceData?.isInCart} + isInCart={priceData?.isInCart || inCartFallback} onAddToCart={async () => { // Если цена не загружена, загружаем её и добавляем в корзину if (!priceData && !isLoadingPriceData) {