import { randomString } from '@/lib/random' import { cn } from '@/lib/utils' import logger from '@/lib/logger' import { useContentPolicy } from '@/providers/ContentPolicyProvider' import modalManager from '@/services/modal-manager.service' import { TImetaInfo } from '@/types' import { ReactNode, useEffect, useMemo, useState } from 'react' import { createPortal } from 'react-dom' import Lightbox from 'yet-another-react-lightbox' import Zoom from 'yet-another-react-lightbox/plugins/zoom' import Image from '../Image' import ImageWithLightbox from '../ImageWithLightbox' export default function ImageGallery({ className, images, start = 0, end = images.length, mustLoad = false }: { className?: string images: TImetaInfo[] start?: number end?: number mustLoad?: boolean }) { const id = useMemo(() => `image-gallery-${randomString()}`, []) const { autoLoadMedia } = useContentPolicy() const [index, setIndex] = useState(-1) useEffect(() => { if (index >= 0) { modalManager.register(id, () => { setIndex(-1) }) } else { modalManager.unregister(id) } }, [index]) const handlePhotoClick = (event: React.MouseEvent, current: number) => { event.stopPropagation() event.preventDefault() const newIndex = start + current logger.debug('[ImageGallery] Click:', { start, current, newIndex, totalImages: images.length, displayImages: displayImages.length }) setIndex(newIndex) } const displayImages = images.slice(start, end) if (!mustLoad && !autoLoadMedia) { return displayImages.map((image, i) => ( )) } let imageContent: ReactNode | null = null if (displayImages.length === 1) { imageContent = ( handlePhotoClick(e, 0)} /> ) } else if (displayImages.length === 2 || displayImages.length === 4) { imageContent = (
{displayImages.map((image, i) => ( handlePhotoClick(e, i)} /> ))}
) } else { imageContent = (
{displayImages.map((image, i) => ( handlePhotoClick(e, i)} /> ))}
) } return (
{imageContent} {index >= 0 && createPortal(
e.stopPropagation()}> { const slides = images.map(({ url, alt }) => ({ src: url, alt: alt || url })) logger.debug('[ImageGallery] Lightbox slides:', { index, slidesCount: slides.length, slides }) return slides })()} plugins={[Zoom]} open={index >= 0} close={() => setIndex(-1)} controller={{ closeOnBackdropClick: true, closeOnPullUp: true, closeOnPullDown: true }} styles={{ toolbar: { paddingTop: '2.25rem' } }} carousel={{ finite: false }} />
, document.body )}
) }