Compare commits
2 Commits
a8f783767f
...
9adc737028
Author | SHA1 | Date | |
---|---|---|---|
9adc737028 | |||
95e6b33b56 |
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { useCart } from "@/contexts/CartContext";
|
import { useCart } from "@/contexts/CartContext";
|
||||||
import { useFavorites } from "@/contexts/FavoritesContext";
|
import { useFavorites } from "@/contexts/FavoritesContext";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
@ -13,6 +13,7 @@ interface BestPriceItemProps {
|
|||||||
article?: string;
|
article?: string;
|
||||||
productId?: string;
|
productId?: string;
|
||||||
onAddToCart?: (e: React.MouseEvent) => void;
|
onAddToCart?: (e: React.MouseEvent) => void;
|
||||||
|
isInCart?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BestPriceItem: React.FC<BestPriceItemProps> = ({
|
const BestPriceItem: React.FC<BestPriceItemProps> = ({
|
||||||
@ -25,9 +26,11 @@ const BestPriceItem: React.FC<BestPriceItemProps> = ({
|
|||||||
article,
|
article,
|
||||||
productId,
|
productId,
|
||||||
onAddToCart,
|
onAddToCart,
|
||||||
|
isInCart = false,
|
||||||
}) => {
|
}) => {
|
||||||
const { addItem } = useCart();
|
const { addItem } = useCart();
|
||||||
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
|
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
|
||||||
|
const [localInCart, setLocalInCart] = useState(false);
|
||||||
|
|
||||||
// Проверяем, есть ли товар в избранном
|
// Проверяем, есть ли товар в избранном
|
||||||
const isItemFavorite = isFavorite(productId, undefined, article, brand);
|
const isItemFavorite = isFavorite(productId, undefined, article, brand);
|
||||||
@ -42,6 +45,9 @@ const BestPriceItem: React.FC<BestPriceItemProps> = ({
|
|||||||
const handleAddToCart = async (e: React.MouseEvent) => {
|
const handleAddToCart = async (e: React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
if (!localInCart) {
|
||||||
|
setLocalInCart(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Если передан кастомный обработчик, используем его
|
// Если передан кастомный обработчик, используем его
|
||||||
if (onAddToCart) {
|
if (onAddToCart) {
|
||||||
@ -167,8 +173,13 @@ const BestPriceItem: React.FC<BestPriceItemProps> = ({
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="button-icon w-inline-block"
|
className="button-icon w-inline-block"
|
||||||
onClick={handleAddToCart}
|
onClick={isInCart ? undefined : handleAddToCart}
|
||||||
style={{ cursor: 'pointer' }}
|
style={{
|
||||||
|
cursor: isInCart ? 'default' : (localInCart ? 'default' : 'pointer'),
|
||||||
|
background: isInCart ? '#9ca3af' : (localInCart ? '#2563eb' : undefined),
|
||||||
|
opacity: isInCart || localInCart ? 0.5 : 1,
|
||||||
|
filter: isInCart || localInCart ? 'grayscale(1)' : 'none'
|
||||||
|
}}
|
||||||
aria-label="Добавить в корзину"
|
aria-label="Добавить в корзину"
|
||||||
>
|
>
|
||||||
<div className="div-block-26">
|
<div className="div-block-26">
|
||||||
|
@ -277,8 +277,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const activeCatalog = catalogsData?.partsIndexCategoriesWithGroups?.[tabData.findIndex(tab => tab === mobileCategory)];
|
const catalogId = mobileCategory.catalogId || 'fallback';
|
||||||
const catalogId = activeCatalog?.id || 'fallback';
|
|
||||||
handleCategoryClick(catalogId, mobileCategory.links[0], subcategoryId);
|
handleCategoryClick(catalogId, mobileCategory.links[0], subcategoryId);
|
||||||
}}
|
}}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
@ -306,8 +305,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const activeCatalog = catalogsData?.partsIndexCategoriesWithGroups?.[tabData.findIndex(tab => tab === mobileCategory)];
|
const catalogId = mobileCategory.catalogId || 'fallback';
|
||||||
const catalogId = activeCatalog?.id || 'fallback';
|
|
||||||
handleCategoryClick(catalogId, link, subcategoryId);
|
handleCategoryClick(catalogId, link, subcategoryId);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -333,7 +331,7 @@
|
|||||||
{tabData.map((cat, index) => {
|
{tabData.map((cat, index) => {
|
||||||
// Получаем ID каталога из данных PartsIndex или создаем fallback ID
|
// Получаем ID каталога из данных PartsIndex или создаем fallback ID
|
||||||
const catalogId = catalogsData?.partsIndexCategoriesWithGroups?.[index]?.id || `fallback_${index}`;
|
const catalogId = catalogsData?.partsIndexCategoriesWithGroups?.[index]?.id || `fallback_${index}`;
|
||||||
|
const groups = catalogsData?.partsIndexCategoriesWithGroups?.[index]?.groups || [];
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="mobile-subcategory"
|
className="mobile-subcategory"
|
||||||
@ -343,7 +341,7 @@
|
|||||||
const categoryWithData = {
|
const categoryWithData = {
|
||||||
...cat,
|
...cat,
|
||||||
catalogId,
|
catalogId,
|
||||||
groups: catalogsData?.partsIndexCategoriesWithGroups?.[index]?.groups
|
groups
|
||||||
};
|
};
|
||||||
setMobileCategory(categoryWithData);
|
setMobileCategory(categoryWithData);
|
||||||
}}
|
}}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { useFavorites } from "@/contexts/FavoritesContext";
|
import { useFavorites } from "@/contexts/FavoritesContext";
|
||||||
|
|
||||||
interface CatalogProductCardProps {
|
interface CatalogProductCardProps {
|
||||||
@ -37,6 +37,7 @@ const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
|
|||||||
isInCart = false,
|
isInCart = false,
|
||||||
}) => {
|
}) => {
|
||||||
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
|
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
|
||||||
|
const [localInCart, setLocalInCart] = useState(false);
|
||||||
|
|
||||||
const displayImage = image || 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEwIiBoZWlnaHQ9IjE5MCIgdmlld0JveD0iMCAwIDIxMCAxOTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMTAiIGhlaWdodD0iMTkwIiBmaWxsPSIjRjNGNEY2Ii8+CjxwYXRoIGQ9Ik04NSA5NUw5NSA4NUwxMjUgMTE1TDE0MCA5NUwxNjUgMTIwSDE2NVY5MEg0NVY5MEw4NSA5NVoiIGZpbGw9IiNEMUQ1REIiLz4KPGNpcmNsZSBjeD0iNzUiIGN5PSI3NSIgcj0iMTAiIGZpbGw9IiNEMUQ1REIiLz4KPHRleHQgeD0iMTA1IiB5PSIxNTAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzlDQTNBRiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+Tm8gaW1hZ2U8L3RleHQ+Cjwvc3ZnPgo=';
|
const displayImage = image || 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEwIiBoZWlnaHQ9IjE5MCIgdmlld0JveD0iMCAwIDIxMCAxOTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMTAiIGhlaWdodD0iMTkwIiBmaWxsPSIjRjNGNEY2Ii8+CjxwYXRoIGQ9Ik04NSA5NUw5NSA4NUwxMjUgMTE1TDE0MCA5NUwxNjUgMTIwSDE2NVY5MEg0NVY5MEw4NSA5NVoiIGZpbGw9IiNEMUQ1REIiLz4KPGNpcmNsZSBjeD0iNzUiIGN5PSI3NSIgcj0iMTAiIGZpbGw9IiNEMUQ1REIiLz4KPHRleHQgeD0iMTA1IiB5PSIxNTAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzlDQTNBRiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+Tm8gaW1hZ2U8L3RleHQ+Cjwvc3ZnPgo=';
|
||||||
|
|
||||||
@ -77,6 +78,9 @@ const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
|
|||||||
const handleBuyClick = (e: React.MouseEvent) => {
|
const handleBuyClick = (e: React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
if (!isInCart && !localInCart) {
|
||||||
|
setLocalInCart(true);
|
||||||
|
}
|
||||||
if (onAddToCart) {
|
if (onAddToCart) {
|
||||||
onAddToCart(e);
|
onAddToCart(e);
|
||||||
} else {
|
} else {
|
||||||
@ -141,8 +145,13 @@ const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
|
|||||||
href="#"
|
href="#"
|
||||||
className="button-icon w-inline-block"
|
className="button-icon w-inline-block"
|
||||||
onClick={handleBuyClick}
|
onClick={handleBuyClick}
|
||||||
style={{ cursor: isInCart ? 'default' : 'pointer', opacity: isInCart ? 0.5 : 1, filter: isInCart ? 'grayscale(1)' : 'none' }}
|
style={{
|
||||||
aria-label={isInCart ? 'В корзине' : 'Купить'}
|
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}
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
<div className="div-block-26">
|
<div className="div-block-26">
|
||||||
|
@ -63,6 +63,7 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
|
|||||||
offers.reduce((acc, _, index) => ({ ...acc, [index]: "1" }), {})
|
offers.reduce((acc, _, index) => ({ ...acc, [index]: "1" }), {})
|
||||||
);
|
);
|
||||||
const [quantityErrors, setQuantityErrors] = useState<{ [key: number]: string }>({});
|
const [quantityErrors, setQuantityErrors] = useState<{ [key: number]: string }>({});
|
||||||
|
const [localInCart, setLocalInCart] = useState<{ [key: number]: boolean }>({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInputValues(offers.reduce((acc, _, index) => ({ ...acc, [index]: "1" }), {}));
|
setInputValues(offers.reduce((acc, _, index) => ({ ...acc, [index]: "1" }), {}));
|
||||||
@ -158,6 +159,7 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleAddToCart = async (offer: CoreProductCardOffer, index: number) => {
|
const handleAddToCart = async (offer: CoreProductCardOffer, index: number) => {
|
||||||
|
setLocalInCart(prev => ({ ...prev, [index]: true }));
|
||||||
const quantity = quantities[index] || 1;
|
const quantity = quantities[index] || 1;
|
||||||
const availableStock = parseStock(offer.pcs);
|
const availableStock = parseStock(offer.pcs);
|
||||||
const inCart = offer.isInCart || false; // Use backend flag
|
const inCart = offer.isInCart || false; // Use backend flag
|
||||||
@ -407,7 +409,8 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
|
|||||||
{displayedOffers.map((offer, idx) => {
|
{displayedOffers.map((offer, idx) => {
|
||||||
const isLast = idx === displayedOffers.length - 1;
|
const isLast = idx === displayedOffers.length - 1;
|
||||||
const maxCount = parseStock(offer.pcs);
|
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
|
// Backend now provides isInCart flag directly
|
||||||
|
|
||||||
@ -484,23 +487,23 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleAddToCart(offer, idx)}
|
onClick={() => handleAddToCart(offer, idx)}
|
||||||
className={`button-icon w-inline-block ${inCart ? 'in-cart' : ''}`}
|
className={`button-icon w-inline-block ${inCart || isLocallyInCart ? 'in-cart' : ''}`}
|
||||||
style={{
|
style={{
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
opacity: inCart ? 0.5 : 1,
|
opacity: inCart || isLocallyInCart ? 0.5 : 1,
|
||||||
backgroundColor: inCart ? '#9ca3af' : undefined
|
backgroundColor: inCart || isLocallyInCart ? '#2563eb' : undefined
|
||||||
}}
|
}}
|
||||||
aria-label={inCart ? "Товар уже в корзине" : "Добавить в корзину"}
|
aria-label={inCart || isLocallyInCart ? "Товар уже в корзине" : "Добавить в корзину"}
|
||||||
title={inCart ? "Товар уже в корзине - нажмите для добавления еще" : "Добавить в корзину"}
|
title={inCart || isLocallyInCart ? "Товар уже в корзине - нажмите для добавления еще" : "Добавить в корзину"}
|
||||||
>
|
>
|
||||||
<div className="div-block-26">
|
<div className="div-block-26">
|
||||||
<img
|
<img
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
src="/images/cart_icon.svg"
|
src="/images/cart_icon.svg"
|
||||||
alt={inCart ? "В корзине" : "В корзину"}
|
alt={inCart || isLocallyInCart ? "В корзине" : "В корзину"}
|
||||||
className="image-11"
|
className="image-11"
|
||||||
style={{
|
style={{
|
||||||
filter: inCart ? 'brightness(0.7)' : undefined
|
filter: inCart || isLocallyInCart ? 'brightness(0.7)' : undefined
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,7 +54,13 @@ const SearchHistoryDropdown: React.FC<SearchHistoryDropdownProps> = ({
|
|||||||
{uniqueQueries.map((item) => (
|
{uniqueQueries.map((item) => (
|
||||||
<button
|
<button
|
||||||
key={item.id}
|
key={item.id}
|
||||||
onClick={() => onItemClick(item.searchQuery)}
|
onClick={() => {
|
||||||
|
if ((item.searchType === 'ARTICLE' || item.searchType === 'OEM') && item.articleNumber) {
|
||||||
|
onItemClick(item.articleNumber);
|
||||||
|
} else {
|
||||||
|
onItemClick(item.searchQuery);
|
||||||
|
}
|
||||||
|
}}
|
||||||
className="search-history-item-custom"
|
className="search-history-item-custom"
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
>
|
>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { useCart } from "@/contexts/CartContext";
|
import { useCart } from "@/contexts/CartContext";
|
||||||
import { useFavorites } from "@/contexts/FavoritesContext";
|
import { useFavorites } from "@/contexts/FavoritesContext";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
@ -13,6 +13,7 @@ interface TopSalesItemProps {
|
|||||||
productId?: string;
|
productId?: string;
|
||||||
onAddToCart?: (e: React.MouseEvent) => void;
|
onAddToCart?: (e: React.MouseEvent) => void;
|
||||||
discount?: string; // Новый пропс для лейбла/скидки
|
discount?: string; // Новый пропс для лейбла/скидки
|
||||||
|
// isInCart?: boolean; // Удаляем из пропсов
|
||||||
}
|
}
|
||||||
|
|
||||||
const TopSalesItem: React.FC<TopSalesItemProps> = ({
|
const TopSalesItem: React.FC<TopSalesItemProps> = ({
|
||||||
@ -24,11 +25,17 @@ const TopSalesItem: React.FC<TopSalesItemProps> = ({
|
|||||||
productId,
|
productId,
|
||||||
onAddToCart,
|
onAddToCart,
|
||||||
discount = 'Топ продаж', // По умолчанию как раньше
|
discount = 'Топ продаж', // По умолчанию как раньше
|
||||||
|
// isInCart = false, // Удаляем из пропсов
|
||||||
}) => {
|
}) => {
|
||||||
const { addItem } = useCart();
|
const { addItem, cartItems = [] } = useCart();
|
||||||
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
|
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
|
||||||
|
const [localInCart, setLocalInCart] = useState(false);
|
||||||
|
|
||||||
const isItemFavorite = isFavorite(productId, undefined, article, brand);
|
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 parsePrice = (priceStr: string): number => {
|
const parsePrice = (priceStr: string): number => {
|
||||||
const cleanPrice = priceStr.replace(/[^\d.,]/g, '').replace(',', '.');
|
const cleanPrice = priceStr.replace(/[^\d.,]/g, '').replace(',', '.');
|
||||||
@ -38,6 +45,9 @@ const TopSalesItem: React.FC<TopSalesItemProps> = ({
|
|||||||
const handleAddToCart = (e: React.MouseEvent) => {
|
const handleAddToCart = (e: React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
if (!localInCart) {
|
||||||
|
setLocalInCart(true);
|
||||||
|
}
|
||||||
if (onAddToCart) {
|
if (onAddToCart) {
|
||||||
onAddToCart(e);
|
onAddToCart(e);
|
||||||
return;
|
return;
|
||||||
@ -134,9 +144,14 @@ const TopSalesItem: React.FC<TopSalesItemProps> = ({
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="button-icon w-inline-block"
|
className="button-icon w-inline-block"
|
||||||
onClick={handleAddToCart}
|
onClick={isInCart ? undefined : handleAddToCart}
|
||||||
style={{ cursor: 'pointer' }}
|
style={{
|
||||||
aria-label="Добавить в корзину"
|
cursor: isInCart ? 'default' : (localInCart ? 'default' : 'pointer'),
|
||||||
|
background: isInCart ? '#9ca3af' : (localInCart ? '#2563eb' : undefined),
|
||||||
|
opacity: isInCart || localInCart ? 0.5 : 1,
|
||||||
|
filter: isInCart || localInCart ? 'grayscale(1)' : 'none'
|
||||||
|
}}
|
||||||
|
aria-label={isInCart ? 'В корзине' : (localInCart ? 'Добавлено' : 'Добавить в корзину')}
|
||||||
>
|
>
|
||||||
<div className="div-block-26">
|
<div className="div-block-26">
|
||||||
<div className="icon-setting w-embed">
|
<div className="icon-setting w-embed">
|
||||||
|
@ -2,6 +2,7 @@ import React, { useRef } from "react";
|
|||||||
import { useQuery } from "@apollo/client";
|
import { useQuery } from "@apollo/client";
|
||||||
import TopSalesItem from "../TopSalesItem";
|
import TopSalesItem from "../TopSalesItem";
|
||||||
import { GET_TOP_SALES_PRODUCTS } from "../../lib/graphql";
|
import { GET_TOP_SALES_PRODUCTS } from "../../lib/graphql";
|
||||||
|
import { useCart } from "@/contexts/CartContext";
|
||||||
|
|
||||||
interface TopSalesProductData {
|
interface TopSalesProductData {
|
||||||
id: string;
|
id: string;
|
||||||
@ -22,6 +23,7 @@ const SCROLL_AMOUNT = 340; // px, ширина одной карточки + о
|
|||||||
|
|
||||||
const TopSalesSection: React.FC = () => {
|
const TopSalesSection: React.FC = () => {
|
||||||
const { data, loading, error } = useQuery(GET_TOP_SALES_PRODUCTS);
|
const { data, loading, error } = useQuery(GET_TOP_SALES_PRODUCTS);
|
||||||
|
const { cartItems = [] } = useCart();
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const scrollLeft = () => {
|
const scrollLeft = () => {
|
||||||
@ -212,6 +214,7 @@ const TopSalesSection: React.FC = () => {
|
|||||||
|
|
||||||
const title = product.name;
|
const title = product.name;
|
||||||
const brand = product.brand || 'Неизвестный бренд';
|
const brand = product.brand || 'Неизвестный бренд';
|
||||||
|
const isInCart = cartItems.some(cartItem => cartItem.productId === product.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TopSalesItem
|
<TopSalesItem
|
||||||
@ -222,6 +225,7 @@ const TopSalesSection: React.FC = () => {
|
|||||||
brand={brand}
|
brand={brand}
|
||||||
article={product.article}
|
article={product.article}
|
||||||
productId={product.id}
|
productId={product.id}
|
||||||
|
isInCart={isInCart}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -39,9 +39,9 @@ const mockData = Array(12).fill({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export default function Catalog() {
|
export default function Catalog() {
|
||||||
const ITEMS_PER_PAGE = 12; // Показывать 12 карточек за раз
|
const ITEMS_PER_PAGE = 24; // Показывать 12 карточек за раз
|
||||||
const PARTSINDEX_PAGE_SIZE = 25; // Синхронизировано для оптимальной скорости
|
const PARTSINDEX_PAGE_SIZE = 25; // Синхронизировано для оптимальной скорости
|
||||||
const MAX_BRANDS_DISPLAY = 10; // Сколько брендов показывать изначально
|
const MAX_BRANDS_DISPLAY = 24; // Сколько брендов показывать изначально
|
||||||
const [visibleCount, setVisibleCount] = useState(ITEMS_PER_PAGE);
|
const [visibleCount, setVisibleCount] = useState(ITEMS_PER_PAGE);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { addItem } = useCart();
|
const { addItem } = useCart();
|
||||||
@ -336,12 +336,6 @@ export default function Catalog() {
|
|||||||
естьЕщеТовары: hasMoreEntities
|
естьЕщеТовары: hasMoreEntities
|
||||||
});
|
});
|
||||||
|
|
||||||
// Если у нас уже достаточно товаров, не загружаем
|
|
||||||
if (currentEntitiesCount >= ITEMS_PER_PAGE) {
|
|
||||||
console.log('✅ Автоподгрузка: достаточно товаров');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Даем время на загрузку цен товаров, если их слишком много загружается
|
// Даем время на загрузку цен товаров, если их слишком много загружается
|
||||||
const loadingCount = accumulatedEntities.filter(entity => {
|
const loadingCount = accumulatedEntities.filter(entity => {
|
||||||
const productForPrice = { id: entity.id, code: entity.code, brand: entity.brand.name };
|
const productForPrice = { id: entity.id, code: entity.code, brand: entity.brand.name };
|
||||||
@ -935,6 +929,20 @@ export default function Catalog() {
|
|||||||
return false;
|
return false;
|
||||||
}, [isPartsAPIMode, loadedArticlesCount, filteredArticles.length]);
|
}, [isPartsAPIMode, loadedArticlesCount, filteredArticles.length]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Сбросить все состояния при смене каталога или подкатегории
|
||||||
|
setAccumulatedEntities([]);
|
||||||
|
setVisibleEntities([]);
|
||||||
|
setEntitiesWithOffers([]);
|
||||||
|
setEntitiesCache(new Map());
|
||||||
|
setCurrentUserPage(1);
|
||||||
|
setPartsIndexPage(1);
|
||||||
|
setHasMoreEntities(true);
|
||||||
|
setShowEmptyState(false);
|
||||||
|
setIsFilterChanging(false);
|
||||||
|
setVisibleCount(ITEMS_PER_PAGE);
|
||||||
|
}, [catalogId, groupId]);
|
||||||
|
|
||||||
if (filtersLoading) {
|
if (filtersLoading) {
|
||||||
return <div className="py-8 text-center">Загрузка фильтров...</div>;
|
return <div className="py-8 text-center">Загрузка фильтров...</div>;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,14 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-block-39-copy {
|
||||||
|
|
||||||
|
max-width: 300px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-block-40 {
|
.flex-block-40 {
|
||||||
background-color: #fff;
|
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +272,18 @@ header.section-4 {
|
|||||||
display: none; /* Chrome, Safari, Opera */
|
display: none; /* Chrome, Safari, Opera */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.heading-2 {
|
||||||
|
max-width: 300px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: block;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle.w-dropdown-toggle {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.mobile-category-overlay {
|
.mobile-category-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -782,7 +799,7 @@ a.link-block-2.w-inline-block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 991px) {
|
@media screen and (max-width: 991px) {
|
||||||
.flex-block-108, .flex-block-14-copy-copy {
|
.flex-block-108 {
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
@ -986,8 +1003,8 @@ a.link-block-2.w-inline-block {
|
|||||||
.flex-block-15-copy {
|
.flex-block-15-copy {
|
||||||
grid-column-gap: 5px;
|
grid-column-gap: 5px;
|
||||||
grid-row-gap: 5px;
|
grid-row-gap: 5px;
|
||||||
width: 160px !important;
|
width: 210px !important;
|
||||||
min-width: 160px !important;
|
min-width: 210px !important;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
.div-block-3 {
|
.div-block-3 {
|
||||||
@ -1005,8 +1022,8 @@ a.link-block-2.w-inline-block {
|
|||||||
.flex-block-15-copy {
|
.flex-block-15-copy {
|
||||||
grid-column-gap: 5px;
|
grid-column-gap: 5px;
|
||||||
grid-row-gap: 5px;
|
grid-row-gap: 5px;
|
||||||
width: 160px !important;
|
width: 180px !important;
|
||||||
min-width: 160px !important;
|
min-width: 180px !important;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
.nameitembp {
|
.nameitembp {
|
||||||
@ -1299,4 +1316,16 @@ a.link-block-2.w-inline-block {
|
|||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
} */
|
} */
|
||||||
|
}
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.pcs-cart-s1 {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.filters-desktop {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user