"use client" import { useMemo, useState } from "react" import { useParams } from "next/navigation" import { useQuery, useQueryClient } from "@tanstack/react-query" import api from "@/lib/api" import { useAlbums } from "@/hooks/use-albums" import { groupByDate } from "@/lib/timeline" import type { AlbumResponse, AssetResponse } from "@/lib/types" import { PhotoGrid } from "@/components/photo-grid" import { AssetPickerDialog } from "@/components/asset-picker-dialog" import { Button } from "@/components/ui/button" import { Spinner } from "@/components/ui/spinner" import { toast } from "sonner" import { PlusIcon } from "lucide-react" export default function AlbumDetailPage() { const { id } = useParams<{ id: string }>() const qc = useQueryClient() const { addEntry, removeEntry } = useAlbums() const [pickerOpen, setPickerOpen] = useState(false) const { data: album, isLoading: albumLoading } = useQuery({ queryKey: ["album", id], queryFn: async () => { const { data } = await api.get(`/albums/${id}`) return data }, }) const { data: assets, isLoading: assetsLoading } = useQuery({ queryKey: ["album", id, "assets"], queryFn: async () => { if (!album || album.asset_ids.length === 0) return [] const results = await Promise.all( album.asset_ids.map((assetId) => api .get(`/assets/${assetId}`) .then((r) => r.data) .catch(() => null), ), ) return results.filter(Boolean) as AssetResponse[] }, enabled: !!album, }) const groups = useMemo(() => groupByDate(assets ?? []), [assets]) const existingIds = useMemo( () => new Set(album?.asset_ids ?? []), [album], ) const handleRemove = async (assetId: string) => { try { await removeEntry({ albumId: id, assetId }) qc.invalidateQueries({ queryKey: ["album", id] }) toast.success("Removed from album") } catch { toast.error("Failed to remove") } } const handleAddPhotos = async (assetIds: string[]) => { let added = 0 for (const assetId of assetIds) { try { await addEntry({ albumId: id, assetId }) added++ } catch { /* skip duplicates */ } } qc.invalidateQueries({ queryKey: ["album", id] }) toast.success(`Added ${added} photo(s)`) } if (albumLoading) { return (
) } if (!album) { return (
Album not found
) } return (

{album.title}

{album.description && (

{album.description}

)}

{album.asset_count} photos

{}} onRemoveAsset={handleRemove} />
) }