const ROUTES = ["landing","signup","subscription","api-setup","ext-install","dashboard"];
const ROUTE_LABELS = {
"landing": "Home",
"signup": "Sign up",
"subscription": "Choose plan",
"api-setup": "API setup",
"ext-install": "Extension",
"dashboard": "Dashboard",
};
function App() {
const [screen, setScreen] = React.useState(() => {
const h = location.hash.replace("#", "");
return ROUTES.includes(h) ? h : "landing";
});
const [user, setUser] = React.useState(null);
const [path, setPath] = React.useState(null);
const [apiState, setApiState] = React.useState(null);
const [extState, setExtState] = React.useState(null);
const [plan, setPlan] = React.useState(null);
const [toasts, setToasts] = React.useState([]);
// Restore session from stored JWT
React.useEffect(() => {
const token = localStorage.getItem("cc_token");
if (!token) return;
fetch("/api/me", { headers: { Authorization: `Bearer ${token}` } })
.then(r => r.ok ? r.json() : null)
.then(d => {
if (d?.id) {
setUser(d);
setPlan(d.plan !== "free" ? d.plan : null);
const cur = location.hash.replace("#", "");
if (!cur || cur === "landing" || cur === "signup") setScreen("dashboard");
}
})
.catch(() => {});
}, []);
// hash + title sync
React.useEffect(() => {
location.hash = screen;
document.title = `Stake Sauce · ${ROUTE_LABELS[screen] || screen}`;
}, [screen]);
const goto = (s) => setScreen(s);
const addToast = (msg, kind = "ok") => {
const id = Date.now() + Math.random();
setToasts(prev => [...prev, { id, msg, kind }]);
setTimeout(() => setToasts(prev => prev.filter(x => x.id !== id)), 3500);
};
const isApp = screen === "dashboard";
const screenEl = (() => {
switch (screen) {
case "landing": return