UI: centered nav title, settings tabs, running status, manual buttons.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-24 17:17:44 +08:00
parent 8ea05e7064
commit b6d9877538
7 changed files with 236 additions and 145 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ export default function LoginPage() {
return (
<div className="login-wrap">
<form className="login-box" onSubmit={onSubmit}>
<h1>eth_hedge_sim</h1>
<h1>OKX </h1>
<p></p>
{err ? <div className="err">{err}</div> : null}
<div className="field">
+8 -4
View File
@@ -90,7 +90,7 @@ export default function PlanPage() {
disabled={!!busy}
onClick={() => act("/api/sim/open-group", "open")}
>
</button>
<button
className="btn ghost"
@@ -98,7 +98,7 @@ export default function PlanPage() {
disabled={!!busy}
onClick={() => act("/api/sim/close-group", "close")}
>
</button>
<button
className="btn ghost"
@@ -115,8 +115,12 @@ export default function PlanPage() {
<div className="kv">
<span></span>
<span className="mono">
{plan?.running ? "运行中" : "已停"} · {plan?.phase || "—"} · {" "}
{plan?.rounds_done ?? 0}/{plan?.max_rounds ?? 3}
{plan?.running ? (
<span className="status-running"></span>
) : (
<span className="status-stopped"></span>
)}{" "}
· {plan?.phase || "—"} · {plan?.rounds_done ?? 0}/{plan?.max_rounds ?? 3}
</span>
</div>
<div className="kv">
+128 -105
View File
@@ -7,7 +7,11 @@ import {
StrategySettings,
} from "../api/client";
type Tab = "strategy" | "account";
export default function SettingsPage() {
const [tab, setTab] = useState<Tab>("strategy");
const [newUsername, setNewUsername] = useState(getUsername() || "admin");
const [currentPassword, setCurrentPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
@@ -85,113 +89,132 @@ export default function SettingsPage() {
}
return (
<div style={{ display: "grid", gap: 16, maxWidth: 560 }}>
<div className="card">
<h2 style={{ marginTop: 0 }}></h2>
<p style={{ color: "var(--muted)" }}>
N =1×
</p>
{stratOk ? <div style={{ color: "var(--up)", marginBottom: 12 }}>{stratOk}</div> : null}
<form onSubmit={onSaveStrategy}>
<div className="field">
<label htmlFor="exit">EXIT_MOVE_POINTS</label>
<input
id="exit"
className="mono"
type="number"
step="1"
value={exitPts}
onChange={(e) => setExitPts(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="rest">REST_SECONDS</label>
<input
id="rest"
className="mono"
type="number"
step="1"
value={rest}
onChange={(e) => setRest(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="rounds">MAX_ROUNDS</label>
<input
id="rounds"
className="mono"
type="number"
step="1"
value={maxRounds}
onChange={(e) => setMaxRounds(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="fee">FEE_RATE</label>
<input
id="fee"
className="mono"
type="number"
step="0.0001"
value={fee}
onChange={(e) => setFee(Number(e.target.value))}
/>
</div>
<button className="btn" type="submit">
</button>
</form>
<div style={{ maxWidth: 560 }}>
<h2 style={{ marginTop: 0 }}></h2>
<div className="tabs">
<button
type="button"
className={tab === "strategy" ? "tab active" : "tab"}
onClick={() => setTab("strategy")}
>
</button>
<button
type="button"
className={tab === "account" ? "tab active" : "tab"}
onClick={() => setTab("account")}
>
</button>
</div>
<div className="card">
<h2 style={{ marginTop: 0 }}></h2>
{err ? <div className="err">{err}</div> : null}
{ok ? <div style={{ color: "var(--up)", marginBottom: 12 }}>{ok}</div> : null}
<form onSubmit={onSaveCreds}>
<div className="field">
<label htmlFor="user"></label>
<input
id="user"
value={newUsername}
onChange={(e) => setNewUsername(e.target.value)}
required
/>
</div>
<div className="field">
<label htmlFor="cur"></label>
<input
id="cur"
type="password"
value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)}
required
/>
</div>
<div className="field">
<label htmlFor="np"></label>
<input
id="np"
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
required
/>
</div>
<div className="field">
<label htmlFor="cp"></label>
<input
id="cp"
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
/>
</div>
<button className="btn" type="submit" disabled={loading}>
{loading ? "保存中…" : "保存账号"}
</button>
</form>
</div>
{tab === "strategy" ? (
<div className="card">
<p style={{ color: "var(--muted)", marginTop: 0 }}>
N =1×
</p>
{stratOk ? <div style={{ color: "var(--up)", marginBottom: 12 }}>{stratOk}</div> : null}
{err && tab === "strategy" ? <div className="err">{err}</div> : null}
<form onSubmit={onSaveStrategy}>
<div className="field">
<label htmlFor="exit">EXIT_MOVE_POINTS</label>
<input
id="exit"
className="mono"
type="number"
step="1"
value={exitPts}
onChange={(e) => setExitPts(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="rest">REST_SECONDS</label>
<input
id="rest"
className="mono"
type="number"
step="1"
value={rest}
onChange={(e) => setRest(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="rounds">MAX_ROUNDS</label>
<input
id="rounds"
className="mono"
type="number"
step="1"
value={maxRounds}
onChange={(e) => setMaxRounds(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="fee">FEE_RATE</label>
<input
id="fee"
className="mono"
type="number"
step="0.0001"
value={fee}
onChange={(e) => setFee(Number(e.target.value))}
/>
</div>
<button className="btn" type="submit">
</button>
</form>
</div>
) : (
<div className="card">
{err ? <div className="err">{err}</div> : null}
{ok ? <div style={{ color: "var(--up)", marginBottom: 12 }}>{ok}</div> : null}
<form onSubmit={onSaveCreds}>
<div className="field">
<label htmlFor="user"></label>
<input
id="user"
value={newUsername}
onChange={(e) => setNewUsername(e.target.value)}
required
/>
</div>
<div className="field">
<label htmlFor="cur"></label>
<input
id="cur"
type="password"
value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)}
required
/>
</div>
<div className="field">
<label htmlFor="np"></label>
<input
id="np"
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
required
/>
</div>
<div className="field">
<label htmlFor="cp"></label>
<input
id="cp"
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
/>
</div>
<button className="btn" type="submit" disabled={loading}>
{loading ? "保存中…" : "保存账号"}
</button>
</form>
</div>
)}
</div>
);
}