first commit

This commit is contained in:
mstfyldz
2026-06-03 03:59:46 +03:00
parent 5882fc12c1
commit bba389b513
30 changed files with 3153 additions and 149 deletions
+162
View File
@@ -0,0 +1,162 @@
"use client";
import { useTranslations } from 'next-intl';
import { motion, AnimatePresence } from 'framer-motion';
import { Instagram } from '@/components/InstagramIcon';
import { useState, useEffect } from 'react';
import { X, ChevronLeft, ChevronRight } from 'lucide-react';
export default function Gallery() {
const t = useTranslations('Gallery');
const images = Array.from({ length: 12 }).map((_, i) => ({
id: i,
src: `https://picsum.photos/600/${400 + (i % 5) * 50}?random=${30 + i}`,
alt: `Gallery ${i + 1}`,
}));
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
// Close lightbox on escape key
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') setSelectedIndex(null);
if (e.key === 'ArrowRight' && selectedIndex !== null) {
setSelectedIndex((prev) => (prev !== null ? (prev + 1) % images.length : null));
}
if (e.key === 'ArrowLeft' && selectedIndex !== null) {
setSelectedIndex((prev) => (prev !== null ? (prev - 1 + images.length) % images.length : null));
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [selectedIndex, images.length]);
return (
<section id="gallery" className="py-24 bg-white text-midnight">
<div className="container mx-auto px-6 lg:px-12">
{/* Header */}
<div className="flex flex-col md:flex-row justify-between items-end mb-10">
<motion.div
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
>
<span className="text-xs tracking-[0.4em] uppercase font-black text-coral mb-3 block">
Fotoğraflar
</span>
<h2 className="font-heading text-5xl md:text-6xl font-black text-midnight">
{t('title')}
</h2>
</motion.div>
<motion.a
initial={{ opacity: 0, x: 20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
href="https://www.instagram.com/kozmosbeach/"
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 px-5 py-2.5 rounded-full border border-coral/30 text-coral font-bold text-sm hover:bg-coral hover:text-white transition-all"
>
<Instagram size={15} />
{t('follow_instagram')}
</motion.a>
</div>
{/* Masonry grid */}
<div className="columns-1 sm:columns-2 md:columns-3 lg:columns-4 gap-3 space-y-3">
{images.map((img, index) => (
<motion.div
key={img.id}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: (index % 4) * 0.07 }}
onClick={() => setSelectedIndex(index)}
className="relative rounded-2xl overflow-hidden group break-inside-avoid cursor-pointer"
>
<img
src={img.src}
alt={img.alt}
className="w-full h-auto object-cover transition-transform duration-700 group-hover:scale-105"
loading="lazy"
/>
{/* Coral gradient overlay */}
<div
className="absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
style={{
background:
'linear-gradient(135deg, rgba(255,90,54,0.55), rgba(0,191,165,0.4))',
}}
/>
{/* Plus icon */}
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<span className="text-white text-4xl font-thin select-none">+</span>
</div>
</motion.div>
))}
</div>
</div>
{/* Lightbox Overlay */}
<AnimatePresence>
{selectedIndex !== null && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-[100] flex items-center justify-center bg-midnight/95 backdrop-blur-md"
>
{/* Close Button */}
<button
onClick={() => setSelectedIndex(null)}
className="absolute top-6 right-6 z-[110] text-white/70 hover:text-white transition-colors"
>
<X size={36} />
</button>
{/* Left/Right Navigation */}
<button
onClick={(e) => {
e.stopPropagation();
setSelectedIndex((selectedIndex - 1 + images.length) % images.length);
}}
className="absolute left-4 md:left-10 z-[110] p-3 rounded-full bg-white/10 text-white hover:bg-white/20 transition-all"
>
<ChevronLeft size={30} />
</button>
<button
onClick={(e) => {
e.stopPropagation();
setSelectedIndex((selectedIndex + 1) % images.length);
}}
className="absolute right-4 md:right-10 z-[110] p-3 rounded-full bg-white/10 text-white hover:bg-white/20 transition-all"
>
<ChevronRight size={30} />
</button>
{/* Image */}
<motion.div
key={selectedIndex}
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
transition={{ type: "spring", damping: 25, stiffness: 300 }}
className="relative max-w-5xl w-full h-[80vh] px-4 md:px-24"
onClick={(e) => e.stopPropagation()}
>
<img
src={images[selectedIndex].src}
alt={images[selectedIndex].alt}
className="w-full h-full object-contain drop-shadow-2xl"
/>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</section>
);
}