From c42d3fe8d4c4f0148f94a647f535d368a348066f Mon Sep 17 00:00:00 2001 From: gahusb Date: Tue, 12 May 2026 14:21:05 +0900 Subject: [PATCH] =?UTF-8?q?feat(stock):=20ResultTable=20=EB=B3=B8=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20+=20ScoreChips=20(=EB=85=B8=EB=93=9C=20=EC=B9=A9=20?= =?UTF-8?q?+=2070=EC=A0=90=20=EA=B0=95=EC=A1=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/stock/screener/Screener.css | 9 +++ .../stock/screener/components/ResultTable.jsx | 65 ++++++++++++++----- .../stock/screener/components/ScoreChips.jsx | 32 +++++++++ 3 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 src/pages/stock/screener/components/ScoreChips.jsx diff --git a/src/pages/stock/screener/Screener.css b/src/pages/stock/screener/Screener.css index 43e2617..b843321 100644 --- a/src/pages/stock/screener/Screener.css +++ b/src/pages/stock/screener/Screener.css @@ -59,3 +59,12 @@ } .node-card-header { font-weight: 500; margin-bottom: 6px; } .weight-row, .param-row { display: flex; align-items: center; gap: 6px; margin-top: 6px; } + +.screener-table { + width: 100%; + font-size: 13px; + border-collapse: collapse; +} +.screener-table th { text-align: left; padding: 8px; background: #0a0f1a; color: #9ca3af; font-weight: 500; border-bottom: 1px solid #1f2937; } +.screener-table td { padding: 8px; border-bottom: 1px solid #1a2230; vertical-align: middle; } +.screener-table tr:hover { background: #0a0f1a; } diff --git a/src/pages/stock/screener/components/ResultTable.jsx b/src/pages/stock/screener/components/ResultTable.jsx index 3393286..0f849e2 100644 --- a/src/pages/stock/screener/components/ResultTable.jsx +++ b/src/pages/stock/screener/components/ResultTable.jsx @@ -1,25 +1,54 @@ +import ScoreChips from './ScoreChips'; + export default function ResultTable({ result }) { - if (!result) return

아직 결과 없음. "지금 실행"을 눌러보세요.

; + if (!result) { + return ( +
+

아직 결과 없음. "지금 실행"을 눌러보세요.

+
+ ); + } + return (
-

Top {result.top_n} · 통과 {result.survivors_count}

- - - - - - {(result.results || []).map((r) => ( - - - - - - - +
+

+ Top {result.top_n} · 통과 {result.survivors_count} · {result.asof} +

+ {result.warnings?.length > 0 && ( +
+ ⚠ {result.warnings.join(' · ')} +
+ )} +
+ +
+
#종목총점진입손절익절R%
{r.rank}{r.name} ({r.ticker}){r.total_score?.toFixed?.(1)}{r.entry_price?.toLocaleString?.()}{r.stop_price?.toLocaleString?.()}{r.target_price?.toLocaleString?.()}{r.r_pct?.toFixed?.(1)}
+ + + + - ))} - -
#종목총점노드진입손절익절R%
+ + + {(result.results || []).map((r) => ( + + {r.rank} + {r.name}
{r.ticker} + {r.total_score?.toFixed(1)} + + {r.entry_price?.toLocaleString?.()} + {r.stop_price?.toLocaleString?.()} + {r.target_price?.toLocaleString?.()} + {r.r_pct?.toFixed?.(1)} + + ))} + + +
); } diff --git a/src/pages/stock/screener/components/ScoreChips.jsx b/src/pages/stock/screener/components/ScoreChips.jsx new file mode 100644 index 0000000..34ed5df --- /dev/null +++ b/src/pages/stock/screener/components/ScoreChips.jsx @@ -0,0 +1,32 @@ +const NODE_ICONS = { + foreign_buy: { icon: '👤', label: '외국인' }, + volume_surge: { icon: '⚡', label: '거래량' }, + momentum: { icon: '🚀', label: '모멘텀' }, + high52w: { icon: '🆙', label: '52w고' }, + rs_rating: { icon: '💪', label: 'RS' }, + ma_alignment: { icon: '📈', label: '정배열' }, + vcp_lite: { icon: '🌀', label: 'VCP' }, +}; + +export default function ScoreChips({ scores }) { + return ( +
+ {Object.entries(scores || {}).map(([name, s]) => { + const meta = NODE_ICONS[name]; + if (!meta) return null; + const active = s >= 70; + return ( + + {meta.icon}{Math.round(s)} + + ); + })} +
+ ); +}