'use client'; import { useEffect, useMemo, useState, type ChangeEvent } from 'react'; import { Search } from 'lucide-react'; import type { CreatorItem } from '@/types/response/channel/creators'; import CreatorCard from './CreatorCard'; type SortKey = 'random'|'subscribers'|'followers'|'name'; const SORT_OPTIONS: { value: SortKey; label: string }[] = [ { value: 'random', label: '무작위' }, { value: 'subscribers', label: '구독자순' }, { value: 'followers', label: '팔로워순' }, { value: 'name', label: '이름순' } ]; const PAGE_SIZE = 50; function shuffle(arr: T[]): T[] { const a = [...arr]; for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } export default function CreatorExplorer({ creators }: { creators: CreatorItem[] }) { const [keyword, setKeyword] = useState(''); const [sort, setSort] = useState('random'); const [visibleCount, setVisibleCount] = useState(PAGE_SIZE); const [randomized, setRandomized] = useState(null); // 첫 진입 무작위 정렬 — 마운트 후 1회 (SSR/hydration 불일치 방지) useEffect(() => { setRandomized(shuffle(creators)); }, [creators]); const filtered = useMemo(() => { let list = sort === 'random' ? (randomized ?? creators) : [...creators]; const kw = keyword.trim().toLowerCase(); if (kw) { list = list.filter(c => c.name.toLowerCase().includes(kw) || (c.handle?.toLowerCase().includes(kw) ?? false)); } if (sort === 'subscribers') { list = [...list].sort((a, b) => b.subscriberCount - a.subscriberCount); } else if (sort === 'followers') { list = [...list].sort((a, b) => b.followerCount - a.followerCount); } else if (sort === 'name') { list = [...list].sort((a, b) => a.name.localeCompare(b.name)); } return list; }, [creators, randomized, keyword, sort]); const visible = filtered.slice(0, visibleCount); const hasMore = visible.length < filtered.length; const handleSortChange = (e: ChangeEvent) => { setSort(e.target.value as SortKey); setVisibleCount(PAGE_SIZE); }; const handleKeywordChange = (e: ChangeEvent) => { setKeyword(e.target.value); setVisibleCount(PAGE_SIZE); }; return (

크리에이터 {filtered.length.toLocaleString()}

e.preventDefault()} className="flex gap-2">
{filtered.length === 0 ? (

크리에이터가 없습니다.

) : ( <>
{visible.map(c => ( ))}
{hasMore && (
)} )}
); }