jarvis-assist/web/src/App.tsx

64 lines
2.3 KiB
TypeScript

import { useState, useEffect } from "react";
import { apiFetch, getStoredKey, onUnauthorized, logout } from "./api";
import { getSpeechMuted, setSpeechMuted } from "./speech";
import Login from "./components/Login";
import Chat from "./components/Chat";
import Dashboard from "./components/Dashboard";
import Settings from "./components/Settings";
import WeatherWidget from "./components/WeatherWidget";
type View = "chat" | "dashboard" | "settings";
export default function App() {
const [authenticated, setAuthenticated] = useState<boolean>(() => getStoredKey() !== null);
const [view, setView] = useState<View>("chat");
const [muted, setMuted] = useState<boolean>(() => getSpeechMuted());
const [assistantName, setAssistantName] = useState<string>("JARVIS");
useEffect(() => onUnauthorized(() => setAuthenticated(false)), []);
useEffect(() => {
if (!authenticated) return;
async function loadAssistantName() {
try {
const response = await apiFetch("/api/v1/settings");
if (!response.ok) return;
const data = await response.json();
setAssistantName(data.assistant_name);
document.title = data.assistant_name;
} catch {
// Default "JARVIS" bleibt bei Fehlern erhalten.
}
}
loadAssistantName();
}, [authenticated]);
function toggleMuted() {
const next = !muted;
setSpeechMuted(next);
setMuted(next);
}
if (!authenticated) {
return <Login onSuccess={() => setAuthenticated(true)} />;
}
return (
<div className="app">
<nav className="nav">
<button onClick={() => setView("chat")} disabled={view === "chat"}>Chat</button>
<button onClick={() => setView("dashboard")} disabled={view === "dashboard"}>Dashboard</button>
<button onClick={() => setView("settings")} disabled={view === "settings"}>Einstellungen</button>
<button onClick={toggleMuted} title={muted ? "Sprachausgabe einschalten" : "Sprachausgabe stummschalten"}>
{muted ? "🔇" : "🔊"}
</button>
<button onClick={() => logout()}>Logout</button>
<WeatherWidget />
</nav>
{view === "chat" && <Chat assistantName={assistantName} />}
{view === "dashboard" && <Dashboard />}
{view === "settings" && <Settings />}
</div>
);
}