import { useCallback, useEffect, useState } from 'react'; import { useAtelierRefresh } from 'officerdev'; import { useAtelierClient } from '../lib/api'; import type { CollectionDetail, GenerationRow } from '../lib/api'; /** * What the main panel is showing: everything, or one collection. * * One hook for both, because the panel below it is the same grid either way and the only difference is * where the rows came from. The collection case used to live in the Collections panel, which meant two * panels each holding their own copy of a collection's images and disagreeing after any edit. */ export const useGalleryManager = (collectionId?: string) => { const client = useAtelierClient(); const [rows, setRows] = useState([]); const [collection, setCollection] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [refreshSignal] = useAtelierRefresh(); const refresh = useCallback(async () => { try { if (collectionId) { const detail = await client.getCollection(collectionId); setCollection(detail); setRows(detail.images); } else { setCollection(null); setRows(await client.listGenerations()); } setError(null); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setLoading(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [collectionId]); useEffect(() => { setLoading(true); void refresh(); }, [refresh]); // A finished generation elsewhere on the dashboard (the Generate panel) bumps this — re-read. useEffect(() => { if (refreshSignal > 0) void refresh(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [refreshSignal]); /** Only meaningful in collection mode: takes the image out of this collection, not out of Atelier. */ const removeFromCollection = async (generationId: string) => { if (!collectionId) return; const { images } = await client.removeFromCollection(collectionId, generationId); setRows(images); setCollection((current) => (current ? { ...current, images } : current)); }; const succeeded = rows.filter((row) => row.status === 'succeeded' && row.image_path); const totalCost = rows.reduce((sum, row) => sum + Number(row.cost_usd ?? 0), 0); return { rows, succeeded, totalCost, collection, loading, error, refresh, removeFromCollection }; };