"use client" ;
import { useState } from "react" ;
import {
Image as ImageIcon,
Download,
ChevronLeft,
ChevronRight,
} from "lucide-react" ;
import { Button } from "@/components/ui/button" ;
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog" ;
import { cn } from "@/lib/utils" ;
type ImageItem = {
id : string ;
src : string ;
alt : string ;
filename : string ;
};
const sampleImages : ImageItem [] = [
{
id: "1" ,
src: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop" ,
alt: "Mountain landscape" ,
filename: "mountain-landscape.jpg" ,
},
{
id: "2" ,
src: "https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=1200&h=800&fit=crop" ,
alt: "Nature scenery" ,
filename: "nature-scenery.jpg" ,
},
{
id: "3" ,
src: "https://images.unsplash.com/photo-1447752875215-b2761acb3c5d?w=1200&h=800&fit=crop" ,
alt: "Forest path" ,
filename: "forest-path.jpg" ,
},
];
export const title = "React Dialog Block Image Preview" ;
export default function DialogImagePreview () {
const [ open , setOpen ] = useState ( false );
const [ currentIndex , setCurrentIndex ] = useState ( 0 );
const currentImage = sampleImages[currentIndex];
const handlePrevious = () => {
setCurrentIndex (( prev ) => (prev - 1 + sampleImages. length ) % sampleImages. length );
};
const handleNext = () => {
setCurrentIndex (( prev ) => (prev + 1 ) % sampleImages. length );
};
const handleDownload = () => {
const link = document. createElement ( "a" );
link.href = currentImage.src;
link.download = currentImage.filename;
link. click ();
};
return (
< Dialog open = {open} onOpenChange = {setOpen}>
< div className = "flex min-h-[350px] items-center justify-center" >
< DialogTrigger asChild >
< Button variant = "outline" >
< ImageIcon className = "mr-2 h-4 w-4" />
Preview Images
</ Button >
</ DialogTrigger >
</ div >
< DialogContent className = "sm:max-w-md p-0 gap-0 overflow-hidden" >
< DialogHeader className = "p-4 pb-0" >
< DialogTitle className = "flex items-center gap-2" >
< ImageIcon className = "h-5 w-5" />
Image Preview
</ DialogTitle >
< DialogDescription >
{currentImage.filename} · {currentIndex + 1 } of {sampleImages. length }
</ DialogDescription >
</ DialogHeader >
< div className = "p-4 space-y-4" >
{ /* Image */ }
< div className = "relative aspect-video rounded-lg border overflow-hidden" >
< img
src = {currentImage.src}
alt = {currentImage.alt}
className = "w-full h-full object-cover"
/>
{sampleImages. length > 1 && (
<>
< Button
variant = "ghost"
size = "icon"
className = "absolute left-2 top-1/2 -translate-y-1/2 h-8 w-8 rounded-full bg-background/80"
onClick = {handlePrevious}
>
< ChevronLeft className = "h-4 w-4" />
</ Button >
< Button
variant = "ghost"
size = "icon"
className = "absolute right-2 top-1/2 -translate-y-1/2 h-8 w-8 rounded-full bg-background/80"
onClick = {handleNext}
>
< ChevronRight className = "h-4 w-4" />
</ Button >
</>
)}
</ div >
{ /* Thumbnails */ }
{sampleImages. length > 1 && (
< div className = "flex justify-center gap-2" >
{sampleImages. map (( image , index ) => (
< button
key = {image.id}
onClick = {() => setCurrentIndex (index)}
className = { cn (
"w-12 h-12 rounded-lg overflow-hidden border-2 transition-colors" ,
currentIndex === index
? "border-primary"
: "border-transparent hover:border-border"
)}
>
< img
src = {image.src}
alt = {image.alt}
className = "w-full h-full object-cover"
/>
</ button >
))}
</ div >
)}
{ /* Download Button */ }
< Button variant = "outline" onClick = {handleDownload} className = "w-full" >
< Download className = "mr-2 h-4 w-4" />
Download
</ Button >
</ div >
</ DialogContent >
</ Dialog >
);
}