import '../style.scss'; import { Metadata } from 'next'; import Link from 'next/link'; import PaperNav from '../_components/PaperNav'; import { fetchPaperLeaderboard } from '@/lib/api/paper'; import { changeDirection, changeSymbol } from '@/lib/utils/stock'; import { formatBpPercent, formatBpAbs, bpDirection } from '@/lib/utils/paper'; import type { PaperLeaderboardSort, PaperLeaderboardPeriod } from '@/types/paper'; export const metadata: Metadata = { title: '모의투자 리더보드 — 개미투자', description: '수익률·승률·MDD 기준 모의투자 순위 (주간/월간/전체)' }; const SORT_TABS: { value: PaperLeaderboardSort; label: string }[] = [ { value: 'return', label: '수익률' }, { value: 'winrate', label: '승률' }, { value: 'mdd', label: 'MDD' } ]; const PERIOD_TABS: { value: PaperLeaderboardPeriod; label: string }[] = [ { value: 'week', label: '주간' }, { value: 'month', label: '월간' }, { value: 'all', label: '전체' } ]; const PAGE_SIZE = 50; type Props = { searchParams: Promise<{ sort?: string; period?: string; page?: string; }>; }; export default async function PaperLeaderboardPage({ searchParams }: Props) { const query = await searchParams; const sort: PaperLeaderboardSort = SORT_TABS.some(c => c.value === query.sort) ? (query.sort as PaperLeaderboardSort) : 'return'; const period: PaperLeaderboardPeriod = PERIOD_TABS.some(c => c.value === query.period) ? (query.period as PaperLeaderboardPeriod) : 'all'; const page = Math.max(Number(query.page) || 1, 1); const res = await fetchPaperLeaderboard({ sort, period, page }); const rows = res.success ? (res.data?.rows ?? []) : []; const buildHref = (next: { sort?: PaperLeaderboardSort; period?: PaperLeaderboardPeriod }) => { const params = new URLSearchParams(); params.set('sort', next.sort ?? sort); params.set('period', next.period ?? period); return `/paper/leaderboard?${params.toString()}`; }; return (
| 순위 | 닉네임 | 수익률 | 승률 | MDD | 체결수 |
|---|---|---|---|---|---|
| {row.rank} |
{row.thumb ? (
// eslint-disable-next-line @next/next/no-img-element
|
{symbol} {formatBpPercent(row.returnBp)} | {formatBpAbs(row.winRateBp)} | {formatBpAbs(row.mddBp)} | {row.fillCount.toLocaleString()} |