import { useState, useCallback } from "react"; /** * Hook for handling mutations (create, update, delete operations). * Manages loading state and error handling for async mutations. * * @param mutationFn - Function that performs the mutation and returns a Promise * @param options - Configuration options * @returns Object containing mutate function, loading state, and error */ export function useMutation( mutationFn: (args: TArgs) => Promise, options: { /** Callback called on successful mutation */ onSuccess?: (data: TResponse) => void; /** Callback called on mutation error */ onError?: (err: unknown) => void; } = {} ): { mutate: (args: TArgs) => Promise; isLoading: boolean; error: string | null; } { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const mutate = useCallback( async (args: TArgs): Promise => { setIsLoading(true); setError(null); try { const result = await mutationFn(args); if (options.onSuccess) { options.onSuccess(result); } return result; } catch (err) { const errorMessage = err instanceof Error ? err.message : "Operation failed"; setError(errorMessage); if (options.onError) { options.onError(err); } else { console.error("Mutation failed:", err); } throw err; } finally { setIsLoading(false); } }, [mutationFn, options] ); return { mutate, isLoading, error, }; }