Spaces:
Running
Running
| import React, { useState, useEffect } from 'react'; | |
| import { motion, AnimatePresence } from 'framer-motion'; | |
| import { Button } from '@/components/ui/button'; | |
| import { ChevronLeft, ChevronRight } from 'lucide-react'; | |
| const HeroSection = ({ images }) => { | |
| const [currentImageIndex, setCurrentImageIndex] = useState(0); | |
| useEffect(() => { | |
| const timer = setTimeout(() => { | |
| setCurrentImageIndex((prevIndex) => (prevIndex + 1) % images.length); | |
| }, 5000); | |
| return () => clearTimeout(timer); | |
| }, [currentImageIndex, images.length]); | |
| const handlePrev = () => { | |
| setCurrentImageIndex((prevIndex) => (prevIndex - 1 + images.length) % images.length); | |
| }; | |
| const handleNext = () => { | |
| setCurrentImageIndex((prevIndex) => (prevIndex + 1) % images.length); | |
| }; | |
| return ( | |
| <div className="relative h-[50vh] sm:h-[60vh] md:h-[70vh] lg:h-[80vh] w-full overflow-hidden shadow-lg"> | |
| <AnimatePresence initial={false}> | |
| <motion.div | |
| key={currentImageIndex} | |
| initial={{ opacity: 0, x: 100 }} | |
| animate={{ opacity: 1, x: 0 }} | |
| exit={{ opacity: 0, x: -100 }} | |
| transition={{ duration: 0.8, ease: "easeInOut" }} | |
| className="absolute inset-0 bg-cover bg-center" | |
| style={{ backgroundImage: `url(${images[currentImageIndex]})` }} | |
| /> | |
| </AnimatePresence> | |
| <div className="absolute inset-0 bg-black/30"></div> | |
| <Button | |
| variant="ghost" | |
| size="icon" | |
| onClick={handlePrev} | |
| className="absolute left-2 md:left-4 top-1/2 -translate-y-1/2 z-20 text-white hover:bg-white/20 p-2 md:p-3" | |
| > | |
| <ChevronLeft className="h-6 w-6 md:h-8 md:w-8" /> | |
| </Button> | |
| <Button | |
| variant="ghost" | |
| size="icon" | |
| onClick={handleNext} | |
| className="absolute right-2 md:right-4 top-1/2 -translate-y-1/2 z-20 text-white hover:bg-white/20 p-2 md:p-3" | |
| > | |
| <ChevronRight className="h-6 w-6 md:h-8 md:w-8" /> | |
| </Button> | |
| <div className="absolute bottom-4 left-1/2 -translate-x-1/2 z-20 flex space-x-2"> | |
| {images.map((_, index) => ( | |
| <button | |
| key={index} | |
| onClick={() => setCurrentImageIndex(index)} | |
| className={`h-2.5 w-2.5 md:h-3 md:w-3 rounded-full transition-all duration-300 ${ | |
| currentImageIndex === index ? 'bg-amber-400 scale-125' : 'bg-white/50 hover:bg-white/80' | |
| }`} | |
| aria-label={`Go to image ${index + 1}`} | |
| /> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default HeroSection; |