feat(ui): 홈 SEED-10 타일 + 가격 헤로 sparkline

홈 페이지:
  - 텍스트 카드를 SeedTiles 컴포넌트로 교체. 10개 병렬로 /api/chart 2일치 받아
    현재가 + 전일대비 (절대값+%) 카드 그리드 (2/3/5 컬럼).
  - max-w 를 3xl → 5xl 로 확장하여 타일 5열 그리드 수용.

종목 페이지:
  - PriceHero 에 series prop 추가, 우측에 SVG sparkline (최근 30 종가) 표시.
  - 라인 색상은 전일대비 부호로 결정 (상승 빨강 / 하락 파랑).
  - lightweight-charts 인스턴스 추가 없이 인라인 SVG 만 사용 — 가벼움.

verify: tsc/next lint clean.
This commit is contained in:
claude
2026-05-28 01:27:49 +09:00
parent 832e73b5ee
commit 04358469d1
4 changed files with 209 additions and 44 deletions

View File

@@ -66,17 +66,22 @@ export default function CodePage({ params }: { params: { code: string } }) {
};
}, [code]);
// 현재가/전일가 — ohlcv 끝 두 점에서 산출.
const { current, prev, asOf } = useMemo(() => {
if (!chart || !chart.ohlcv.length) return { current: null, prev: null, asOf: null };
// 현재가/전일가 + 헤더 sparkline 시리즈 — ohlcv 끝부분에서 산출.
const { current, prev, asOf, sparkSeries } = useMemo(() => {
if (!chart || !chart.ohlcv.length)
return { current: null, prev: null, asOf: null, sparkSeries: [] as number[] };
const valid = chart.ohlcv.filter((p) => p.close != null);
if (!valid.length) return { current: null, prev: null, asOf: null };
if (!valid.length)
return { current: null, prev: null, asOf: null, sparkSeries: [] as number[] };
const last = valid[valid.length - 1];
const prevPt = valid.length >= 2 ? valid[valid.length - 2] : null;
// 최근 30개 종가 (없으면 가용 전체).
const recent = valid.slice(-30).map((p) => p.close as number);
return {
current: last.close,
prev: prevPt?.close ?? null,
asOf: last.date,
sparkSeries: recent,
};
}, [chart]);
@@ -100,6 +105,7 @@ export default function CodePage({ params }: { params: { code: string } }) {
current={current}
prev={prev}
asOf={asOf}
series={sparkSeries}
/>
<div className="grid gap-6 lg:grid-cols-[1fr_280px]">
<div>

View File

@@ -1,34 +1,28 @@
import { SearchBox } from "../components/SearchBox";
import { SeedTiles } from "../components/SeedTiles";
export default function HomePage() {
return (
<main className="mx-auto max-w-3xl px-6 py-16">
<h1 className="text-3xl font-bold tracking-tight text-zinc-50">
</h1>
<main className="mx-auto max-w-5xl px-6 py-12">
<h1 className="text-3xl font-bold tracking-tight text-zinc-50"> </h1>
<p className="mt-2 text-sm text-zinc-400">
, <b className="text-rose-300"> </b>
15·30·1 .
</p>
<div className="mt-8">
<div className="mt-6">
<SearchBox autoFocus />
</div>
<div className="mt-12 grid gap-3 text-xs text-zinc-500 sm:grid-cols-2">
<div className="rounded-lg border border-zinc-800 bg-zinc-900/30 p-4">
<div className="font-medium text-zinc-300"> 10</div>
<div className="mt-1">
, SK하이닉스, , , ,
, HD현대중공업, NAVER, KT&amp;G,
</div>
</div>
<div className="rounded-lg border border-zinc-800 bg-zinc-900/30 p-4">
<div className="font-medium text-zinc-300">/</div>
<div className="mt-1">
16:30 KST , 02:00 KST LGBM .
Chronos(zero-shot) + LightGBM.
</div>
<div className="mt-10">
<SeedTiles />
</div>
<div className="mt-6 rounded-lg border border-zinc-800 bg-zinc-900/30 p-4 text-xs text-zinc-500">
<div className="font-medium text-zinc-300"> · </div>
<div className="mt-1">
16:30 KST , 02:00 KST LGBM .
Chronos(zero-shot) + LightGBM.
</div>
</div>
</main>