import { useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; import { type Provider, OnboardingStep } from "./types"; import { ProviderSelectionStep } from "./provider-selection-step"; import { IngestionStep } from "./ingestion-step"; import { VerificationStep } from "./verification-step"; import { PROVIDER_CONFIGS } from "./provider-config"; import { Progress } from "../ui/progress"; interface OnboardingModalProps { isOpen: boolean; onClose: () => void; onComplete: () => void; } export function OnboardingModal({ isOpen, onClose, onComplete, }: OnboardingModalProps) { const [currentStep, setCurrentStep] = useState( OnboardingStep.PROVIDER_SELECTION, ); const [selectedProvider, setSelectedProvider] = useState(); const [ingestionStatus, setIngestionStatus] = useState< "idle" | "waiting" | "processing" | "complete" | "error" >("idle"); const [verificationResult, setVerificationResult] = useState(); const [isCheckingRecall, setIsCheckingRecall] = useState(false); const [error, setError] = useState(); // Calculate progress const getProgress = () => { switch (currentStep) { case OnboardingStep.PROVIDER_SELECTION: return 33; case OnboardingStep.FIRST_INGESTION: return 66; case OnboardingStep.VERIFICATION: return 100; default: return 0; } }; // Poll for ingestion status const pollIngestion = async () => { setIngestionStatus("waiting"); try { const maxAttempts = 30; // 60 seconds (30 * 2s) let attempts = 0; // Store the timestamp when polling starts const startTime = Date.now(); const poll = async (): Promise => { if (attempts >= maxAttempts) { throw new Error("Ingestion timeout - please try again"); } // Check for new ingestion logs from the last 5 minutes const response = await fetch("/api/v1/logs?limit=1"); const data = await response.json(); // Check if there's a recent ingestion (created after we started polling) if (data.logs && data.logs.length > 0) { const latestLog = data.logs[0]; const logTime = new Date(latestLog.time).getTime(); // If the log was created after we started polling, we found a new ingestion if (logTime >= startTime) { return true; } } await new Promise((resolve) => setTimeout(resolve, 2000)); attempts++; return poll(); }; const success = await poll(); if (success) { setIngestionStatus("complete"); // Auto-advance to verification step after 2 seconds setTimeout(() => { setCurrentStep(OnboardingStep.VERIFICATION); }, 2000); } } catch (err) { setError(err instanceof Error ? err.message : "Unknown error occurred"); setIngestionStatus("error"); } }; const handleProviderSelect = (provider: Provider) => { setSelectedProvider(provider); }; const handleContinueFromProvider = () => { setCurrentStep(OnboardingStep.FIRST_INGESTION); }; const handleStartWaiting = () => { pollIngestion(); }; const handleComplete = () => { setCurrentStep(OnboardingStep.COMPLETE); onComplete(); onClose(); }; // Poll for recall logs to detect verification const pollRecallLogs = async () => { setIsCheckingRecall(true); try { const maxAttempts = 30; // 60 seconds let attempts = 0; const startTime = Date.now(); const poll = async (): Promise => { if (attempts >= maxAttempts) { throw new Error("Verification timeout - please try again"); } // Check for new recall logs const response = await fetch("/api/v1/recall-logs?limit=1"); const data = await response.json(); // Check if there's a recent recall (created after we started polling) if (data.recallLogs && data.recallLogs.length > 0) { const latestRecall = data.recallLogs[0]; const recallTime = new Date(latestRecall.createdAt).getTime(); // If the recall was created after we started polling if (recallTime >= startTime) { // Return the query as verification result return latestRecall.query || "Recall detected successfully"; } } await new Promise((resolve) => setTimeout(resolve, 2000)); attempts++; return poll(); }; const result = await poll(); if (result) { setVerificationResult(result); setIsCheckingRecall(false); } } catch (err) { setError(err instanceof Error ? err.message : "Unknown error occurred"); setIsCheckingRecall(false); } }; const getStepTitle = () => { switch (currentStep) { case OnboardingStep.PROVIDER_SELECTION: return "Step 1 of 3"; case OnboardingStep.FIRST_INGESTION: return "Step 2 of 3"; case OnboardingStep.VERIFICATION: return "Step 3 of 3"; default: return ""; } }; return (
Welcome to Core

{getStepTitle()}

{currentStep === OnboardingStep.PROVIDER_SELECTION && ( )} {currentStep === OnboardingStep.FIRST_INGESTION && selectedProvider && ( )} {currentStep === OnboardingStep.VERIFICATION && selectedProvider && ( )}
); }