import { Link } from "@remix-run/react"; import { useRef, useState, useEffect, useCallback } from "react"; import { motion } from "framer-motion"; import { ChevronLeft, ChevronRight, Package, ShoppingBag } from "lucide-react"; import { Skeleton } from "./ui/skeleton"; import { ErrorState } from "./UiProvider"; interface HorizontalCollection { id?: string; title?: string; description?: string | null; coverImageUrl?: string | null; productCount?: number; } const HorizontalCollectionsList = ({ collections, isLoading, isError, refetch, showViewAllButton = false, }: { collections: HorizontalCollection[]; isLoading: boolean; isError: boolean; refetch: () => void; showViewAllButton?: boolean; }) => { const scrollContainerRef = useRef(null); const [showLeftButton, setShowLeftButton] = useState(false); const [showRightButton, setShowRightButton] = useState(false); const [currentPage, setCurrentPage] = useState(0); const totalPages = collections.length; // Helper function to calculate card width consistently const getCardWidth = useCallback(() => { // Same calculation as scrollToNext/scrollToPrev: 85vw (max 300px) + 16px gap return Math.min(window.innerWidth * 0.85, 300) + 16; }, []); const checkScrollButtons = useCallback(() => { 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 card width using the same logic as scroll functions const cardWidth = getCardWidth(); // Calculate current page based on scroll position const page = Math.round(Math.abs(scrollLeft) / cardWidth); setCurrentPage(Math.min(page, collections.length - 1)); }, [collections.length, getCardWidth]); 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); }, [collections, checkScrollButtons]); const scrollToNext = () => { if (!scrollContainerRef.current) return; const container = scrollContainerRef.current; const cardWidth = getCardWidth(); container.scrollBy({ left: cardWidth, behavior: "smooth" }); }; const scrollToPrev = () => { if (!scrollContainerRef.current) return; const container = scrollContainerRef.current; const cardWidth = getCardWidth(); container.scrollBy({ left: -cardWidth, behavior: "smooth" }); }; if (isLoading) { return ; } if (isError) { return (
); } if (collections.length === 0) { return null; } return (
{/* Scroll Container */}
{collections.map((collection, index) => (
{/* Collection Image */}
{collection.coverImageUrl ? ( {collection.title ) : (
)} {/* Product Count Badge */} {collection.productCount !== undefined && (
{collection.productCount} محصول
)}
{/* Collection Info */}

{collection.title || "بدون عنوان"}

{collection.description && (

{collection.description}

)}
))} {/* View All Button Card */} {showViewAllButton && (

مشاهده همه کالکشن‌ها

کاوش در کالکشن‌های بیشتر

مشاهده همه
)}
{/* Navigation Buttons Row (mobile only) */} {collections.length > 1 && (
{/* Dots indicator */}
{Array.from({ length: totalPages }).map((_, i) => (
))}
)}
); }; const HorizontalSkeleton = () => { return (
{Array(4) .fill(1) .map((_, index) => (
))}
); }; export default HorizontalCollectionsList;