Files
ember-market-frontend/components/modals/image-viewer-modal.tsx
2025-12-15 18:09:38 +00:00

99 lines
3.2 KiB
TypeScript

import { Dialog, DialogContent } from "@/components/ui/dialog";
import { ChevronLeft, ChevronRight, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useEffect } from "react";
interface ImageViewerModalProps {
isOpen: boolean;
onClose: () => void;
imageUrl: string;
onNavigate?: (direction: 'prev' | 'next') => void;
}
export function ImageViewerModal({ isOpen, onClose, imageUrl, onNavigate }: ImageViewerModalProps) {
const handleNavigation = (direction: 'prev' | 'next') => (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
onNavigate?.(direction);
};
// Add keyboard navigation
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (!onNavigate) return;
if (e.key === 'ArrowLeft') {
e.preventDefault();
onNavigate('prev');
} else if (e.key === 'ArrowRight') {
e.preventDefault();
onNavigate('next');
} else if (e.key === 'Escape') {
e.preventDefault();
onClose();
}
};
if (isOpen) {
window.addEventListener('keydown', handleKeyDown);
}
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [isOpen, onNavigate, onClose]);
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="p-0 border-none bg-black/90 max-w-[90vw] max-h-[90vh] overflow-hidden [&>button:not([id='custom-close-btn'])]:hidden">
{/* Custom close button */}
<Button
id="custom-close-btn"
variant="ghost"
size="icon"
onClick={onClose}
className="absolute top-4 right-4 z-50 bg-black/40 hover:bg-black/60 text-white rounded-full border border-white/20"
>
<X size={18} />
</Button>
<div className="relative w-[90vw] h-[90vh] mx-auto">
{/* Navigation buttons */}
{onNavigate && (
<>
<Button
variant="ghost"
size="icon"
className="absolute left-4 top-1/2 -translate-y-1/2 z-50 bg-black/40 hover:bg-black/60 text-white rounded-full w-10 h-10 border border-white/20"
onClick={handleNavigation('prev')}
>
<ChevronLeft size={24} />
</Button>
<Button
variant="ghost"
size="icon"
className="absolute right-4 top-1/2 -translate-y-1/2 z-50 bg-black/40 hover:bg-black/60 text-white rounded-full w-10 h-10 border border-white/20"
onClick={handleNavigation('next')}
>
<ChevronRight size={24} />
</Button>
</>
)}
{/* Image container - add onClick handler to close modal */}
<div
className="w-full h-full flex items-center justify-center p-4 cursor-pointer"
onClick={onClose}
>
<img
src={imageUrl}
alt="Full size image"
className="max-w-full max-h-full object-contain cursor-pointer"
loading="eager"
/>
</div>
</div>
</DialogContent>
</Dialog>
);
}