"use client"; import { useEffect, useState } from "react"; import { ShoppingBag } from "lucide-react"; import { Button } from "@/components/ui/button"; import type { Product } from "@/lib/headless/types"; import { useCartStore } from "@/store/cart-store"; const SCROLL_THRESHOLD_PX = 80; // Antes esta barra quedaba fija desde el primer render en mobile, // tapando permanentemente parte de la imagen del producto solo para // duplicar un boton que ya está visible más abajo. Ahora combina tres // condiciones, igual que el "Buy Now" sticky de Amazon: // - scrolled: recien aparece despues de que el usuario empieza a // scrollear (nunca sobre la vista inicial de la imagen/hero). // - !buttonVisible: el boton real (#product-buy-button en // ProductPurchase, visible tambien en mobile) no esta en pantalla -- // ya sea porque todavia no se llego a el, o porque se scrolleo mas // alla. // - !pastRecommendations: una vez que "También te puede gustar" // (#recommendations-section en app/product/[slug]/page.tsx) empieza a // entrar en pantalla, la barra se oculta y sigue oculta el resto del // scroll (footer incluido) -- pedido explicito del usuario. OJO: // condicionar esto a que el borde superior de la seccion cruce el // TOPE del viewport (top <= 0) rompe en paginas cortas -- si no hay // suficiente contenido/footer debajo, nunca se puede scrollear tan // lejos y el bug original (barra pegada hasta el fondo) segunia // reproduciendose. En cambio, se compara contra la ALTURA del // viewport (top < innerHeight): se oculta apenas la seccion empieza a // asomar desde abajo, se mantiene oculta al seguir scrolleando mas // alla (top se vuelve cada vez mas negativo, sigue siendo < // innerHeight), y solo reaparece si se vuelve a scrollear hacia // arriba lo suficiente como para que la seccion salga de pantalla per // completo otra vez. export function MobileAddToCart({ product }: { product: Product }) { const addItem = useCartStore((state) => state.addItem); const [buttonVisible, setButtonVisible] = useState(true); const [pastRecommendations, setPastRecommendations] = useState(false); const [scrolled, setScrolled] = useState(false); const outOfStock = product.variants[0]?.available === false; useEffect(() => { const target = document.getElementById("product-buy-button"); if (!target) return; const observer = new IntersectionObserver((entries) => { const entry = entries[0]; if (entry) setButtonVisible(entry.isIntersecting); }, { threshold: 0 }); observer.observe(target); return () => observer.disconnect(); }, []); useEffect(() => { const target = document.getElementById("recommendations-section"); if (!target) return; const observer = new IntersectionObserver((entries) => { const entry = entries[0]; if (entry) setPastRecommendations(entry.boundingClientRect.top < window.innerHeight); }, { threshold: 0 }); observer.observe(target); return () => observer.disconnect(); }, []); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > SCROLL_THRESHOLD_PX); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); const visible = scrolled && !buttonVisible && !pastRecommendations; return (
); }