Files
aydogannakliyat/components/FleetGallery.tsx

141 lines
5.1 KiB
TypeScript

"use client";
import { useState } from "react";
import Image from "next/image";
import { motion, AnimatePresence } from "framer-motion";
import { X, ChevronLeft, ChevronRight } from "lucide-react";
interface FleetGalleryProps {
images: string[];
}
export function FleetGallery({ images }: FleetGalleryProps) {
const [selectedImage, setSelectedImage] = useState<number | null>(null);
const nextImage = () => {
if (selectedImage !== null) {
setSelectedImage((selectedImage + 1) % images.length);
}
};
const prevImage = () => {
if (selectedImage !== null) {
setSelectedImage((selectedImage - 1 + images.length) % images.length);
}
};
return (
<section className="py-24 bg-background px-6 md:px-12">
<div className="max-w-7xl mx-auto">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className="mb-12"
>
<span className="text-primary font-headline font-bold text-xs tracking-[0.3em] uppercase mb-2 block">
SAHADAN KARELER
</span>
<h2 className="text-4xl md:text-5xl font-black text-on-surface uppercase tracking-tighter leading-none">
FİLOMUZ <span className="text-primary">AKSİYONDA</span>
</h2>
</motion.div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{images.map((src, index) => (
<motion.div
key={src}
initial={{ opacity: 0, scale: 0.9 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1 }}
whileHover={{ scale: 0.98 }}
className="relative aspect-square cursor-pointer overflow-hidden group bg-surface-container-low"
onClick={() => setSelectedImage(index)}
>
<Image
src={src}
alt={`Fleet image ${index + 1}`}
fill
sizes="(max-width: 768px) 50vw, 25vw"
className="object-cover transition-transform duration-500 group-hover:scale-110 grayscale group-hover:grayscale-0"
/>
<div className="absolute inset-0 bg-primary/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
<div className="w-12 h-12 rounded-full bg-white/10 backdrop-blur-md flex items-center justify-center border border-white/20">
<div className="w-1 h-4 bg-white rounded-full"></div>
<div className="w-4 h-1 bg-white rounded-full absolute"></div>
</div>
</div>
</motion.div>
))}
</div>
</div>
<AnimatePresence>
{selectedImage !== null && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/95 backdrop-blur-sm p-4 md:p-12"
onClick={() => setSelectedImage(null)}
>
<motion.button
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
className="absolute top-8 right-8 text-white hover:text-primary transition-colors z-[110]"
onClick={(e) => {
e.stopPropagation();
setSelectedImage(null);
}}
>
<X size={40} strokeWidth={1} />
</motion.button>
<button
className="absolute left-4 md:left-8 text-white hover:text-primary transition-colors z-[110]"
onClick={(e) => {
e.stopPropagation();
prevImage();
}}
>
<ChevronLeft size={60} strokeWidth={1} />
</button>
<button
className="absolute right-4 md:right-8 text-white hover:text-primary transition-colors z-[110]"
onClick={(e) => {
e.stopPropagation();
nextImage();
}}
>
<ChevronRight size={60} strokeWidth={1} />
</button>
<motion.div
layoutId={images[selectedImage]}
className="relative w-full h-full flex items-center justify-center"
onClick={(e) => e.stopPropagation()}
>
<div className="relative w-full h-full max-w-5xl max-h-[80vh]">
<Image
src={images[selectedImage]}
alt="Full size fleet image"
fill
className="object-contain"
sizes="100vw"
priority
/>
</div>
</motion.div>
<div className="absolute bottom-10 left-1/2 -translate-x-1/2 text-white/50 font-label text-xs tracking-widest uppercase">
{selectedImage + 1} / {images.length}
</div>
</motion.div>
)}
</AnimatePresence>
</section>
);
}