"use client"; import { useEffect, useState } from "react"; import { type Lang, dict } from "@/lib/i18n"; import { fetchLeaderboard, type LeaderEntry, type LeaderTab, } from "@/lib/leaderboard"; // 누적 랭킹 — 참가자 / AI 모델 2탭, 폴딩(기본 접힘) // 매치 페이지(골드 카드 직후)에 삽입. defaultOpen=true 면 전체 페이지용 펼친 상태. export default function Leaderboard({ lang = "ko", defaultOpen = false, }: { lang?: Lang; defaultOpen?: boolean; }) { const t = dict(lang); const [open, setOpen] = useState(defaultOpen); const [tab, setTab] = useState("voters"); const [rows, setRows] = useState([]); // 펼쳐졌을 때 + 탭 변경 시에만 조회 (접힌 동안은 네트워크 안 씀) useEffect(() => { if (!open) return; let alive = true; fetchLeaderboard(tab).then((r) => alive && setRows(r)); return () => { alive = false; }; }, [open, tab]); return (

{t.lbTitle}

{open && ( <> {/* 탭 */}
{( [ ["voters", t.lbTabVoters], ["ai", t.lbTabAI], ] as [LeaderTab, string][] ).map(([val, label]) => ( ))}
{/* 헤더 라벨 */}
{tab === "ai" ? t.lbTabAI : t.lbTabVoters} {t.lbPoints}
{/* TOP 10 목록 */}
    {rows.map((r, i) => { const top3 = i < 3; return (
  1. {i + 1} {r.label} {r.points.toLocaleString()} {t.lbUnit}
  2. ); })}
)} {/* 폴딩 토글 — defaultOpen(전체 페이지)에서는 숨김 */} {!defaultOpen && ( )}
); }