diff options
Diffstat (limited to 'makima/frontend/src/hooks')
| -rw-r--r-- | makima/frontend/src/hooks/useChains.ts | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/makima/frontend/src/hooks/useChains.ts b/makima/frontend/src/hooks/useChains.ts new file mode 100644 index 0000000..272847a --- /dev/null +++ b/makima/frontend/src/hooks/useChains.ts @@ -0,0 +1,145 @@ +import { useState, useCallback, useEffect } from "react"; +import { + listChains, + getChain, + createChain, + updateChain, + archiveChain, + getChainGraph, + type ChainSummary, + type ChainWithContracts, + type ChainGraphResponse, + type ChainStatus, + type CreateChainRequest, + type UpdateChainRequest, +} from "../lib/api"; + +interface UseChainsResult { + chains: ChainSummary[]; + loading: boolean; + error: string | null; + refresh: () => Promise<void>; + createNewChain: (req: CreateChainRequest) => Promise<ChainWithContracts | null>; + updateExistingChain: ( + chainId: string, + req: UpdateChainRequest + ) => Promise<ChainWithContracts | null>; + archiveExistingChain: (chainId: string) => Promise<boolean>; + getChainById: (chainId: string) => Promise<ChainWithContracts | null>; + getGraph: (chainId: string) => Promise<ChainGraphResponse | null>; +} + +export function useChains(statusFilter?: ChainStatus): UseChainsResult { + const [chains, setChains] = useState<ChainSummary[]>([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState<string | null>(null); + + const fetchChains = useCallback(async () => { + setLoading(true); + setError(null); + try { + const response = await listChains(statusFilter); + setChains(response.chains); + } catch (err) { + console.error("Failed to fetch chains:", err); + setError(err instanceof Error ? err.message : "Failed to fetch chains"); + } finally { + setLoading(false); + } + }, [statusFilter]); + + useEffect(() => { + fetchChains(); + }, [fetchChains]); + + const createNewChain = useCallback( + async (req: CreateChainRequest): Promise<ChainWithContracts | null> => { + try { + const chain = await createChain(req); + // Refresh the list + await fetchChains(); + // Return the full chain with contracts + return await getChain(chain.id); + } catch (err) { + console.error("Failed to create chain:", err); + setError(err instanceof Error ? err.message : "Failed to create chain"); + return null; + } + }, + [fetchChains] + ); + + const updateExistingChain = useCallback( + async ( + chainId: string, + req: UpdateChainRequest + ): Promise<ChainWithContracts | null> => { + try { + await updateChain(chainId, req); + // Refresh the list + await fetchChains(); + // Return the updated chain + return await getChain(chainId); + } catch (err) { + console.error("Failed to update chain:", err); + setError(err instanceof Error ? err.message : "Failed to update chain"); + return null; + } + }, + [fetchChains] + ); + + const archiveExistingChain = useCallback( + async (chainId: string): Promise<boolean> => { + try { + await archiveChain(chainId); + // Refresh the list + await fetchChains(); + return true; + } catch (err) { + console.error("Failed to archive chain:", err); + setError(err instanceof Error ? err.message : "Failed to archive chain"); + return false; + } + }, + [fetchChains] + ); + + const getChainById = useCallback( + async (chainId: string): Promise<ChainWithContracts | null> => { + try { + return await getChain(chainId); + } catch (err) { + console.error("Failed to get chain:", err); + setError(err instanceof Error ? err.message : "Failed to get chain"); + return null; + } + }, + [] + ); + + const getGraph = useCallback( + async (chainId: string): Promise<ChainGraphResponse | null> => { + try { + return await getChainGraph(chainId); + } catch (err) { + console.error("Failed to get chain graph:", err); + setError(err instanceof Error ? err.message : "Failed to get chain graph"); + return null; + } + }, + [] + ); + + return { + chains, + loading, + error, + refresh: fetchChains, + createNewChain, + updateExistingChain, + archiveExistingChain, + getChainById, + getGraph, + }; +} |
