/* global React, ReactDOM */
const { useState, useEffect, useMemo } = React;
const TWEAK_DEFAULTS = { accent: "#00e0ff", density: "balanced", showTape: true, monoEverything: false };
function AuthShell() {
const [authPage, setAuthPage] = useState("login");
window._setAuthPage = setAuthPage;
const onLogin = () => window.location.reload();
if (authPage === "register") return ;
return ;
}
function App() {
const [user, setUser] = useState(window.Auth.getUser());
const [route, setRoute] = useState("dashboard");
const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
const [theme, setTheme] = useState(() => {
const saved = localStorage.getItem("aura-theme");
return saved === "light" ? "light" : "dark";
});
// Shared state — fetched from API
const [accounts, setAccounts] = useState([]);
const [activeAccount, setActiveAccount] = useState(null);
const [openTrades, setOpenTrades] = useState([]);
const [botStatus, setBotStatus] = useState(null);
useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
try { localStorage.setItem("aura-theme", theme); } catch (e) {}
}, [theme]);
useEffect(() => {
document.documentElement.style.setProperty("--accent", tweaks.accent);
}, [tweaks.accent]);
useEffect(() => {
document.body.style.fontFamily = tweaks.monoEverything ? "var(--font-mono)" : "var(--font-sans)";
}, [tweaks.monoEverything]);
useEffect(() => {
if (!user) {
window.api.me().then((u) => { if (u) { setUser(u); window.Auth.setUser(u); } }).catch(() => {});
}
}, []);
useEffect(() => {
window.api.listAccounts().then((accts) => {
if (accts && accts.length > 0) {
setAccounts(accts);
const def = accts.find((a) => a.is_default) || accts[0];
setActiveAccount(def);
}
}).catch(() => {});
}, []);
useEffect(() => {
if (!activeAccount) return;
const refresh = () => {
window.api.openTrades(activeAccount.id).then(setOpenTrades).catch(() => {});
window.api.botStatus(activeAccount.id).then(setBotStatus).catch(() => {});
};
refresh();
const id = setInterval(refresh, 15000);
return () => clearInterval(id);
}, [activeAccount]);
const marketOpen = useMemo(() => {
const d = new Date();
const day = d.getUTCDay();
return day >= 1 && day <= 5;
}, []);
const dayPnL = useMemo(() => {
return openTrades.reduce((sum, t) => sum + (t.pnl || 0), 0);
}, [openTrades]);
const sharedState = {
user, accounts, activeAccount, setActiveAccount,
openTrades, setOpenTrades, botStatus, setBotStatus,
accounts, setAccounts,
balance: activeAccount ? activeAccount.balance : null,
equity: activeAccount ? activeAccount.equity : null,
dayPnL,
};
const toggleTheme = () => setTheme((t) => t === "dark" ? "light" : "dark");
let page;
switch (route) {
case "dashboard": page = ; break;
case "active": page = ; break;
case "history": page = ; break;
case "signals": page = ; break;
case "performance":
case "analytics": page = ; break;
case "bot":
case "risk": page = ; break;
case "accounts": page = ; break;
case "profile": page = ; break;
case "help": page = ; break;
default: page = ;
}
return (
<>
{tweaks.showTape && }
{page}
>
);
}
function PlaceholderPage({ title }) {
return (
<>
{title}
>
);
}
function Tweaks({ tweaks, setTweak, theme, setTheme }) {
const { TweaksPanel, TweakSection, TweakRadio, TweakToggle, TweakColor } = window;
return (
setTheme(v)} />
setTweak("accent", v)} />
setTweak("monoEverything", v)} />
setTweak("density", v)} />
setTweak("showTape", v)} />
window.Auth.logout()} />
);
}
function Root() {
if (!window.Auth.isLoggedIn()) return ;
return ;
}
ReactDOM.createRoot(document.getElementById("root")).render();