63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import Image from "next/image";
|
|
|
|
export default function ProjectShowcase({ images }: { images: string[] }) {
|
|
const [index, setIndex] = useState(0);
|
|
|
|
return (
|
|
<div className="grid grid-cols-1 lg:grid-cols-12 gap-4 h-[500px]">
|
|
{/* Main Image */}
|
|
<div className="lg:col-span-9 relative overflow-hidden rounded-3xl border border-neutral-800 bg-neutral-900 group">
|
|
<AnimatePresence mode="wait">
|
|
<motion.img
|
|
key={index}
|
|
src={images[index]}
|
|
initial={{ opacity: 0, scale: 1.05 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
exit={{ opacity: 0, scale: 0.95 }}
|
|
transition={{ duration: 0.4, ease: "easeInOut" }}
|
|
className="absolute inset-0 h-full w-full object-cover"
|
|
/>
|
|
</AnimatePresence>
|
|
|
|
{/* Subtle Overlay Label */}
|
|
<div className="absolute bottom-4 left-4 bg-black/60 backdrop-blur-md px-3 py-1.5 rounded-full border border-white/10 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
<p className="text-[10px] font-mono uppercase tracking-widest text-white/70">
|
|
View {index + 1} of {images.length}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Thumbnail Column */}
|
|
<div className="lg:col-span-3 flex lg:flex-col gap-3 overflow-x-auto lg:overflow-y-auto pr-2 custom-scrollbar">
|
|
{images.map((img, i) => (
|
|
<button
|
|
key={i}
|
|
onClick={() => setIndex(i)}
|
|
className={`relative flex-shrink-0 w-24 lg:w-full aspect-video rounded-xl border-2 transition-all overflow-hidden ${
|
|
i === index
|
|
? "border-blue-500 ring-4 ring-blue-500/10"
|
|
: "border-neutral-800 opacity-40 hover:opacity-100"
|
|
}`}
|
|
>
|
|
<Image
|
|
src={img}
|
|
className="h-full w-full object-cover"
|
|
alt={`Thumb ${i}`}
|
|
/>
|
|
{i === index && (
|
|
<motion.div
|
|
layoutId="active-thumb"
|
|
className="absolute inset-0 bg-blue-500/10 z-10"
|
|
/>
|
|
)}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|