diff --git a/src/components/CoreProductCard.tsx b/src/components/CoreProductCard.tsx index 64ede6f..ac83a7c 100644 --- a/src/components/CoreProductCard.tsx +++ b/src/components/CoreProductCard.tsx @@ -274,7 +274,11 @@ const CoreProductCard: React.FC = ({
-
+ +
+ +
+
info @@ -310,8 +314,6 @@ const CoreProductCard: React.FC = ({
)}
-
-
Наличие
diff --git a/src/components/Filters.tsx b/src/components/Filters.tsx index 80f1c69..fa4b641 100644 --- a/src/components/Filters.tsx +++ b/src/components/Filters.tsx @@ -88,7 +88,7 @@ const Filters: React.FC = ({ if (filter.type === "range") { return ( = ({ if (filter.type === "range") { return ( = ({ title, min = DEFAULT_MIN, max const [open, setOpen] = useState(true); const trackRef = useRef(null); - // Обновляем локальное состояние при изменении внешнего значения + // Обновляем локальное состояние при изменении внешнего значения или границ useEffect(() => { - if (value) { - setFrom(String(value[0])); - setTo(String(value[1])); - setConfirmedFrom(value[0]); - setConfirmedTo(value[1]); - } else { - setFrom(String(min)); - setTo(String(max)); - setConfirmedFrom(min); - setConfirmedTo(max); + let nextFrom = value ? value[0] : min; + let nextTo = value ? value[1] : max; + let changed = false; + // Корректируем значения, если они вне новых границ + if (nextFrom < min) { nextFrom = min; changed = true; } + if (nextTo > max) { nextTo = max; changed = true; } + if (nextFrom > nextTo) { nextFrom = nextTo; changed = true; } + setFrom(String(nextFrom)); + setTo(String(nextTo)); + setConfirmedFrom(nextFrom); + setConfirmedTo(nextTo); + // Если значения были скорректированы, уведомляем родителя + if (changed && onChange) { + onChange([nextFrom, nextTo]); } - }, [value, min, max]); + }, [value, min, max, onChange]); // Обновляем ширину полосы при монтировании и ресайзе useLayoutEffect(() => { diff --git a/src/components/index/ProductOfDaySection.tsx b/src/components/index/ProductOfDaySection.tsx index 611a44f..a1a7ca1 100644 --- a/src/components/index/ProductOfDaySection.tsx +++ b/src/components/index/ProductOfDaySection.tsx @@ -49,6 +49,16 @@ const ProductOfDaySection: React.FC = () => { .sort((a, b) => a.sortOrder - b.sortOrder); }, [data]); + // Корректный сброс currentSlide только если индекс вне диапазона + useEffect(() => { + if (currentSlide > activeProducts.length - 1) { + setCurrentSlide(activeProducts.length > 0 ? activeProducts.length - 1 : 0); + } + // Если товаров стало больше и текущий слайд = 0, ничего не делаем + // Если товаров стало меньше и текущий слайд в диапазоне, ничего не делаем + // Если товаров стало меньше и текущий слайд вне диапазона, сбрасываем на последний + }, [activeProducts.length]); + // Получаем данные из PartsIndex для текущего товара const currentProduct = activeProducts[currentSlide]; const { data: partsIndexData } = useQuery( @@ -132,11 +142,6 @@ const ProductOfDaySection: React.FC = () => { setCurrentSlide(index); }; - // Сброс слайда при изменении товаров - useEffect(() => { - setCurrentSlide(0); - }, [activeProducts]); - // Если нет активных товаров дня, не показываем секцию if (loading || error || activeProducts.length === 0) { return null; @@ -244,7 +249,7 @@ const ProductOfDaySection: React.FC = () => {
{productImage && ( -
+
= ({ const [selectedDetail, setSelectedDetail] = useState<{ oem: string; name: string } | null>(null); const [hoveredCodeOnImage, setHoveredCodeOnImage] = useState(null); const router = useRouter(); + const [isImageModalOpen, setIsImageModalOpen] = useState(false); // Получаем инфо об узле (для картинки) console.log('🔍 KnotIn - GET_LAXIMO_UNIT_INFO запрос:', { @@ -164,6 +165,12 @@ const KnotIn: React.FC = ({ }); }; + // Обработчик клика по картинке (zoom) + const handleImageClick = (e: React.MouseEvent) => { + // Если клик был по точке, не открываем модалку (точки выше по z-index) + setIsImageModalOpen(true); + }; + // Обработчик наведения на точку const handlePointHover = (coord: any) => { // Попробуем использовать разные поля для связи @@ -318,8 +325,9 @@ const KnotIn: React.FC = ({ loading="lazy" alt={unitName || unitInfo?.name || "Изображение узла"} onLoad={handleImageLoad} - className="max-w-full h-auto mx-auto rounded" + className="max-w-full h-auto mx-auto rounded cursor-zoom-in" style={{ maxWidth: 400, display: 'block' }} + onClick={handleImageClick} /> {/* Точки/области */} {coordinates.map((coord: any, idx: number) => { @@ -369,8 +377,8 @@ const KnotIn: React.FC = ({ pointerEvents: 'auto', }} title={`${codeValue} (Клик - выделить в списке, двойной клик - перейти к выбору бренда)`} - onClick={() => handlePointClick(coord)} - onDoubleClick={() => handlePointDoubleClick(coord)} + onClick={e => { e.stopPropagation(); handlePointClick(coord); }} + onDoubleClick={e => { e.stopPropagation(); handlePointDoubleClick(coord); }} onMouseEnter={() => handlePointHover(coord)} onMouseLeave={() => { setHoveredCodeOnImage(null); @@ -388,7 +396,31 @@ const KnotIn: React.FC = ({
); })} -
+
+ {/* Модалка увеличенного изображения */} + {isImageModalOpen && ( +
setIsImageModalOpen(false)} + style={{ cursor: 'zoom-out' }} + > + {unitName e.stopPropagation()} + style={{ background: '#fff' }} + /> + +
+ )} {/* Модалка выбора бренда */}