"use client" import * as Dialog from "@radix-ui/react-dialog" import { AnimatePresence, motion } from "framer-motion" import Image from "next/image" import React, { useState } from "react" import { ChevronRightIcon } from "@/components/Icons" import ArrowRightIcon from "@/components/Icons/ArrowRight" import CloseIcon from "@/components/Icons/Close" import Button from "@/components/TempDesignSystem/Button" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import styles from "./Lightbox.module.css" import { FullViewProps, GalleryProps, LightboxProps, } from "@/types/components/lightbox/lightbox" export function Lightbox({ images, children }: LightboxProps) { const [isOpen, setIsOpen] = useState(false) const [selectedImageIndex, setSelectedImageIndex] = useState(0) const [isFullView, setIsFullView] = useState(false) const handleOpenChange = (open: boolean) => { if (!open) { setTimeout(() => { setIsOpen(false) setSelectedImageIndex(0) setIsFullView(false) }, 300) // 300ms delay } else { setIsOpen(true) } } const handleNext = () => { setSelectedImageIndex((prevIndex) => (prevIndex + 1) % images.length) } const handlePrev = () => { setSelectedImageIndex( (prevIndex) => (prevIndex - 1 + images.length) % images.length ) } const triggerElement = React.Children.map( children, function mapChild(child): React.ReactNode { if (React.isValidElement(child)) { if (child.props.id === "lightboxTrigger") { return React.cloneElement(child, { onClick: () => setIsOpen(true), } as React.HTMLAttributes) } else if (child.props.children) { return React.cloneElement(child, { children: React.Children.map(child.props.children, mapChild), } as React.HTMLAttributes) } } return child } ) return ( <> {triggerElement} {isOpen && ( {isFullView ? ( setIsFullView(false)} onNext={handleNext} onPrev={handlePrev} currentIndex={selectedImageIndex} totalImages={images.length} /> ) : ( setIsOpen(false)} onSelectImage={(image) => { setSelectedImageIndex( images.findIndex((img) => img.url === image.url) ) }} onImageClick={() => setIsFullView(true)} selectedImage={images[selectedImageIndex]} /> )} )} ) } function Gallery({ images, onClose, onSelectImage, onImageClick, selectedImage, }: GalleryProps) { const mainImage = selectedImage || images[0] const mainImageIndex = images.findIndex((img) => img.url === mainImage.url) function getThumbImages() { const thumbs = [] for (let i = 1; i <= 5; i++) { const index = (mainImageIndex + i) % images.length thumbs.push(images[index]) } return thumbs } const handleNext = () => { const nextIndex = (mainImageIndex + 1) % images.length onSelectImage(images[nextIndex]) } const handlePrev = () => { const prevIndex = (mainImageIndex - 1 + images.length) % images.length onSelectImage(images[prevIndex]) } return (
{/* Desktop Gallery */}
{mainImage.alt}
{mainImage.alt}
{getThumbImages().map((image, index) => ( onSelectImage(image)} initial={{ opacity: 0, x: 50 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -50 }} transition={{ duration: 0.2, delay: index * 0.05 }} > {image.alt} ))}
{/* Mobile Gallery */}
{images.map((image, index) => ( onImageClick()} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.3, delay: index * 0.05 }} > {image.alt} ))}
) } function FullView({ image, onClose, onNext, onPrev, currentIndex, totalImages, }: FullViewProps) { return (
{`${currentIndex + 1} / ${totalImages}`}
{image.alt}
{image.alt}
) }