Newer
Older
My-Portfolio / frontend / src / components / sections / projects / Slideshow.jsx
import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import LeftArrow from "../../../assets/buttons/LeftArrow.svg";
import RightArrow from "../../../assets/buttons/RightArrow.svg";
import { X } from "lucide-react";
import Heading from "../../Heading";

const Slideshow = ({ images, projectName }) => {
  const [currentIndex, setCurrentIndex] = useState(0);
  const [isFullscreen, setIsFullscreen] = useState(false);

  if (!images || images.length === 0) return null; // No images available

  const preloadImage = (index) => {
    const img = new Image();
    img.src = images[index];
  };

  const nextSlide = () => {
    const nextIndex = (currentIndex + 1) % images.length;
    preloadImage(nextIndex);
    setCurrentIndex(nextIndex);
  };

  const prevSlide = () => {
    const prevIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
    preloadImage(prevIndex);
    setCurrentIndex(prevIndex);
  };

  return (
    <div className="relative w-full max-w-6xl mx-auto my-10">
      <Heading
        title={`${projectName} Screenshots`}
        className="text-2xl sm:text-3xl lg:text-5xl font-semibold text-center mb-10"
        highlightWords={[{ word: projectName, color: "text-orange-500" }]}
      />

      {/* Slideshow Thumbnail */}
      <div
        className="relative w-full h-max overflow-hidden shadow-lg shadow-black rounded-lg cursor-pointer"
        onClick={() => setIsFullscreen(true)}
      >
        <AnimatePresence mode="wait">
          <motion.img
            key={currentIndex}
            src={images[currentIndex]}
            alt={`Slide ${currentIndex}`}
            className="object-cover w-full h-full rounded-lg"
            initial={{ opacity: 0, x: 50 }}
            animate={{ opacity: 1, x: 0 }}
            exit={{ opacity: 0, x: -50 }}
            transition={{ duration: 0.5 }}
          />
        </AnimatePresence>

        {/* Navigation Buttons */}
        <button
          onClick={(e) => {
            e.stopPropagation();
            prevSlide();
          }}
          className="absolute left-0 top-1/2 transform -translate-y-1/2 bg-black/50 p-2 rounded-full"
        >
          <img src={LeftArrow} alt="Previous" />
        </button>

        <button
          onClick={(e) => {
            e.stopPropagation();
            nextSlide();
          }}
          className="absolute right-0 top-1/2 transform -translate-y-1/2 bg-black/50 p-2 rounded-full"
        >
          <img src={RightArrow} alt="Next" />
        </button>
      </div>

      {/* Fullscreen Mode*/}
      {isFullscreen && (
        <div className="fixed inset-0 bg-black bg-opacity-90 flex items-center justify-center z-50">
          <motion.div
            initial={{ scale: 0.8, opacity: 0 }}
            animate={{ scale: 1, opacity: 1 }}
            exit={{ scale: 0.8, opacity: 0 }}
            transition={{ duration: 0.3 }}
            className="relative max-w-full"
          >
            <motion.img
              key={currentIndex}
              src={images[currentIndex]}
              alt={`Slide ${currentIndex}`}
              className="object-cover w-full rounded-lg"
            />

            {/* Close Button */}
            <button
              onClick={() => setIsFullscreen(false)}
              className="absolute top-4 right-4 bg-black/50 p-2 rounded-full text-white"
            >
              <X size={24} />
            </button>

            {/* Navigation Buttons */}
            <button
              onClick={prevSlide}
              className="absolute left-4 top-1/2 transform -translate-y-1/2 bg-black/50 p-2 rounded-full"
            >
              <img src={LeftArrow} alt="Previous" />
            </button>

            <button
              onClick={nextSlide}
              className="absolute right-4 top-1/2 transform -translate-y-1/2 bg-black/50 p-2 rounded-full"
            >
              <img src={RightArrow} alt="Next" />
            </button>
          </motion.div>
        </div>
      )}
    </div>
  );
};

export default Slideshow;