Files
digicraft-fe/components/ZoomableImage.tsx
Fahri Can Seçer 6e3bee17ef
Some checks failed
Deploy Frontend / deploy (push) Has been cancelled
main
2026-02-05 01:34:13 +03:00

107 lines
4.8 KiB
TypeScript

import React, { useState } from 'react';
import { GlassMagnifier } from 'react-image-magnifiers';
interface ZoomableImageProps {
src: string;
alt: string;
className?: string;
magnifierSize?: string;
zoomLevel?: number;
children?: React.ReactNode;
disabled?: boolean; // New prop to prevent zoom on click
}
export const ZoomableImage: React.FC<ZoomableImageProps> = ({
src,
alt,
className = "",
magnifierSize = "30%",
zoomLevel = 2.5,
children,
disabled = false
}) => {
const [isOpen, setIsOpen] = useState(false);
const toggleModal = (e: React.MouseEvent) => {
if (disabled) return; // Don't open if disabled
e.stopPropagation();
setIsOpen(!isOpen);
};
return (
<>
{/* Thumbnail trigger */}
<div
className={`cursor-zoom-in relative group ${className}`}
onClick={toggleModal}
title="Click to zoom"
>
<img
src={src}
alt={alt}
className="w-full h-full object-cover" // Changed to object-cover to match Home usage expectation or passed className? Actually lets keep original but fix usage if needed. Wait, original was w-full h-auto object-contain.
/>
{children}
{!children && (
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors flex items-center justify-center opacity-0 group-hover:opacity-100">
<span className="bg-white/80 text-stone-900 p-2 rounded-full shadow-lg backdrop-blur-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
</span>
</div>
)}
</div>
{/* Modal */}
{isOpen && (
<div
className="fixed inset-0 z-[9999] bg-stone-900/95 backdrop-blur-md flex items-center justify-center p-8 animate-in fade-in duration-200"
onClick={() => setIsOpen(false)}
>
<div className="relative w-full h-full max-w-7xl flex items-center justify-center" onClick={(e) => e.stopPropagation()}>
<button
onClick={() => setIsOpen(false)}
className="absolute -top-6 -right-6 md:top-0 md:-right-12 text-white/50 hover:text-white transition-colors p-2 z-50"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-8 h-8">
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
</button>
<div className="w-full h-full flex items-center justify-center rounded-lg overflow-hidden">
<GlassMagnifier
imageSrc={src}
imageAlt={alt}
magnifierSize={magnifierSize}
magnifierBorderSize={2}
magnifierBorderColor="rgba(255, 255, 255, 0.5)"
square={false}
allowOverflow={true}
style={{
width: 'auto',
height: 'auto',
maxWidth: '100%',
maxHeight: '90vh',
display: 'block'
}}
imageStyle={{
width: 'auto',
height: 'auto',
maxWidth: '100%',
maxHeight: '90vh',
objectFit: 'contain'
}}
/>
</div>
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 bg-black/50 text-white px-4 py-2 rounded-full text-xs font-medium backdrop-blur-md pointer-events-none z-50">
Hover to magnify Click outside to close
</div>
</div>
</div>
)}
</>
);
};