From 232b94755a6aff5697588134f67b0f974d198e53 Mon Sep 17 00:00:00 2001 From: claude-owner Date: Mon, 1 Jun 2026 10:47:44 +0900 Subject: [PATCH] refactor(returns): extract shared ReturnBucket from Intraday/PeriodReturns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IntradayReturns(1D 10분봉 모드)와 PeriodReturns(일봉 이상)는 페이지의 같은 슬롯에서 모드 전환으로 갈아끼우는 한 쌍이다. 두 컴포넌트의 Bucket 서브컴포넌트는 className 문자열까지 완전히 동일했지만 각 파일에 별도 정의돼 있었다 — 한쪽 톤만 바꾸면 모드 전환 시 시각적 점프가 생기는 드리프트 리스크. 신규 web/components/ReturnBucket.tsx 로 단일 source of truth 분리: - 색 규칙(rose/sky/zinc), 카드 톤(rounded-md border-zinc-800 bg-zinc-900/30 px-2 py-2 text-center), 라벨/값 타이포 일괄 캡슐화. - 두 패널은 각자 horizon 라벨/계산 로직만 유지하고 렌더는 ReturnBucket 으로 위임. 기존 외부 동작/시각 결과 동일 — 동일한 className 을 한 곳으로 묶은 순수 리팩토링. 검증: - npx tsc --noEmit clean - npx next lint "✔ No ESLint warnings or errors" --- web/components/IntradayReturns.tsx | 23 +++-------------------- web/components/PeriodReturns.tsx | 24 +++--------------------- web/components/ReturnBucket.tsx | 28 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 41 deletions(-) create mode 100644 web/components/ReturnBucket.tsx diff --git a/web/components/IntradayReturns.tsx b/web/components/IntradayReturns.tsx index 32d00ff..3572f78 100644 --- a/web/components/IntradayReturns.tsx +++ b/web/components/IntradayReturns.tsx @@ -13,6 +13,7 @@ // 추가 백엔드 호출 없음 — chart.ohlcv 슬라이싱만. import type { OhlcvPoint } from "../lib/api"; +import { ReturnBucket } from "./ReturnBucket"; const BUCKETS: { label: string; bars: number }[] = [ { label: "10분", bars: 1 }, @@ -55,27 +56,9 @@ export function IntradayReturns({ ohlcv }: { ohlcv: OhlcvPoint[] }) {
{buckets.map((b) => ( - + ))} - -
- - ); -} - -function Bucket({ label, pct }: { label: string; pct: number | null }) { - // 한국식 컬러 — 상승=rose, 하락=sky, 0/null=zinc. - const tone = - pct == null || pct === 0 - ? "text-zinc-400" - : pct > 0 - ? "text-rose-400" - : "text-sky-400"; - return ( -
-
{label}
-
- {pct == null ? "—" : `${pct >= 0 ? "+" : ""}${pct.toFixed(2)}%`} +
); diff --git a/web/components/PeriodReturns.tsx b/web/components/PeriodReturns.tsx index 1b9d432..31ae2c2 100644 --- a/web/components/PeriodReturns.tsx +++ b/web/components/PeriodReturns.tsx @@ -5,6 +5,7 @@ // 거래일 기준 근사: 1주≈5, 1개월≈21, 3개월≈63, 6개월≈126, 1년≈252. import type { OhlcvPoint } from "../lib/api"; +import { ReturnBucket } from "./ReturnBucket"; const BUCKETS: { label: string; days: number }[] = [ { label: "1주", days: 5 }, @@ -45,28 +46,9 @@ export function PeriodReturns({ ohlcv }: { ohlcv: OhlcvPoint[] }) {
{buckets.map((b) => ( - + ))} - -
- - ); -} - -function Bucket({ label, pct }: { label: string; pct: number | null }) { - const tone = - pct == null || pct === 0 - ? "text-zinc-400" - : pct > 0 - ? "text-rose-400" - : "text-sky-400"; - return ( -
-
{label}
-
- {pct == null - ? "—" - : `${pct >= 0 ? "+" : ""}${pct.toFixed(2)}%`} +
); diff --git a/web/components/ReturnBucket.tsx b/web/components/ReturnBucket.tsx new file mode 100644 index 0000000..4ca34ae --- /dev/null +++ b/web/components/ReturnBucket.tsx @@ -0,0 +1,28 @@ +// 수익률 미니 셀 — IntradayReturns(1D 10분봉 모드) 와 PeriodReturns(일봉 이상) 가 같은 +// 슬롯에서 모드 전환으로 갈아끼우므로 두 패널의 Bucket 톤/색 규칙은 반드시 동일해야 한다. +// 예전엔 각 파일에 동일한 Bucket 이 중복 정의돼 있어 한쪽만 톤을 바꾸면 모드 전환 시 +// 시각적 점프가 생길 위험이 있었다. 한 곳으로 묶어 단일 source of truth 로 둔다. +// +// 한국식 컬러 규칙: 상승 = rose, 하락 = sky, 0/null = zinc (Toss 톤). + +type Props = { + label: string; + pct: number | null; +}; + +export function ReturnBucket({ label, pct }: Props) { + const tone = + pct == null || pct === 0 + ? "text-zinc-400" + : pct > 0 + ? "text-rose-400" + : "text-sky-400"; + return ( +
+
{label}
+
+ {pct == null ? "—" : `${pct >= 0 ? "+" : ""}${pct.toFixed(2)}%`} +
+
+ ); +}