"use client"; // 테마 상세 페이지: /themes/{slug}. // 카드 그리드로 해당 테마 종목을 나열. close/pct_change 없으면 자리만 표시. import Link from "next/link"; import { useEffect, useState } from "react"; import { api, type ThemeDetailResponse } from "../../../lib/api"; export default function ThemePage({ params }: { params: { slug: string } }) { const { slug } = params; const [data, setData] = useState(null); const [err, setErr] = useState(null); useEffect(() => { let alive = true; setErr(null); setData(null); api .themeDetail(slug, 60) .then((r) => { if (alive) setData(r); }) .catch((e) => { if (alive) setErr(e instanceof Error ? e.message : String(e)); }); return () => { alive = false; }; }, [slug]); return (
← 홈
{err &&
테마 로딩 실패: {err}
} {!data && !err &&
테마 로딩 중…
} {data && ( <>

{data.name}

{data.description}

{data.items.length} 종목
{data.items.map((m) => { const pct = m.pct_change; const tone = pct == null || pct === 0 ? "text-zinc-400" : pct > 0 ? "text-rose-400" : "text-sky-400"; return (
{m.name}
{m.market ?? "—"}
{m.close != null ? m.close.toLocaleString(undefined, { maximumFractionDigits: 0, }) : "—"} {pct != null ? `${pct >= 0 ? "+" : ""}${pct.toFixed(2)}%` : ""}
{m.code}
); })}
)}
); }