'use client'; import { useEffect, useState } from "react"; import { IconChevronLeft, IconChevronRight, IconZoomInFilled } from "@tabler/icons-react"; import Image from "next/image"; import ImageViewer from "@/components/ui/ImageViewer"; import type { Screenshot } from "@/constants/projects"; interface ProjectCarouselProps { screenshots: Screenshot[]; } /** Milliseconds each slide stays up before auto-advancing. */ const AUTOPLAY_MS = 5000; export default function ProjectCarousel({ screenshots }: ProjectCarouselProps) { const [index, setIndex] = useState(0); const [viewerOpen, setViewerOpen] = useState(false); const [paused, setPaused] = useState(false); const [isHovered, setIsHovered] = useState(false); const len = screenshots.length; const go = (i: number) => setIndex(((i % len) + len) % len); useEffect(() => { if (len < 2 || paused || viewerOpen) return; const t = setInterval(() => setIndex((i) => (i + 1) % len), AUTOPLAY_MS); return () => clearInterval(t); }, [len, paused, viewerOpen]); if (len === 0) return null; const active = screenshots[index]; const handleButtonClick = (e: React.MouseEvent, i: number) => { e.stopPropagation(); go(i); setPaused(true); setTimeout(() => setPaused(false), AUTOPLAY_MS); }; return (
{ setPaused(true); setIsHovered(true); }} onMouseLeave={() => { setPaused(false); setIsHovered(false); }} onFocusCapture={() => setPaused(true)} onBlurCapture={() => setPaused(false)} >
setViewerOpen(true)} > {screenshots.map((shot, i) => ( {shot.alt} ))}
{isHovered && }

{active.caption ?? active.alt}

{len > 1 && (
{screenshots.map((shot, i) => (
)} {viewerOpen && ( setViewerOpen(false)} /> )}
); }