From 79010a5dae426216bfa4ae1d94d4b6ffeee9cca5 Mon Sep 17 00:00:00 2001 From: Dennis Thiessen Date: Fri, 10 Jul 2026 18:47:40 +0200 Subject: [PATCH] Overview: restore wide focus card and half-width positions The focus|radar 3/5-2/5 pairing made the top-pick card cramped and the full-width positions panel stretched its trade charts. Back to the layout that worked: focus card full width, account ribbons, then positions | radar side by side, performance chart at the bottom. Kept from the rework: radar rows still swap the focus card - and now reliably, because the ticker symbol inside a row is no longer a navigation link (clicking anywhere in the row, symbol included, selects it; the ticker page is reachable via the focus card's Ticker details button). Below-gate inspection, badges, and the reset link unchanged. Co-Authored-By: Claude Fable 5 --- frontend/src/pages/DashboardPage.tsx | 106 +++++++++++++-------------- 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index ed26e63..5a6a89a 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -96,13 +96,7 @@ function RadarSetupRow({ setup, rank, reason, name, selected, onSelect }: RadarR > {rank} - e.stopPropagation()} - className="block font-medium text-blue-300 transition-colors hover:text-blue-200" - > - {setup.symbol} - + {setup.symbol} {name && {name}} @@ -413,9 +407,8 @@ export default function DashboardPage() { ) )} - {/* Setup in focus | Radar — the decision pair */} -
-
+ {/* Setup in focus — full width; select a radar row below to swap it */} +
{(trades.isLoading || activation.isLoading) && } {trades.isError && Failed to load setups} {trades.data && activation.data && ( @@ -444,9 +437,54 @@ export default function DashboardPage() { ) )} -
+
-
+ {/* Metric strip — the account ribbons, right above the positions they describe */} + {(trades.isLoading || openTrades.isLoading) ? ( +
+ +
+ ) : ( +
+ 0 ? `$${exposure.riskUsd.toFixed(0)}` : '—'} + sub={exposure.count > 0 ? `${exposure.count} open · distance to stops` : 'no open trades'} + /> + 0 ? fmtR(exposure.unrealR) : '—'} + valueClass={rColor(exposure.rPriced > 0 ? exposure.unrealR : null)} + sub={ + exposure.count > 0 + ? `${money(exposure.unrealUsd)} · ${exposure.winners}▲ ${exposure.losers}▼` + : 'mark-to-market' + } + /> + 0 ? money(exposure.alphaUsd) : '—'} + valueClass={ + exposure.alphaPriced > 0 + ? exposure.alphaUsd >= 0 ? 'text-emerald-300' : 'text-red-300' + : 'text-gray-100' + } + sub="open trades vs buy-and-hold SPY" + /> + 0 ? 'text-blue-300' : 'text-gray-100'} + sub={activation.data ? activationSummary(activation.data) : 'setups clearing the gate'} + /> +
+ )} + + {/* Open positions | Radar — side by side, half width each */} +
+ + +
{trades.isLoading && } {trades.data && radar.qualified.length === 0 && radar.below.length === 0 && ( @@ -535,50 +573,6 @@ export default function DashboardPage() {
- {/* Metric strip — the account ribbons, right above the positions they describe */} - {(trades.isLoading || openTrades.isLoading) ? ( -
- -
- ) : ( -
- 0 ? `$${exposure.riskUsd.toFixed(0)}` : '—'} - sub={exposure.count > 0 ? `${exposure.count} open · distance to stops` : 'no open trades'} - /> - 0 ? fmtR(exposure.unrealR) : '—'} - valueClass={rColor(exposure.rPriced > 0 ? exposure.unrealR : null)} - sub={ - exposure.count > 0 - ? `${money(exposure.unrealUsd)} · ${exposure.winners}▲ ${exposure.losers}▼` - : 'mark-to-market' - } - /> - 0 ? money(exposure.alphaUsd) : '—'} - valueClass={ - exposure.alphaPriced > 0 - ? exposure.alphaUsd >= 0 ? 'text-emerald-300' : 'text-red-300' - : 'text-gray-100' - } - sub="open trades vs buy-and-hold SPY" - /> - 0 ? 'text-blue-300' : 'text-gray-100'} - sub={activation.data ? activationSummary(activation.data) : 'setups clearing the gate'} - /> -
- )} - - {/* Open positions — full width, right under their ribbons */} - - {/* Performance — the paper book vs the same dollars in SPY */}