/** * Hook for the initial BanGUI setup flow. * * Exposes the current setup completion status and a submission handler. * Uses the shared setup status hook to deduplicate requests when multiple * consumers mount simultaneously. */ import { useCallback, useState } from "react"; import { ApiError } from "../api/client"; import { submitSetup } from "../api/setup"; import { invalidateSetupStatus, useSharedSetupStatus } from "./useSharedSetupStatus"; import type { SetupRequest, SetupStatusResponse, } from "../types/setup"; export interface UseSetupResult { /** Known setup status, or null while loading. */ status: SetupStatusResponse | null; /** Whether the initial status check is in progress. */ loading: boolean; /** User-facing error message from the last status check. */ error: string | null; /** Refresh the setup status from the backend. */ refresh: () => Promise; /** Whether a submit request is currently in flight. */ submitting: boolean; /** User-facing error message from the last submit attempt. */ submitError: string | null; /** Submit the initial setup payload. */ submit: (payload: SetupRequest) => Promise; } export function useSetup(): UseSetupResult { const { status, loading, error, refresh } = useSharedSetupStatus(); const [submitting, setSubmitting] = useState(false); const [submitError, setSubmitError] = useState(null); const submit = useCallback(async (payload: SetupRequest): Promise => { setSubmitting(true); setSubmitError(null); try { await submitSetup(payload); // Invalidate the cache after successful setup so the next check reflects the new state. invalidateSetupStatus(); } catch (err: unknown) { if (err instanceof ApiError) { setSubmitError(err.message); } else if (err instanceof Error) { setSubmitError(err.message); } else { setSubmitError("An unexpected error occurred."); } throw err; } finally { setSubmitting(false); } }, []); return { status, loading, error, refresh, submitting, submitError, submit, }; }