145 lines
4.7 KiB
TypeScript
145 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import Image from "next/image";
|
|
import { X } from "lucide-react";
|
|
|
|
interface BentoGalleryProps {
|
|
images: string[];
|
|
}
|
|
|
|
export default function BentoGallery({ images }: BentoGalleryProps) {
|
|
const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);
|
|
|
|
const openLightbox = (index: number) => {
|
|
setLightboxIndex(index);
|
|
};
|
|
|
|
const closeLightbox = () => {
|
|
setLightboxIndex(null);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 auto-rows-[200px] md:auto-rows-[250px]">
|
|
{/* Big Feature Image */}
|
|
{images.length > 0 && (
|
|
<div
|
|
className="relative rounded-3xl overflow-hidden group col-span-2 row-span-2 cursor-pointer h-full"
|
|
onClick={() => openLightbox(0)}
|
|
>
|
|
<Image
|
|
src={images[0]}
|
|
alt="Gallery Image 1"
|
|
fill
|
|
sizes="(max-width: 768px) 100vw, 50vw"
|
|
className="object-cover group-hover:scale-105 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
{/* Top Right */}
|
|
{images.length > 1 && (
|
|
<div
|
|
className="relative rounded-3xl overflow-hidden group col-span-2 row-span-1 cursor-pointer h-full"
|
|
onClick={() => openLightbox(1)}
|
|
>
|
|
<Image
|
|
src={images[1]}
|
|
alt="Gallery Image 2"
|
|
fill
|
|
sizes="(max-width: 768px) 100vw, 50vw"
|
|
className="object-cover group-hover:scale-105 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
{/* Middle Right 1 */}
|
|
{images.length > 2 && (
|
|
<div
|
|
className="relative rounded-3xl overflow-hidden group col-span-1 row-span-1 cursor-pointer h-full"
|
|
onClick={() => openLightbox(2)}
|
|
>
|
|
<Image
|
|
src={images[2]}
|
|
alt="Gallery Image 3"
|
|
fill
|
|
sizes="(max-width: 768px) 50vw, 25vw"
|
|
className="object-cover group-hover:scale-105 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
{/* Middle Right 2 */}
|
|
{images.length > 3 && (
|
|
<div
|
|
className="relative rounded-3xl overflow-hidden group col-span-1 row-span-1 cursor-pointer h-full"
|
|
onClick={() => openLightbox(3)}
|
|
>
|
|
<Image
|
|
src={images[3]}
|
|
alt="Gallery Image 4"
|
|
fill
|
|
sizes="(max-width: 768px) 50vw, 25vw"
|
|
className="object-cover group-hover:scale-105 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
{/* Bottom Row 1 */}
|
|
{images.length > 4 && (
|
|
<div
|
|
className="relative rounded-3xl overflow-hidden group col-span-2 md:col-span-3 row-span-1 cursor-pointer h-full"
|
|
onClick={() => openLightbox(4)}
|
|
>
|
|
<Image
|
|
src={images[4]}
|
|
alt="Gallery Image 5"
|
|
fill
|
|
sizes="(max-width: 768px) 100vw, 75vw"
|
|
className="object-cover group-hover:scale-105 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
{/* Bottom Row 2 */}
|
|
{images.length > 5 && (
|
|
<div
|
|
className="relative rounded-3xl overflow-hidden group col-span-2 md:col-span-1 row-span-1 cursor-pointer h-full"
|
|
onClick={() => openLightbox(5)}
|
|
>
|
|
<Image
|
|
src={images[5]}
|
|
alt="Gallery Image 6"
|
|
fill
|
|
sizes="(max-width: 768px) 100vw, 25vw"
|
|
className="object-cover group-hover:scale-105 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Lightbox */}
|
|
{lightboxIndex !== null && (
|
|
<div
|
|
className="fixed inset-0 z-[100] bg-dark/95 backdrop-blur-sm flex items-center justify-center p-4 cursor-zoom-out opacity-0 animate-fade-in"
|
|
style={{ animationFillMode: "forwards" }}
|
|
onClick={closeLightbox}
|
|
>
|
|
<div className="relative max-w-6xl w-full h-[85vh] aspect-auto" onClick={(e) => e.stopPropagation()}>
|
|
<Image
|
|
src={images[lightboxIndex]}
|
|
alt="Lightbox Image"
|
|
fill
|
|
sizes="100vw"
|
|
className="object-contain rounded-xl shadow-2xl"
|
|
/>
|
|
</div>
|
|
|
|
<button
|
|
className="absolute top-6 right-6 text-white/60 hover:text-white transition-colors bg-white/10 hover:bg-white/20 p-2 rounded-full"
|
|
onClick={closeLightbox}
|
|
>
|
|
<X size={28} />
|
|
</button>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|