import React, { useEffect, useState } from "react";
import Landing from "./pages/Landing";
import Dashboard from "./pages/Dashboard";
import Setup from "./pages/Setup";
import PreInterview from "./pages/PreInterview";
import Interview from "./pages/Interview";
import Processing from "./pages/Processing";
import Results from "./pages/Results";
import { useInterview } from "./contexts/InterviewContext";
import { useAuth } from "./contexts/AuthContext";
import { api } from "./api/client";
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
console.error("App Error Boundary caught:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
Something went wrong
The application encountered an unexpected error. Please return to the landing page and try again.
{this.state.error?.message || "Unknown error"}
);
}
return this.props.children;
}
}
function App() {
const iv = useInterview();
const { currentUser, isGuest, loading: authLoading, loginWithGoogle } = useAuth();
const [caps, setCaps] = useState({ mode: "CPU", llmMode: "api", audioEnabled: true });
// 1. Route Guard: Auto-transition to dashboard if user is known
useEffect(() => {
if (!authLoading && currentUser && iv.step === "landing") {
iv.setStep("dashboard");
}
}, [currentUser, authLoading, iv.step]);
// 2. Fetch server capabilities once
useEffect(() => {
api.getHealth().then(res => {
setCaps({
mode: res.mode || "CPU",
llmMode: res.llm_mode || "api",
audioEnabled: res.asr_available === true
});
}).catch(() => {});
}, []);
if (authLoading) {
return (
);
}
// FLOW: Landing
if (iv.step === "landing") {
return (
{
const res = await loginWithGoogle();
if (res) iv.setStep("dashboard");
}}
onGuestLogin={() => iv.setStep("dashboard")}
/>
);
}
// FLOW: Dashboard
if (iv.step === "dashboard") {
// Allow guests (isGuest=true) even if currentUser temporarily null during async restore
if (!currentUser && !isGuest) {
iv.setStep("landing");
return null;
}
return (
iv.setStep("setup")}
onViewResults={async (sid) => {
try {
const reportData = await api.getReport(sid);
iv.setReport(reportData);
iv.setStep("results");
} catch (e) {
alert("Could not load report details.");
}
}}
/>
);
}
// FLOW: Setup
if (iv.step === "setup") {
return (
{
iv.setReport(null);
iv.saveSetup(data);
iv.setStep("pre-interview");
}}
onBack={() => iv.setStep("dashboard")}
/>
);
}
// FLOW: Pre-Interview (Equipment Check & Question Gen)
if (iv.step === "pre-interview") {
return (
iv.startInterview()}
/>
);
}
// FLOW: Active Interview
if (iv.step === "interview") {
return (
iv.skipQuestion && iv.skipQuestion()}
onExit={() => iv.restart()}
error={iv.error}
/>
);
}
// FLOW: Final Evaluation Processing
if (iv.step === "processing") {
return (
{
iv.setReport(report);
iv.setStep("results");
}}
/>
);
}
// FLOW: Results & Feedback
if (iv.step === "results") {
return (
iv.restart()}
/>
);
}
return (
Unknown Application State
Current Step: {iv.step}
);
}
export default function AppWithBoundary() {
return (
);
}