49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from "react";
|
|
import Image from "next/image";
|
|
import { IconZoomInFilled } from "@tabler/icons-react";
|
|
|
|
interface ProjectImageProps {
|
|
src: string;
|
|
alt: string;
|
|
caption?: string;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
export default function ProjectImage({ src, alt, caption, onClick }: ProjectImageProps) {
|
|
const [isHovered, setIsHovered] = useState(false);
|
|
|
|
const handleMouseEnter = () => {
|
|
setIsHovered(true);
|
|
};
|
|
|
|
const handleMouseLeave = () => {
|
|
setIsHovered(false);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className="relative cursor-pointer"
|
|
onMouseEnter={handleMouseEnter}
|
|
onMouseLeave={handleMouseLeave}
|
|
onClick={onClick}
|
|
>
|
|
<Image
|
|
src={src}
|
|
alt={alt}
|
|
width={1200}
|
|
height={750}
|
|
className={`h-auto w-full rounded-lg border border-neutral-800`}
|
|
/>
|
|
<div className="flex items-center justify-center pt-2">
|
|
<p className="text-sm text-neutral-500">{caption ?? alt}</p>
|
|
</div>
|
|
|
|
<div className={`pointer-events-none absolute inset-0 z-100 hidden md:flex transition-opacity duration-300 justify-center items-center w-full h-full`}>
|
|
{isHovered && <IconZoomInFilled size={32} className="text-neutral-300" />}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|