diff --git a/frontend/src/components/ticker/RecommendationPanel.tsx b/frontend/src/components/ticker/RecommendationPanel.tsx index 646934c..a6d1283 100644 --- a/frontend/src/components/ticker/RecommendationPanel.tsx +++ b/frontend/src/components/ticker/RecommendationPanel.tsx @@ -1,4 +1,5 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; +import { createPortal } from 'react-dom'; import type { TradeSetup } from '../../lib/types'; import { formatPrice, formatPercent } from '../../lib/format'; import { useCreatePaperTrade } from '../../hooks/usePaperTrades'; @@ -220,6 +221,16 @@ function SetupCard({ setup, action, currentPrice, risk, regime, selectedPrice, o const activeRR = selected?.rr_ratio ?? setup.rr_ratio; const activeProb = selected?.probability ?? prob; + // Close the take dialog on Escape. + useEffect(() => { + if (!taking) return; + const onKey = (e: globalThis.KeyboardEvent) => { + if (e.key === 'Escape') setTaking(false); + }; + window.addEventListener('keydown', onKey); + return () => window.removeEventListener('keydown', onKey); + }, [taking]); + const confirmTake = () => { createTrade.mutate( { @@ -343,66 +354,85 @@ function SetupCard({ setup, action, currentPrice, risk, regime, selectedPrice, o scaleTo={(setup.targets ?? []).map((t) => t.price)} /> - {taking && ( -
-
- - -
- {setup.targets && setup.targets.length > 1 ? ( - + +
+ {setup.targets && setup.targets.length > 1 ? ( + + ) : null} + +
+ - + {createTrade.isPending ? 'Taking…' : 'Confirm trade'} + + +
- + , + document.body, )} {/* Target ladder — open by default; clicking a row previews it on the rail */}