'use client' import { useEffect, useRef, useState } from 'react' export type PvpRankEntry = { rank: number; guid: number; name: string; race: number; class: number; kills: number; playedTime: number } const MEDAL = ['🥇', '🥈', '🥉'] /** Ranking mundial de bajas: búsqueda por nombre + paginación (API). */ export function ArmoryPvpRank({ locale, initial, total: initialTotal, pageSize, labels, }: { locale: string initial: PvpRankEntry[] total: number pageSize: number labels: { title: string desc: string search: string empty: string character: string kills: string playedTime: string } }) { const [entries, setEntries] = useState(initial) const [total, setTotal] = useState(initialTotal) const [page, setPage] = useState(1) const [q, setQ] = useState('') const [loading, setLoading] = useState(false) const pages = Math.max(1, Math.ceil(total / pageSize)) const load = async (p: number, search: string) => { setLoading(true) try { const res = await fetch(`/api/armory/pvprank?page=${p}&q=${encodeURIComponent(search)}&locale=${locale}`) const data = await res.json() setEntries(Array.isArray(data.entries) ? data.entries : []) setTotal(Number(data.total) || 0) } catch { setEntries([]) } finally { setLoading(false) } } const skip = useRef(true) useEffect(() => { if (skip.current) { skip.current = false return } const t = setTimeout(() => { setPage(1) load(1, q) }, 300) return () => clearTimeout(t) // eslint-disable-next-line react-hooks/exhaustive-deps }, [q]) const goto = (p: number) => { if (p < 1 || p > pages || p === page || loading) return setPage(p) load(p, q) } const fmtTime = (sec: number) => { const d = Math.floor(sec / 86400) const h = Math.floor((sec % 86400) / 3600) const m = Math.floor((sec % 3600) / 60) return `${d}d ${h}h ${m}m` } const win = 2 const from = Math.max(1, page - win) const to = Math.min(pages, page + win) const nums: number[] = [] for (let p = from; p <= to; p++) nums.push(p) return (
{labels.title}

{labels.desc}

setQ(e.target.value)} placeholder={labels.search} /> {entries.length === 0 ? (

{labels.empty}

) : ( {entries.map((e) => ( ))}
# {labels.character} {labels.kills} {labels.playedTime}
{e.rank <= 3 ? {MEDAL[e.rank - 1]} : null} {e.rank} {e.name} {e.kills.toLocaleString(locale)} {fmtTime(e.playedTime)}
)} {pages > 1 && (
{from > 1 && ( <> {from > 2 && …} )} {nums.map((p) => ( ))} {to < pages && ( <> {to < pages - 1 && …} )}
)}
) }