"use client" import { useEffect, useRef, useState, useMemo, useCallback } from "react" import type { AssetResponse } from "@/lib/types" import type { DateGroup } from "@/lib/timeline" import { PhotoCard } from "./photo-card" import { ImageViewer } from "./image-viewer" import { AddToAlbumDialog } from "./add-to-album-dialog" import { Button } from "@/components/ui/button" import { Spinner } from "@/components/ui/spinner" import { ImagePlusIcon, XIcon, CheckSquareIcon } from "lucide-react" interface PhotoGridProps { groups: DateGroup[] isLoading: boolean hasMore: boolean onLoadMore: () => void onRemoveAsset?: (assetId: string) => void } export function PhotoGrid({ groups, isLoading, hasMore, onLoadMore, onRemoveAsset, }: PhotoGridProps) { const sentinelRef = useRef(null) const [selectedIndex, setSelectedIndex] = useState(null) const [selecting, setSelecting] = useState(false) const [selectedIds, setSelectedIds] = useState>(new Set()) const [albumDialogOpen, setAlbumDialogOpen] = useState(false) const allAssets = useMemo( () => groups.flatMap((g) => g.assets), [groups], ) const toggleSelect = useCallback((id: string, selected: boolean) => { setSelectedIds((prev) => { const next = new Set(prev) if (selected) next.add(id) else next.delete(id) return next }) }, []) const exitSelection = useCallback(() => { setSelecting(false) setSelectedIds(new Set()) }, []) useEffect(() => { const el = sentinelRef.current if (!el) return const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) onLoadMore() }, { rootMargin: "200px" }, ) observer.observe(el) return () => observer.disconnect() }, [onLoadMore]) if (allAssets.length === 0 && !isLoading) { return (
No photos yet. Upload some to get started.
) } let flatIndex = 0 return (
{/* Selection toolbar */} {selecting && (
{selectedIds.size} selected
{onRemoveAsset && selectedIds.size > 0 && ( )}
)} {!selecting && allAssets.length > 0 && (
)}
{groups.map((group) => { const startIndex = flatIndex flatIndex += group.assets.length return (

{group.label}

{group.assets.map((asset, j) => ( toggleSelect(asset.id, sel)} onClick={() => setSelectedIndex(startIndex + j)} /> ))}
) })} {hasMore &&
} {isLoading && (
)}
{selectedIndex !== null && ( setSelectedIndex(null)} /> )} { setAlbumDialogOpen(open) if (!open) exitSelection() }} />
) }