'use client' import { useState } from 'react' import { wowheadIcon, wowheadUrl, wowheadData } from '@/lib/wowhead' import { WowheadRefresh } from './WowheadRefresh' export type AchCat = { id: number name: string total: number completed: number totalPoints: number earnedPoints: number pct: number isFeats: boolean } export type AchDetailItem = { id: number name: string description: string reward: string icon: string points: number date: number } const PAGE_SIZE = 20 function ringColor(pct: number) { if (pct >= 90) return '#4ade5f' if (pct >= 50) return '#e0902f' return '#d97b28' } export function ArmoryAchievements({ locale, guid, categories, earnedPoints, totalCompleted, apiPath = '/api/armory/achievements', idKey = 'guid', labels, }: { locale: string guid: number categories: AchCat[] earnedPoints: number totalCompleted: number apiPath?: string idKey?: string labels: { summary: string back: string reward: string empty: string of: string feats: string } }) { const [cat, setCat] = useState(null) const [entries, setEntries] = useState([]) const [total, setTotal] = useState(0) const [page, setPage] = useState(1) const [loading, setLoading] = useState(false) const pages = Math.max(1, Math.ceil(total / PAGE_SIZE)) const open = async (c: AchCat, p = 1) => { setCat(c) setPage(p) setLoading(true) try { const res = await fetch(`${apiPath}?${idKey}=${guid}&cat=${c.id}&page=${p}&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 goto = (p: number) => { if (!cat || p < 1 || p > pages || p === page || loading) return open(cat, p) } const fmtDate = (unix: number) => { if (!unix) return '' const d = new Date(unix * 1000) if (Number.isNaN(d.getTime())) return '' return d.toLocaleDateString(locale, { day: '2-digit', month: '2-digit', year: 'numeric' }) } // ---- Vista detalle de una categoría ---- if (cat) { const from = Math.max(1, page - 2) const to = Math.min(pages, page + 2) const nums: number[] = [] for (let p = from; p <= to; p++) nums.push(p) return (
{cat.name} {cat.completed} {labels.of} {cat.total} {cat.isFeats ? '' : ` · ${cat.earnedPoints} / ${cat.totalPoints}`}
{entries.length === 0 && !loading ? (

{labels.empty}

) : (
    {entries.map((a) => (
  • {a.name} {a.description ?

    {a.description}

    : null} {a.reward ? (

    {labels.reward}: {a.reward}

    ) : null}
    {a.points > 0 ? ( {a.points} ) : null} {fmtDate(a.date)}
  • ))}
)} {pages > 1 && (
{from > 1 && ( <> {from > 2 && } )} {nums.map((p) => ( ))} {to < pages && ( <> {to < pages - 1 && } )}
)}
) } // ---- Vista rejilla de categorías ---- const totalAch = categories.reduce((s, c) => s + c.total, 0) const summary = labels.summary .replace('{done}', String(totalCompleted)) .replace('{total}', String(totalAch)) .replace('{points}', String(earnedPoints)) return (

{summary}

{categories.map((c) => { const col = ringColor(c.pct) return ( ) })}
) }