'use client'; import { useState } from 'react'; import { ChevronLeftIcon, ImagesIcon, XIcon } from 'lucide-react'; import { AnimatePresence, motion } from 'motion/react'; import { type GeneratedImage, useGeneratedImages } from '@/hooks/useGeneratedImages'; import { cn } from '@/lib/shadcn/utils'; const MotionPanel = motion.create('div'); const MotionOverlay = motion.create('div'); interface ThumbnailProps { image: GeneratedImage; onClick: () => void; } function Thumbnail({ image, onClick }: ThumbnailProps) { return ( {/* eslint-disable-next-line @next/next/no-img-element */} ); } interface FullImageViewProps { image: GeneratedImage; onBack: () => void; } function FullImageView({ image, onBack }: FullImageViewProps) { return ( All images {/* eslint-disable-next-line @next/next/no-img-element */} {image.prompt && {image.prompt}} ); } /** * Floating gallery button + slide-in panel for all agent-generated images. * The button appears once at least one image has been generated. */ export function ImageGallery() { const images = useGeneratedImages(); const [open, setOpen] = useState(false); const [selected, setSelected] = useState(null); if (images.length === 0) return null; return ( <> {/* Floating trigger button */} {!open && ( setOpen(true)} aria-label="View generated images" className={cn( 'relative flex items-center justify-center rounded-full p-3', 'bg-background border-input/50 border shadow-lg', 'hover:bg-accent focus-visible:ring-ring transition-colors focus-visible:ring-2 focus-visible:outline-none' )} > {images.length} )} {/* Gallery panel + backdrop */} {open && ( <> { setSelected(null); setOpen(false); }} /> {/* Header */} Generated images {images.length} {images.length === 1 ? 'image' : 'images'} { setSelected(null); setOpen(false); }} aria-label="Close gallery" className="hover:bg-accent focus-visible:ring-ring rounded-full p-1.5 transition-colors focus-visible:ring-2 focus-visible:outline-none" > {/* Content */} {selected ? ( setSelected(null)} /> ) : ( {[...images].reverse().map((img) => ( setSelected(img)} /> ))} )} > )} > ); }
{image.prompt}
{images.length} {images.length === 1 ? 'image' : 'images'}