demo / frontend /src /hooks /useStartDemo.ts
Pierre Andrews
Initial commit
f52d137
import { useCallback, useState } from "react";
import { FormData } from "../types";
import {
createStartDemoPayload,
readFileAsText,
startDemo,
} from "../utils/api";
import { useHealthCheck } from "./useHealthCheck";
interface HealthCheckProgress {
attempt: number;
maxAttempts: number;
}
interface UseStartDemoOptions {
onSuccess?: () => void;
onError?: (error: Error) => void;
}
interface UseStartDemoReturn {
// States
isStarting: boolean;
iframeUrl: string;
iframeLoading: boolean;
healthCheckProgress: HealthCheckProgress | null;
// Actions
startDemoSession: (
formData: FormData,
loginLabel: string,
accessToken: string | null,
options?: UseStartDemoOptions & { logPrefix?: string }
) => Promise<void>;
resetDemo: () => void;
setIframeLoaded: () => void;
}
export const useStartDemo = (): UseStartDemoReturn => {
const [isStarting, setIsStarting] = useState<boolean>(false);
const [iframeUrl, setIframeUrl] = useState<string>("");
const [iframeLoading, setIframeLoading] = useState<boolean>(false);
const { healthCheckProgress, startHealthCheck } = useHealthCheck();
const startDemoSession = useCallback(async (
formData: FormData,
loginLabel: string,
accessToken: string | null,
options: UseStartDemoOptions & { logPrefix?: string } = {}
) => {
const {
onSuccess,
onError,
logPrefix = "Demo startup"
} = options;
setIsStarting(true);
setIframeLoading(true);
try {
// Read MCP file if present
const mcpText = formData.mcpFile
? await readFileAsText(formData.mcpFile)
: null;
// Create and send payload
const payload = createStartDemoPayload(
formData.model,
formData.provider,
loginLabel,
mcpText,
);
const result = await startDemo(payload, accessToken);
setIframeUrl(result.iframe_url);
// Start health checking in the background
await startHealthCheck(result.health_url, {
logPrefix: `${logPrefix} health check`,
onSuccess: () => {
setIframeLoading(false);
if (onSuccess) {
onSuccess();
}
},
onError: (healthCheckError) => {
setIframeLoading(false);
if (onError) {
onError(new Error("Server startup timed out. The application may still be loading in the background."));
}
},
});
} catch (error) {
console.error(`${logPrefix} failed:`, error);
setIsStarting(false);
setIframeLoading(false);
if (onError) {
onError(error as Error);
}
} finally {
setIsStarting(false);
}
}, [startHealthCheck]);
const resetDemo = useCallback(() => {
setIframeUrl("");
setIframeLoading(false);
setIsStarting(false);
}, []);
const setIframeLoaded = useCallback(() => {
setIframeLoading(false);
}, []);
return {
// States
isStarting,
iframeUrl,
iframeLoading,
healthCheckProgress,
// Actions
startDemoSession,
resetDemo,
setIframeLoaded,
};
};