Initial eth_hedge_sim: P0 market, auth UI, one-click deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-24 16:33:25 +08:00
commit e51f357b48
49 changed files with 4783 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
import type { ReactNode } from "react";
import { NavLink, Navigate, Route, Routes } from "react-router-dom";
import { clearSession, getToken, getUsername } from "./api/client";
import LoginPage from "./pages/Login";
import PlanPage from "./pages/Plan";
import TradesPage from "./pages/Trades";
import StatsPage from "./pages/Stats";
import SettingsPage from "./pages/Settings";
function Shell({ children }: { children: ReactNode }) {
const user = getUsername();
return (
<div className="app-shell">
<nav className="topnav">
<div className="brand">eth_hedge_sim</div>
<NavLink to="/plan" className={({ isActive }) => (isActive ? "active" : "")}>
</NavLink>
<NavLink to="/trades" className={({ isActive }) => (isActive ? "active" : "")}>
</NavLink>
<NavLink to="/stats" className={({ isActive }) => (isActive ? "active" : "")}>
</NavLink>
<NavLink to="/settings" className={({ isActive }) => (isActive ? "active" : "")}>
</NavLink>
<div className="spacer" />
<span className="meta mono">{user}</span>
<button
className="btn ghost"
type="button"
onClick={() => {
clearSession();
window.location.href = "/login";
}}
>
退
</button>
</nav>
<main className="page">{children}</main>
</div>
);
}
function RequireAuth({ children }: { children: ReactNode }) {
if (!getToken()) return <Navigate to="/login" replace />;
return <Shell>{children}</Shell>;
}
export default function App() {
return (
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route
path="/plan"
element={
<RequireAuth>
<PlanPage />
</RequireAuth>
}
/>
<Route
path="/trades"
element={
<RequireAuth>
<TradesPage />
</RequireAuth>
}
/>
<Route
path="/stats"
element={
<RequireAuth>
<StatsPage />
</RequireAuth>
}
/>
<Route
path="/settings"
element={
<RequireAuth>
<SettingsPage />
</RequireAuth>
}
/>
<Route path="/" element={<Navigate to="/plan" replace />} />
<Route path="*" element={<Navigate to="/plan" replace />} />
</Routes>
);
}