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 ; case "signup": return ; case "api-setup": return ; case "ext-install": return ; case "subscription": return ; case "dashboard": return ; default: return ; } })(); return (
{/* Background: body::before (steak tile), body::after (vignette), and the route-specific .landing-bg layer carry the full look. The old .bg-stage / .bg-noise overlays were duplicating that work and the brutalist theme's .bg-noise had a typo making vertical lines way too dark — visible stripes over everything. Removed. */}
SS Stake Sauce
{!isApp ? ( ) : ( )}
{isApp ? ( <> live {(user?.username || "U").slice(0,1).toUpperCase()} {user?.username || "—"} { localStorage.removeItem("cc_token"); setUser(null); setPlan(null); goto("landing"); }}> Sign out ) : ( <> {screen !== "signup" && screen !== "landing" && ( goto("landing")}>Exit )} {screen === "landing" && ( <> goto("signup")}>Sign in goto("signup")}>Get started )} )}
{screenEl}
{toasts.map(tt => ( {tt.msg} ))}
); } ReactDOM.createRoot(document.getElementById("root")).render();