Files
website/app/components/PhotoGallery.tsx
T

67 lines
3.7 KiB
TypeScript

// app/components/PhotoGallery.tsx
'use client';
import { Gallery, Item } from 'react-photoswipe-gallery';
import 'photoswipe/dist/photoswipe.css';
import Image from 'next/image';
interface GalleryImage {
src: string;
width: number;
height: number;
name: string;
}
export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
return (
<div className="bg-slate-100 dark:bg-[#0a0d11] flex justify-center w-full min-h-screen border-t border-slate-200 dark:border-white/5 transition-colors duration-300">
<Gallery>
<div className="grid grid-cols-2 lg:grid-cols-4 2xl:grid-cols-6 grid-flow-dense w-full">
{images.map((img, index) => {
const isHorizontal = img.width > img.height;
return (
<div
key={index}
className={`relative bg-slate-200 dark:bg-[#0d1117] overflow-hidden group cursor-pointer transition-colors duration-300 ${isHorizontal ? 'col-span-2' : 'col-span-1'}`}
>
<Item
original={img.src}
thumbnail={img.src}
width={img.width}
height={img.height}
alt={`Gallery image ${img.name}`}
>
{({ ref, open }) => (
<div
ref={ref as React.RefCallback<HTMLDivElement>}
onClick={open}
className="w-full h-full relative block min-h-75"
>
{/* Outer Frame - Light border in light mode, Dark in dark mode */}
<div className="absolute inset-0 border-8 border-slate-100/10 dark:border-[#0d1117]/40 transition-colors duration-300 z-10 pointer-events-none"></div>
{/* Inner Hover Frame */}
<div className="absolute inset-4 border-2 border-slate-300/50 dark:border-white/10 transition-all duration-500 z-10 pointer-events-none group-hover:scale-95 group-hover:border-[#84c0a0]/80 dark:group-hover:border-[#84c0a0]/60 [clip-path:polygon(0_calc(100%-1rem),0_100%,1rem_100%,1rem_0,0_0,0_1rem,100%_1rem,100%_0,calc(100%-1rem)_0,calc(100%-1rem)_100%,100%_100%,100%_calc(100%-1rem))]"></div>
<Image
src={img.src}
alt={`Photo of ${img.name.replace('.jpg', '')}`}
width={isHorizontal ? 1200 : 800}
height={isHorizontal ? 800 : 800}
quality={90}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="w-full h-full object-cover block transition-all duration-700 group-hover:scale-110 group-hover:opacity-100 dark:group-hover:opacity-100"
/>
</div>
)}
</Item>
</div>
);
})}
</div>
</Gallery>
</div>
);
}