'use client'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { fetchApi } from '@/lib/utils/client'; import useAuth from '@/hooks/useAuth'; import { useMemberContext } from '@/contexts/memberProvider'; import Loading from '@/app/component/Loading'; import RankingTabs from './RankingTabs'; import PeriodFilter from './PeriodFilter'; import CategoryFilter from './CategoryFilter'; import Podium from './Podium'; import RankingList from './RankingList'; import MyRankBar from './MyRankBar'; import type { RankingResponse, RankingPeriod, RankingType } from '@/types/response/ranking'; interface Props { type: 'comprehensive'|'creator'|'donor'; basePath: string; } export default function RankingView({ type, basePath }: Props) { const router = useRouter(); const searchParams = useSearchParams(); const { isAuthenticated } = useAuth(); const { member } = useMemberContext(); const initialPeriod = (searchParams.get('period') as RankingPeriod) || 'month'; const initialCategory = searchParams.get('category') || 'all'; const [period, setPeriod] = useState(initialPeriod); const [category, setCategory] = useState(initialCategory); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const viewerMemberID = isAuthenticated ? member?.id ?? null : null; const loadData = useCallback(() => { setLoading(true); const qs = new URLSearchParams(); qs.set('type', type); qs.set('period', period); qs.set('category', category); qs.set('page', '1'); qs.set('perPage', '50'); fetchApi(`/api/ranking?${qs.toString()}`, { silent: true }).then((res) => { setData(res.data ?? null); }).catch(() => { setData(null); }).finally(() => { setLoading(false); }); }, [type, period, category]); useEffect(() => { loadData(); }, [loadData]); useEffect(() => { const qs = new URLSearchParams(); if (period !== 'month') { qs.set('period', period); } if (category !== 'all') { qs.set('category', category); } const query = qs.toString(); router.replace(query ? `${basePath}?${query}` : basePath, { scroll: false }); }, [period, category, basePath, router]); const asRankingType: RankingType = type; const snapshotLabel = useMemo(() => { if (!data?.snapshotAt) { return null; } const d = new Date(data.snapshotAt); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} 기준`; }, [data?.snapshotAt]); return (

순위

{type !== 'donor' ? : null}
{loading ? ( ) : ( <> {data && data.top3.length > 0 ? ( ) : null} {snapshotLabel ?

{snapshotLabel}

: null} {data?.myRank ? : null} )}
); }