import React, { useRef, useState, useEffect } from "react"; import { ContentItem } from "../lib/types"; import { useNavigate } from "react-router-dom"; import { ChevronLeft, ChevronRight, Star } from "lucide-react"; import { cn } from "@/lib/utils"; import { useIsMobile } from "@/hooks/use-mobile"; import { useMyList } from "@/hooks/use-my-list"; import { supabase } from "@/integrations/supabase/client"; import { useUrdf } from "@/hooks/useUrdf"; interface CarouselProps { title: string; items: ContentItem[]; className?: string; } const Carousel: React.FC = ({ title, items, className }) => { const carouselRef = useRef(null); const navigate = useNavigate(); const isMobile = useIsMobile(); const { myList, addToMyList, removeFromMyList, isInMyList } = useMyList(); const [imageUrls, setImageUrls] = useState>({}); const { urdfProcessor, processUrdfFiles } = useUrdf(); // Fetch image URLs for all items useEffect(() => { const fetchImages = async () => { const urls: Record = {}; for (const item of items) { if ( item.imageUrl && !item.imageUrl.startsWith("http") && !item.imageUrl.startsWith("data:") ) { try { // Get public URL for the image const { data, error } = await supabase.storage .from("urdf-images") .createSignedUrl(item.imageUrl, 3600); // 1 hour expiry if (data && !error) { urls[item.id] = data.signedUrl; } else { // Fallback to placeholder urls[item.id] = "/placeholder.svg"; } } catch (error) { console.error(`Error fetching image for ${item.id}:`, error); urls[item.id] = "/placeholder.svg"; } } else { // For URLs that are already full URLs or data URIs urls[item.id] = item.imageUrl || "/placeholder.svg"; } } setImageUrls(urls); }; if (items.length > 0) { fetchImages(); } }, [items]); const handleScrollLeft = () => { if (carouselRef.current) { const scrollAmount = carouselRef.current.offsetWidth / 4.1; carouselRef.current.scrollBy({ left: -scrollAmount, behavior: "smooth" }); } }; const handleScrollRight = () => { if (carouselRef.current) { const scrollAmount = carouselRef.current.offsetWidth / 4.1; carouselRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" }); } }; const handleItemClick = async (item: ContentItem) => { // Only navigate to the content detail page, let the detail page handle loading navigate(`/content/${item.id}`); // We've removed the URDF loading here to prevent duplication with ContentDetail's loading }; const handleStarClick = (e: React.MouseEvent, item: ContentItem) => { e.stopPropagation(); // Prevent navigation on star click if (isInMyList(item.id)) { removeFromMyList(item.id); } else { addToMyList(item); } }; // If no items, don't render the carousel if (items.length === 0) return null; return (
{items.map((item) => (
handleItemClick(item)} >
{/* Image container with darker overlay on hover */}
{item.title}
{/* Star button */}
handleStarClick(e, item)} >
{/* Title overlay - visible on hover without gradient */}

{item.title}

))}
{/* Scroll buttons - changed to always visible */}
); }; export default Carousel;