From 95e6b33b56ec8ccb865b072ad5f70eb7606e7df6 Mon Sep 17 00:00:00 2001 From: egortriston Date: Wed, 30 Jul 2025 13:57:16 +0300 Subject: [PATCH] catalog and bags --- src/components/BestPriceItem.tsx | 17 ++++++++-- src/components/BottomHead.tsx | 10 +++--- src/components/CatalogProductCard.tsx | 15 +++++++-- src/components/CoreProductCard.tsx | 19 ++++++----- src/components/SearchHistoryDropdown.tsx | 8 ++++- src/components/TopSalesItem.tsx | 25 ++++++++++++--- src/components/index/TopSalesSection.tsx | 4 +++ src/pages/catalog.tsx | 24 +++++++++----- src/styles/my.css | 41 ++++++++++++++++++++---- 9 files changed, 123 insertions(+), 40 deletions(-) diff --git a/src/components/BestPriceItem.tsx b/src/components/BestPriceItem.tsx index 6821f09..dd69e5a 100644 --- a/src/components/BestPriceItem.tsx +++ b/src/components/BestPriceItem.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import { useCart } from "@/contexts/CartContext"; import { useFavorites } from "@/contexts/FavoritesContext"; import toast from "react-hot-toast"; @@ -13,6 +13,7 @@ interface BestPriceItemProps { article?: string; productId?: string; onAddToCart?: (e: React.MouseEvent) => void; + isInCart?: boolean; } const BestPriceItem: React.FC = ({ @@ -25,9 +26,11 @@ const BestPriceItem: React.FC = ({ article, productId, onAddToCart, + isInCart = false, }) => { const { addItem } = useCart(); const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites(); + const [localInCart, setLocalInCart] = useState(false); // Проверяем, есть ли товар в избранном const isItemFavorite = isFavorite(productId, undefined, article, brand); @@ -42,6 +45,9 @@ const BestPriceItem: React.FC = ({ const handleAddToCart = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); + if (!localInCart) { + setLocalInCart(true); + } // Если передан кастомный обработчик, используем его if (onAddToCart) { @@ -167,8 +173,13 @@ const BestPriceItem: React.FC = ({
diff --git a/src/components/BottomHead.tsx b/src/components/BottomHead.tsx index 5167b80..dc389ff 100644 --- a/src/components/BottomHead.tsx +++ b/src/components/BottomHead.tsx @@ -277,8 +277,7 @@ } } } - const activeCatalog = catalogsData?.partsIndexCategoriesWithGroups?.[tabData.findIndex(tab => tab === mobileCategory)]; - const catalogId = activeCatalog?.id || 'fallback'; + const catalogId = mobileCategory.catalogId || 'fallback'; handleCategoryClick(catalogId, mobileCategory.links[0], subcategoryId); }} style={{ cursor: "pointer" }} @@ -306,8 +305,7 @@ } } } - const activeCatalog = catalogsData?.partsIndexCategoriesWithGroups?.[tabData.findIndex(tab => tab === mobileCategory)]; - const catalogId = activeCatalog?.id || 'fallback'; + const catalogId = mobileCategory.catalogId || 'fallback'; handleCategoryClick(catalogId, link, subcategoryId); }} > @@ -333,7 +331,7 @@ {tabData.map((cat, index) => { // Получаем ID каталога из данных PartsIndex или создаем fallback ID const catalogId = catalogsData?.partsIndexCategoriesWithGroups?.[index]?.id || `fallback_${index}`; - + const groups = catalogsData?.partsIndexCategoriesWithGroups?.[index]?.groups || []; return (
= ({ isInCart = false, }) => { const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites(); + const [localInCart, setLocalInCart] = useState(false); const displayImage = image || 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEwIiBoZWlnaHQ9IjE5MCIgdmlld0JveD0iMCAwIDIxMCAxOTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMTAiIGhlaWdodD0iMTkwIiBmaWxsPSIjRjNGNEY2Ii8+CjxwYXRoIGQ9Ik04NSA5NUw5NSA4NUwxMjUgMTE1TDE0MCA5NUwxNjUgMTIwSDE2NVY5MEg0NVY5MEw4NSA5NVoiIGZpbGw9IiNEMUQ1REIiLz4KPGNpcmNsZSBjeD0iNzUiIGN5PSI3NSIgcj0iMTAiIGZpbGw9IiNEMUQ1REIiLz4KPHRleHQgeD0iMTA1IiB5PSIxNTAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzlDQTNBRiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+Tm8gaW1hZ2U8L3RleHQ+Cjwvc3ZnPgo='; @@ -77,6 +78,9 @@ const CatalogProductCard: React.FC = ({ const handleBuyClick = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); + if (!isInCart && !localInCart) { + setLocalInCart(true); + } if (onAddToCart) { onAddToCart(e); } else { @@ -141,8 +145,13 @@ const CatalogProductCard: React.FC = ({ href="#" className="button-icon w-inline-block" onClick={handleBuyClick} - style={{ cursor: isInCart ? 'default' : 'pointer', opacity: isInCart ? 0.5 : 1, filter: isInCart ? 'grayscale(1)' : 'none' }} - aria-label={isInCart ? 'В корзине' : 'Купить'} + style={{ + cursor: isInCart || localInCart ? 'default' : 'pointer', + opacity: isInCart || localInCart ? 0.5 : 1, + filter: isInCart || localInCart ? 'grayscale(1)' : 'none', + background: isInCart || localInCart ? '#2563eb' : undefined + }} + aria-label={isInCart || localInCart ? 'В корзине' : 'Купить'} tabIndex={0} >
diff --git a/src/components/CoreProductCard.tsx b/src/components/CoreProductCard.tsx index b894852..e284369 100644 --- a/src/components/CoreProductCard.tsx +++ b/src/components/CoreProductCard.tsx @@ -63,6 +63,7 @@ const CoreProductCard: React.FC = ({ offers.reduce((acc, _, index) => ({ ...acc, [index]: "1" }), {}) ); const [quantityErrors, setQuantityErrors] = useState<{ [key: number]: string }>({}); + const [localInCart, setLocalInCart] = useState<{ [key: number]: boolean }>({}); useEffect(() => { setInputValues(offers.reduce((acc, _, index) => ({ ...acc, [index]: "1" }), {})); @@ -158,6 +159,7 @@ const CoreProductCard: React.FC = ({ }; const handleAddToCart = async (offer: CoreProductCardOffer, index: number) => { + setLocalInCart(prev => ({ ...prev, [index]: true })); const quantity = quantities[index] || 1; const availableStock = parseStock(offer.pcs); const inCart = offer.isInCart || false; // Use backend flag @@ -407,7 +409,8 @@ const CoreProductCard: React.FC = ({ {displayedOffers.map((offer, idx) => { const isLast = idx === displayedOffers.length - 1; const maxCount = parseStock(offer.pcs); - const inCart = offer.isInCart || false; // Use backend flag + const inCart = offer.isInCart || false; + const isLocallyInCart = !!localInCart[idx]; // Backend now provides isInCart flag directly @@ -484,23 +487,23 @@ const CoreProductCard: React.FC = ({