Logs a warning when the initial setup status request fails, allowing operators to diagnose issues during the setup phase. The form remains visible while the error is logged for debugging purposes.
89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
/**
|
|
* Hook for the initial BanGUI setup flow.
|
|
*
|
|
* Exposes the current setup completion status and a submission handler.
|
|
*/
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { ApiError } from "../api/client";
|
|
import { getSetupStatus, submitSetup } from "../api/setup";
|
|
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<void>;
|
|
/** 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<void>;
|
|
}
|
|
|
|
export function useSetup(): UseSetupResult {
|
|
const [status, setStatus] = useState<SetupStatusResponse | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [submitting, setSubmitting] = useState(false);
|
|
const [submitError, setSubmitError] = useState<string | null>(null);
|
|
|
|
const refresh = useCallback(async (): Promise<void> => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const resp = await getSetupStatus();
|
|
setStatus(resp);
|
|
} catch (err: unknown) {
|
|
const errorMessage = err instanceof Error ? err.message : "Failed to fetch setup status";
|
|
console.warn("Setup status check failed:", errorMessage);
|
|
setError(errorMessage);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
void refresh();
|
|
}, [refresh]);
|
|
|
|
const submit = useCallback(async (payload: SetupRequest): Promise<void> => {
|
|
setSubmitting(true);
|
|
setSubmitError(null);
|
|
|
|
try {
|
|
await submitSetup(payload);
|
|
} 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,
|
|
};
|
|
}
|