diff --git a/web/components/NewsList.tsx b/web/components/NewsList.tsx index fc70693..5373af7 100644 --- a/web/components/NewsList.tsx +++ b/web/components/NewsList.tsx @@ -1,7 +1,12 @@ "use client"; +// 토스증권 뉴스 카드 스타일을 흉내낸 리스트. +// +// 백엔드가 OG 썸네일은 아직 안 주므로 텍스트 카드 + 감성 칩 + 출처 배지만. +// 썸네일은 백엔드에 og_image 컬럼이 들어오면 추가. + import { useEffect, useState } from "react"; -import { api, type NewsResponse } from "../lib/api"; +import { api, type NewsItem, type NewsResponse } from "../lib/api"; export function NewsList({ code }: { code: string }) { const [data, setData] = useState(null); @@ -29,44 +34,83 @@ export function NewsList({ code }: { code: string }) { return (
-
최근 뉴스/공시
-
); } -function sentimentColor(l: string): string { - if (l === "positive") return "text-emerald-400"; - if (l === "negative") return "text-red-400"; - return "text-zinc-400"; +function NewsCard({ n }: { n: NewsItem }) { + return ( +
  • + +
    {n.title}
    +
    + + {n.published_at && ( + {formatRelative(n.published_at)} + )} + {n.sentiment_label && ( + + )} +
    +
    +
  • + ); } -function formatDate(iso: string): string { +function SourceBadge({ source }: { source: string }) { + return ( + {source} + ); +} + +function SentimentChip({ + label, + score, +}: { + label: string; + score: number | null; +}) { + // KR 관행: 긍정=빨강, 부정=파랑 (StockChart 와 톤 일치) + const tone = + label === "positive" + ? "bg-rose-500/15 text-rose-300" + : label === "negative" + ? "bg-sky-500/15 text-sky-300" + : "bg-zinc-700/40 text-zinc-400"; + const text = + label === "positive" ? "긍정" : label === "negative" ? "부정" : "중립"; + return ( + + {text} + {score != null && ` ${score >= 0 ? "+" : ""}${score.toFixed(2)}`} + + ); +} + +function formatRelative(iso: string): string { try { const d = new Date(iso); - return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`; + const now = Date.now(); + const diffMin = Math.round((now - d.getTime()) / 60000); + if (diffMin < 1) return "방금"; + if (diffMin < 60) return `${diffMin}분 전`; + if (diffMin < 60 * 24) return `${Math.round(diffMin / 60)}시간 전`; + if (diffMin < 60 * 24 * 7) return `${Math.round(diffMin / (60 * 24))}일 전`; + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; } catch { return iso; }