From 63c56a11b2b0aac2e3e8b3f43c8e2a8c010ff334 Mon Sep 17 00:00:00 2001 From: Macbook Date: Sat, 6 Jun 2026 03:25:11 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A7=90=EB=A6=BC=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EB=A7=A4=EB=A7=A4=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.css | 13 +++++++++++++ .../src/components/TradeNotificationListPage.tsx | 11 +++++++++++ .../tradeNotification/TradeNotificationListRow.tsx | 8 ++++++++ 3 files changed, 32 insertions(+) diff --git a/frontend/src/App.css b/frontend/src/App.css index afe7b45..123cfd8 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -12188,6 +12188,19 @@ html.theme-light .tam-disclaimer { color: #90a4ae; } } .tnl-row-chart:hover { background: var(--bg4); color: var(--text); } +.tnl-row-trade { + padding: 0 14px; + border: none; + border-left: 1px solid var(--border); + background: rgba(38, 132, 255, 0.15); + color: #2684ff; + font-size: 12px; + font-weight: 600; + cursor: pointer; + transition: background 0.15s; +} +.tnl-row-trade:hover { background: rgba(38, 132, 255, 0.28); color: #5ba0ff; } + /* TopMenuBar 앱 다운로드 버튼 */ .tmb-app-download-btn { display: flex; diff --git a/frontend/src/components/TradeNotificationListPage.tsx b/frontend/src/components/TradeNotificationListPage.tsx index 0a3bd7d..20eda41 100644 --- a/frontend/src/components/TradeNotificationListPage.tsx +++ b/frontend/src/components/TradeNotificationListPage.tsx @@ -190,6 +190,16 @@ export const TradeNotificationListPage: React.FC = ({ setRightTab('trade'); }, [tickers]); + /** 알림 목록 아이템 "매매" 버튼 — 우측 패널 열고 해당 종목 현재가 입력 */ + const handleTradeFromAlert = useCallback((item: TradeNotificationItem) => { + if (!item.isRead) markAsRead(item.id); + const price = coerceFiniteNumber(tickers?.get(item.market)?.tradePrice) + ?? coerceFiniteNumber(item.price); + handleSelectMarket(item.market, price ?? undefined); + setRightOpen(true); + setRightTab('trade'); + }, [markAsRead, tickers, handleSelectMarket]); + const selectedCount = selectedIds.size; const handleNotificationSelect = useCallback((item: TradeNotificationItem) => { @@ -509,6 +519,7 @@ export const TradeNotificationListPage: React.FC = ({ markAsRead(item.id); setFullscreenItem(item); }} + onTrade={() => handleTradeFromAlert(item)} tickers={tickers} /> ))} diff --git a/frontend/src/components/tradeNotification/TradeNotificationListRow.tsx b/frontend/src/components/tradeNotification/TradeNotificationListRow.tsx index 4c12ee4..08da18f 100644 --- a/frontend/src/components/tradeNotification/TradeNotificationListRow.tsx +++ b/frontend/src/components/tradeNotification/TradeNotificationListRow.tsx @@ -51,6 +51,8 @@ interface Props { onDelete: (e: React.MouseEvent) => void; onDetail: () => void; onGoToChart: () => void; + /** 매매 버튼 클릭 → 우측 매매 패널 열기 */ + onTrade?: () => void; } const MAX_INDICATOR_CARDS = 8; @@ -67,6 +69,7 @@ const TradeNotificationListRow: React.FC = ({ onDelete, onDetail, onGoToChart, + onTrade, }) => { useTradeAlertTimeFormat(); const isBuy = item.signalType === 'BUY'; @@ -309,6 +312,11 @@ const TradeNotificationListRow: React.FC = ({ + {onTrade && ( + + )} );