import { Link } from "@remix-run/react"; import { useRef, useState, useEffect } from "react"; import { motion } from "framer-motion"; import { ChevronLeft, ChevronRight, Images } from "lucide-react"; import { Skeleton } from "./ui/skeleton"; import { ErrorState } from "./UiProvider"; import discountRed from "~/assets/icons/product/discount-red.svg"; import placeholderImage from "~/assets/icons/product.png"; interface HorizontalProduct { id?: string; title?: string; images?: string[]; discountPercent?: number; discountPrice?: number; basePrice?: number; } const HorizontalProductList = ({ products, isLoading, isError, refetch, storeId, storePage, }: { products: HorizontalProduct[]; isLoading: boolean; isError: boolean; refetch: () => void; storeId?: string; storePage?: boolean; }) => { const scrollContainerRef = useRef(null); const [showLeftButton, setShowLeftButton] = useState(false); const [showRightButton, setShowRightButton] = useState(false); const [currentPage, setCurrentPage] = useState(0); const totalPages = Math.ceil(products.length / 2); const checkScrollButtons = () => { if (!scrollContainerRef.current) return; const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current; // Calculate max scroll position const maxScroll = scrollWidth - clientWidth; // For RTL, scrollLeft might be negative or start from max // Check if we can scroll in each direction const canScrollRight = Math.abs(scrollLeft) > 100; const canScrollLeft = Math.abs(scrollLeft) < maxScroll - 100; setShowRightButton(canScrollRight); setShowLeftButton(canScrollLeft); // Calculate current page based on scroll position const page = Math.round(Math.abs(scrollLeft) / clientWidth); setCurrentPage(page); }; useEffect(() => { // Small delay to ensure content is rendered const timer = setTimeout(() => { checkScrollButtons(); }, 100); const container = scrollContainerRef.current; if (container) { container.addEventListener("scroll", checkScrollButtons); window.addEventListener("resize", checkScrollButtons); return () => { container.removeEventListener("scroll", checkScrollButtons); window.removeEventListener("resize", checkScrollButtons); }; } return () => clearTimeout(timer); }, [products]); const scrollToNext = () => { if (!scrollContainerRef.current) return; const container = scrollContainerRef.current; const scrollAmount = container.clientWidth; container.scrollBy({ left: scrollAmount, behavior: "smooth" }); }; const scrollToPrev = () => { if (!scrollContainerRef.current) return; const container = scrollContainerRef.current; const scrollAmount = container.clientWidth; container.scrollBy({ left: -scrollAmount, behavior: "smooth" }); }; if (isLoading) { return ; } if (isError) { return (
); } if (products.length === 0) { return null; } return (
{/* Scroll Container */}
{products.map((product, index) => (
{/* Single Image Display */} {/* Discount badge */} {product.discountPercent && product.discountPercent !== 0 && ( )} {/* Overlay info */}
{/* Title */}

{product.title}

{/* Price */}
{product.discountPrice && (

{`${product.discountPrice.toLocaleString()}`} تومان

)} {product.basePrice && product.discountPercent ? (

{product.basePrice.toLocaleString()}

) : null}
))}
{/* Navigation Buttons Row */} {products.length > 2 && (
{/* Dots indicator */}
{Array.from({ length: totalPages }).map((_, i) => (
))}
)}
); }; // Simple thumbnail component - shows only first image with count badge const ProductThumbnail = ({ image, imageCount, title, }: { image?: string; imageCount: number; title?: string; }) => { return ( <> {title { e.currentTarget.src = placeholderImage; e.currentTarget.style.objectFit = "contain"; e.currentTarget.className = "w-full h-full object-contain bg-GRAY4"; }} /> {/* Image count badge - only show if more than 1 image */} {imageCount > 1 && (
{imageCount}
)} ); }; const DiscountBadge = ({ discountPercent }: { discountPercent?: number }) => { return (

{discountPercent}

discount-red
); }; const HorizontalSkeleton = () => { return (
{Array(6) .fill(1) .map((_, index) => ( ))}
); }; export default HorizontalProductList;