Polish semi dual cards: equal height, quote header, holding state.

Right card stacks title then green expiry; left shows 持仓中 after open.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-08 15:11:10 +08:00
parent 626c9c1323
commit 43e2df2b62
2 changed files with 96 additions and 32 deletions
+27 -10
View File
@@ -902,7 +902,13 @@ export default function PlanPage() {
<div className="plan-semi-head"> <div className="plan-semi-head">
<h3 className="plan-panel-title"> · </h3> <h3 className="plan-panel-title"> · </h3>
<span className="mono meta"> <span className="mono meta">
{plan.semi_armed ? "已授权" : "未授权"} {open ? (
<span className="status-running"></span>
) : plan.semi_armed ? (
"已授权"
) : (
"未授权"
)}
{" · "} {" · "}
{semiMny === "itm" ? "实值" : semiMny === "atm" ? "平值" : "虚值"} {semiMny === "itm" ? "实值" : semiMny === "atm" ? "平值" : "虚值"}
{" · "} {" · "}
@@ -1287,10 +1293,14 @@ export default function PlanPage() {
})()} })()}
</div> </div>
<div className="plan-semi-btns"> <div className="plan-semi-btns">
{open ? (
<span className="plan-semi-holding status-running"></span>
) : (
<>
<button <button
className="btn ghost" className="btn ghost"
type="button" type="button"
disabled={open || !!busy || !semiDirty} disabled={!!busy || !semiDirty}
onClick={() => void saveSemiParams()} onClick={() => void saveSemiParams()}
> >
@@ -1298,7 +1308,7 @@ export default function PlanPage() {
<button <button
className="btn" className="btn"
type="button" type="button"
disabled={open || !!busy || !!plan.semi_armed} disabled={!!busy || !!plan.semi_armed}
onClick={() => void armSemi(true)} onClick={() => void armSemi(true)}
> >
@@ -1306,23 +1316,30 @@ export default function PlanPage() {
<button <button
className="btn ghost" className="btn ghost"
type="button" type="button"
disabled={open || !!busy || !plan.semi_armed} disabled={!!busy || !plan.semi_armed}
onClick={() => void armSemi(false)} onClick={() => void armSemi(false)}
> >
</button> </button>
</>
)}
</div> </div>
</section> </section>
<section className="card plan-t-quote" aria-label="期权报价列表"> <section className="card plan-t-quote" aria-label="期权报价列表">
<div className="plan-semi-head"> <div className="plan-t-head-stack">
<h3 className="plan-panel-title"> <h3 className="plan-panel-title plan-t-title-line">
{semiView === "short" ? "Put" : "Call"} · / / {semiView === "short" ? "Put" : "Call"}
{semiMny === "itm"
? "实值"
: semiMny === "atm"
? "平值"
: "虚值"}
</h3> </h3>
<span className="mono meta"> <div className="mono plan-t-expiry-line">
{ladder?.expiry_ymd {ladder?.expiry_ymd
? `到期 ${ladder.expiry_ymd}` ? `到期 ${ladder.expiry_ymd}`
: "—"} : "到期 —"}
{ladder?.hours_left != null {ladder?.hours_left != null
? ` · 剩余≈${fmt(ladder.hours_left, 1)}h` ? ` · 剩余≈${fmt(ladder.hours_left, 1)}h`
: ""} : ""}
@@ -1333,7 +1350,7 @@ export default function PlanPage() {
{ladder?.index_px != null {ladder?.index_px != null
? ` · 指数 ${fmtExPx("index", ladder.index_px)}` ? ` · 指数 ${fmtExPx("index", ladder.index_px)}`
: ""} : ""}
</span> </div>
</div> </div>
{!ladder?.ok ? ( {!ladder?.ok ? (
<p className="meta">{ladder?.detail || "暂无报价链"}</p> <p className="meta">{ladder?.detail || "暂无报价链"}</p>
+48 -1
View File
@@ -478,24 +478,52 @@ input {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 10px; gap: 10px;
margin-bottom: 12px; margin-bottom: 12px;
align-items: start; align-items: stretch;
} }
.plan-semi-tab > .card { .plan-semi-tab > .card {
margin-bottom: 0; margin-bottom: 0;
min-width: 0; min-width: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.plan-semi-tab > .plan-semi-card .plan-semi-btns {
margin-top: auto;
}
.plan-semi-tab > .plan-t-quote .plan-t-wrap {
flex: 1;
min-height: 0;
} }
@media (max-width: 960px) { @media (max-width: 960px) {
.plan-semi-tab { .plan-semi-tab {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.plan-semi-tab > .card {
height: auto;
}
} }
.plan-semi-compact { .plan-semi-compact {
padding: 10px 12px; padding: 10px 12px;
} }
.plan-semi-holding {
display: inline-flex;
align-items: center;
min-height: 34px;
padding: 6px 14px;
font-size: 14px;
font-weight: 700;
border-radius: 6px;
border: 1px solid rgba(14, 203, 129, 0.45);
background: rgba(14, 203, 129, 0.12);
}
.plan-semi-head { .plan-semi-head {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
@@ -572,6 +600,25 @@ input {
padding: 10px 12px; padding: 10px 12px;
} }
.plan-t-head-stack {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 8px;
}
.plan-t-title-line {
margin: 0;
font-size: 14px;
}
.plan-t-expiry-line {
font-size: 12px;
font-weight: 600;
color: #0ecb81;
line-height: 1.4;
}
.plan-t-wrap { .plan-t-wrap {
overflow-x: auto; overflow-x: auto;
margin-top: 4px; margin-top: 4px;