import { useState } from "react"; import { BrainCircuit, FileSearch, Gauge, Github, Sparkles, Wrench } from "lucide-react"; import { api, setTokens } from "../lib/api.js"; export default function AuthPage({ onAuthed, appInfo }) { const [mode, setMode] = useState("login"); const [email, setEmail] = useState(""); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); const [busy, setBusy] = useState(false); const [demoBusy, setDemoBusy] = useState(false); const isDemo = Boolean(appInfo?.demo_mode); async function startDemo() { setError(""); setDemoBusy(true); try { const response = await fetch("/api/auth/demo", { method: "POST" }); const data = await response.json(); if (!response.ok) { throw new Error( typeof data.detail === "string" ? data.detail : "Could not start the demo. Please try again." ); } setTokens(data); onAuthed(await api("/api/auth/me")); } catch (err) { setError(err.message); } finally { setDemoBusy(false); } } async function submit(event) { event.preventDefault(); setError(""); setBusy(true); try { const path = mode === "login" ? "/api/auth/login" : "/api/auth/register"; const body = mode === "login" ? { email, password } : { email, username, password }; const response = await fetch(path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const data = await response.json(); if (!response.ok) { throw new Error( typeof data.detail === "string" ? data.detail : "Please check your details and try again." ); } setTokens(data); onAuthed(await api("/api/auth/me")); } catch (err) { setError(err.message); } finally { setBusy(false); } } return (
Streaming chat backed by an autonomous tool-calling agent, hybrid retrieval over your documents, and full cost observability.