Untitled
unknown
plain_text
2 months ago
7.9 kB
5
Indexable
// components/gallery.tsx export function Gallery({ sections }: GalleryProps) { const [isDialogOpen, setIsDialogOpen] = useState(false); const [isDownloading, setIsDownloading] = useState(false); const [isFullImageLoaded, setIsFullImageLoaded] = useState(false); const [selectedTab, setSelectedTab] = useState("preview"); const [commentCounts, setCommentCounts] = useState<Record<string, number>>({}); const handleDownload = async (imageSrc: string) => { try { setIsDownloading(true); const fileName = imageSrc.split('/').pop() || 'image'; const response = await fetch(imageSrc); if (!response.ok) throw new Error('Download failed'); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); } catch (error) { console.error('Download error:', error); toast.error('Download fehlgeschlagen'); } finally { setIsDownloading(false); } }; return ( <div className="space-y-12"> {sections.map((section, sectionIndex) => ( <div key={sectionIndex} className="space-y-4"> <div className="space-y-2"> <h2 className="text-2xl font-bold">{section.title}</h2> {section.description && ( <p className="text-muted-foreground">{section.description}</p> )} </div> <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"> {section.images.map((image, imageIndex) => { const aspectRatio = image.width / image.height; const isPortrait = aspectRatio < 0.8; const isLandscape = aspectRatio > 1.2; const photoId = `${section.title}-${imageIndex}`; const commentCount = commentCounts[photoId] || 0; return ( <div key={imageIndex} className={` relative overflow-hidden rounded-lg bg-muted/30 transition-opacity duration-300 ${isPortrait ? 'row-span-2' : ''} `} style={{ aspectRatio: isPortrait ? '2/3' : isLandscape ? '16/9' : '1/1', }} > <img src={image.thumbnailSrc} alt={image.alt} className="h-full w-full object-cover" loading="lazy" /> <Dialog onOpenChange={(open) => { setIsDialogOpen(open); if (open) { setSelectedTab("preview"); setIsFullImageLoaded(false); } }}> <DialogTrigger asChild> <div className="absolute inset-0 flex items-center justify-center gap-2 bg-black/60 opacity-0 hover:opacity-100 transition-opacity duration-200 cursor-pointer"> <Button variant="secondary" size="icon" className="h-9 w-9 z-10" onClick={(e) => { e.stopPropagation(); handleDownload(image.src); }} > <Download className="h-4 w-4" /> </Button> </div> </DialogTrigger> <DialogContent className="w-[90%] h-[90vh] max-w-7xl p-4 sm:p-6"> <DialogHeader className="mb-4"> <DialogTitle>Bildvorschau</DialogTitle> <DialogDescription> Ansehen und herunterladen des Bildes in voller Auflösung </DialogDescription> </DialogHeader> <div className="flex-1 h-[calc(90vh-8rem)]"> <ImageDialog image={image} fullSizeImageSrc={image.src} thumbnailSrc={image.thumbnailSrc} photoId={photoId} commentCount={commentCount} selectedTab={selectedTab} setSelectedTab={setSelectedTab} isFullImageLoaded={isFullImageLoaded} setIsFullImageLoaded={setIsFullImageLoaded} handleDownload={handleDownload} isDownloading={isDownloading} onCommentAdded={(photoId) => { setCommentCounts(prev => ({ ...prev, [photoId]: (prev[photoId] || 0) + 1 })); }} /> </div> </DialogContent> </Dialog> {commentCount > 0 && ( <Dialog onOpenChange={(open) => { setIsDialogOpen(open); if (open) setSelectedTab("comments"); }}> <DialogTrigger asChild> <div className="absolute bottom-2 right-2 z-10"> <div className="bg-black/70 backdrop-blur-sm rounded-full px-2 py-1 flex items-center gap-1 text-white text-sm cursor-pointer hover:bg-black/80 transition-colors"> <MessageCircle className="h-4 w-4" /> <span>{commentCount}</span> </div> </div> </DialogTrigger> <DialogContent className="w-[90%] h-[90vh] max-w-7xl p-4 sm:p-6"> <DialogHeader className="mb-4"> <DialogTitle>Bildvorschau</DialogTitle> <DialogDescription> Ansehen und herunterladen des Bildes in voller Auflösung </DialogDescription> </DialogHeader> <div className="flex-1 h-[calc(90vh-8rem)]"> <ImageDialog image={image} fullSizeImageSrc={image.src} thumbnailSrc={image.thumbnailSrc} photoId={photoId} commentCount={commentCount} selectedTab={selectedTab} setSelectedTab={setSelectedTab} isFullImageLoaded={isFullImageLoaded} setIsFullImageLoaded={setIsFullImageLoaded} handleDownload={handleDownload} isDownloading={isDownloading} onCommentAdded={(photoId) => { setCommentCounts(prev => ({ ...prev, [photoId]: (prev[photoId] || 0) + 1 })); }} /> </div> </DialogContent> </Dialog> )} </div> ); })} </div> </div> ))} </div> ); }
Editor is loading...
Leave a Comment