'use client'; import * as React from 'react'; import { Loader2, Trash2 } from 'lucide-react'; import { useAuth } from '@/components/id/auth-provider'; import { fetchDocumentPhotoUrl } from '@/lib/api'; import { DocumentFullscreenViewer, DocumentPhotoThumbnail } from './document-photo-viewer'; interface DocumentPhotoGalleryProps { userId: string; token: string | null; storageKeys: string[]; readOnly?: boolean; onRemove?: (storageKey: string) => void; } export function DocumentPhotoGallery({ userId, token, storageKeys, readOnly, onRemove }: DocumentPhotoGalleryProps) { const { isPinLocked } = useAuth(); const [urls, setUrls] = React.useState>({}); const [loadingKeys, setLoadingKeys] = React.useState>(new Set()); const [viewerOpen, setViewerOpen] = React.useState(false); const [viewerIndex, setViewerIndex] = React.useState(0); React.useEffect(() => { if (!token || storageKeys.length === 0 || isPinLocked) { setUrls({}); return; } let cancelled = false; setLoadingKeys(new Set(storageKeys)); void Promise.all( storageKeys.map(async (storageKey) => { try { const response = await fetchDocumentPhotoUrl(userId, storageKey, token); return { storageKey, accessUrl: response.accessUrl }; } catch { return { storageKey, accessUrl: '' }; } }) ).then((results) => { if (cancelled) return; const next: Record = {}; for (const item of results) { if (item.accessUrl) next[item.storageKey] = item.accessUrl; } setUrls(next); setLoadingKeys(new Set()); }); return () => { cancelled = true; }; }, [isPinLocked, storageKeys.join('|'), token, userId]); const resolvedImages = storageKeys .map((storageKey) => ({ storageKey, url: urls[storageKey] })) .filter((item) => Boolean(item.url)); if (storageKeys.length === 0) return null; return ( <>
{storageKeys.map((storageKey) => (
{ const resolvedIndex = resolvedImages.findIndex((item) => item.storageKey === storageKey); if (resolvedIndex >= 0) { setViewerIndex(resolvedIndex); setViewerOpen(true); } }} /> {!readOnly && onRemove ? ( ) : null} {loadingKeys.has(storageKey) ? (
) : null}
))}
); }