feat(hub): mobile AI tabs and dashboard position lines

Mobile AI coach uses four top tabs (trading, general, history, new) with single-panel view and wider desktop history. Dashboard account cards show key levels and positions one per line with colored float PnL.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-11 11:16:28 +08:00
parent c59a17f9ac
commit 1042fdeef3
7 changed files with 185 additions and 39 deletions
+30 -1
View File
@@ -90,6 +90,35 @@
</div>`;
}
function renderRemarkLines(ac) {
const lines = Array.isArray(ac && ac.remark_lines) ? ac.remark_lines : [];
if (!lines.length) {
const fallback = esc((ac && ac.remark) || "—");
return `<div class="dash-ac-remark"><div class="dash-ac-remark-line">${fallback}</div></div>`;
}
return `<div class="dash-ac-remark">${lines
.map((ln) => {
const kind = ln && ln.kind;
const text = esc((ln && ln.text) || "");
if (kind === "position" && ln.pnl != null && Number.isFinite(Number(ln.pnl))) {
const pnl = Number(ln.pnl);
return (
`<div class="dash-ac-remark-line dash-ac-remark-pos">` +
`${text} 浮<span class="${pnlClass(pnl)}">${pnlSigned(pnl, 2)}</span>` +
`</div>`
);
}
const cls =
kind === "monitor"
? "dash-ac-remark-line dash-ac-remark-mon"
: kind === "issue"
? "dash-ac-remark-line dash-ac-remark-issue"
: "dash-ac-remark-line";
return `<div class="${cls}">${text}</div>`;
})
.join("")}</div>`;
}
function renderAccounts(accounts, threshold) {
if (!elAccounts) return;
const rows = Array.isArray(accounts) ? accounts : [];
@@ -129,7 +158,7 @@
<div class="dash-ac-metric"><span>浮盈亏</span><strong class="${pnlClass(floatPnl)}">${pnlSigned(floatPnl, 2)}</strong></div>
</div>
${lossBar}
<div class="dash-ac-remark">${esc(ac.remark || "—")}</div>
${renderRemarkLines(ac)}
</article>`;
})
.join("");