Armería: PvP campos de batalla, logros por categoría, bandas/mazmorras y página de hermandad
- PvP: pestaña Campos de batalla (pvpstats) con resultado, stats por partida y fecha/hora. - Logros: rejilla por categoría con anillos de progreso + detalle por categoría (datos de Achievement.db2 + Achievement_Category.db2, iconos vía wowhead). - Bandas: progreso por dificultad (10/25/heroico) con jefes reales de DungeonEncounter.db2 y tooltip de jefes; agrupado por expansión (Clásico/TBC/WotLK). - Mazmorras: mismo sistema, Normal + Heroico, Clásico/TBC/WotLK. - Página de hermandad estilo armería: cabecera (emblema, puntos = unión de logros de miembros sin duplicar, nº miembros, fundada), pestañas Hermandad/Logros, roster con iconos de clase/raza, columna Función (rol por spec), filtros clase/función, orden por rango/puntos/nivel de objeto/nivel/nombre, paginación. - Barra lateral: mensaje diario con login (iron-session, gated por pertenencia), logros recientes y desgloses de clases y funciones. - Cabecera de personaje: enlace a la hermandad + nombre del reino. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import type { BgMatch } from '@/lib/armory'
|
||||
|
||||
/** Nombre + color por BattlegroundTypeId (3.4.3 WotLK). */
|
||||
const BG_TYPES: Record<number, { es: string; en: string; color: string; icon: string }> = {
|
||||
1: { es: 'Valle de Alterac', en: 'Alterac Valley', color: '#4a90d9', icon: 'fas fa-mountain' },
|
||||
2: { es: 'Garganta Grito de Guerra', en: 'Warsong Gulch', color: '#2ecc71', icon: 'fas fa-flag' },
|
||||
3: { es: 'Cuenca de Arathi', en: 'Arathi Basin', color: '#e0a13a', icon: 'fas fa-tower-observation' },
|
||||
7: { es: 'Ojo de la Tormenta', en: 'Eye of the Storm', color: '#9b59b6', icon: 'fas fa-bolt' },
|
||||
9: { es: 'Costa de los Ancestros', en: 'Strand of the Ancients', color: '#c0703a', icon: 'fas fa-ship' },
|
||||
30: { es: 'Isla de la Conquista', en: 'Isle of Conquest', color: '#5dade2', icon: 'fas fa-anchor' },
|
||||
32: { es: 'Campo de batalla aleatorio', en: 'Random Battleground', color: '#888888', icon: 'fas fa-dice' },
|
||||
}
|
||||
|
||||
export type BgLabels = {
|
||||
history: string
|
||||
desc: string
|
||||
matches: string
|
||||
wins: string
|
||||
losses: string
|
||||
winRate: string
|
||||
result: string
|
||||
win: string
|
||||
loss: string
|
||||
kb: string
|
||||
hk: string
|
||||
deaths: string
|
||||
damage: string
|
||||
healing: string
|
||||
honor: string
|
||||
date: string
|
||||
none: string
|
||||
battleground: string
|
||||
}
|
||||
|
||||
export function ArmoryBattlegrounds({
|
||||
locale,
|
||||
rows,
|
||||
matches,
|
||||
wins,
|
||||
losses,
|
||||
winRate,
|
||||
labels,
|
||||
}: {
|
||||
locale: string
|
||||
rows: BgMatch[]
|
||||
matches: number
|
||||
wins: number
|
||||
losses: number
|
||||
winRate: number
|
||||
labels: BgLabels
|
||||
}) {
|
||||
const fmt = (n: number) => n.toLocaleString(locale)
|
||||
const fmtDate = (iso: string) => {
|
||||
const d = new Date(iso)
|
||||
if (Number.isNaN(d.getTime())) return '—'
|
||||
const day = d.toLocaleDateString(locale, { day: '2-digit', month: 'short', year: 'numeric' })
|
||||
const time = d.toLocaleTimeString(locale, { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false })
|
||||
return (
|
||||
<span className="armory-bg-dt">
|
||||
<span className="armory-bg-dt-d">{day}</span>
|
||||
<span className="armory-bg-dt-t">{time}</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
const bgOf = (type: number) =>
|
||||
BG_TYPES[type] || { es: `BG #${type}`, en: `BG #${type}`, color: '#777', icon: 'fas fa-khanda' }
|
||||
|
||||
return (
|
||||
<div className="armory-panel armory-bg-panel">
|
||||
<div className="armory-bg-header">
|
||||
<div className="armory-quest-title">
|
||||
<i className="fas fa-flag-checkered" /> {labels.history}
|
||||
</div>
|
||||
<p className="armory-bg-desc">{labels.desc}</p>
|
||||
</div>
|
||||
|
||||
<div className="armory-bg-summary">
|
||||
<div className="armory-bg-stat">
|
||||
<span className="armory-bg-stat-num" style={{ color: '#ffd100' }}>
|
||||
{fmt(matches)}
|
||||
</span>
|
||||
<span className="armory-bg-stat-lbl">{labels.matches}</span>
|
||||
</div>
|
||||
<div className="armory-bg-stat">
|
||||
<span className="armory-bg-stat-num" style={{ color: '#2ecc71' }}>
|
||||
{fmt(wins)}
|
||||
</span>
|
||||
<span className="armory-bg-stat-lbl">{labels.wins}</span>
|
||||
</div>
|
||||
<div className="armory-bg-stat">
|
||||
<span className="armory-bg-stat-num" style={{ color: '#ff5555' }}>
|
||||
{fmt(losses)}
|
||||
</span>
|
||||
<span className="armory-bg-stat-lbl">{labels.losses}</span>
|
||||
</div>
|
||||
<div className="armory-bg-stat">
|
||||
<span className="armory-bg-stat-num" style={{ color: '#e0a13a' }}>
|
||||
{winRate}%
|
||||
</span>
|
||||
<span className="armory-bg-stat-lbl">{labels.winRate}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{rows.length === 0 ? (
|
||||
<p className="armory-hint">{labels.none}</p>
|
||||
) : (
|
||||
<div className="armory-bg-table-wrap">
|
||||
<table className="armory-quest-table armory-bg-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{labels.battleground}</th>
|
||||
<th className="armory-bg-c">{labels.result}</th>
|
||||
<th className="armory-bg-c">{labels.kb}</th>
|
||||
<th className="armory-bg-c">{labels.hk}</th>
|
||||
<th className="armory-bg-c">{labels.deaths}</th>
|
||||
<th className="armory-bg-c">{labels.damage}</th>
|
||||
<th className="armory-bg-c">{labels.healing}</th>
|
||||
<th className="armory-bg-c">{labels.honor}</th>
|
||||
<th className="armory-bg-c">{labels.date}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((m) => {
|
||||
const bg = bgOf(m.type)
|
||||
const name = locale === 'en' ? bg.en : bg.es
|
||||
return (
|
||||
<tr key={m.id}>
|
||||
<td>
|
||||
<span className="armory-bg-name">
|
||||
<span className="armory-bg-ico" style={{ background: bg.color }}>
|
||||
<i className={bg.icon} />
|
||||
</span>
|
||||
{name}
|
||||
</span>
|
||||
</td>
|
||||
<td className="armory-bg-c">
|
||||
<span className={`armory-bg-res ${m.won ? 'win' : 'loss'}`}>{m.won ? labels.win : labels.loss}</span>
|
||||
</td>
|
||||
<td className="armory-bg-c armory-bg-kb">{fmt(m.killingBlows)}</td>
|
||||
<td className="armory-bg-c">{fmt(m.honorableKills)}</td>
|
||||
<td className="armory-bg-c">{fmt(m.deaths)}</td>
|
||||
<td className="armory-bg-c">{fmt(m.damage)}</td>
|
||||
<td className="armory-bg-c">{fmt(m.healing)}</td>
|
||||
<td className="armory-bg-c armory-bg-honor">{fmt(m.bonusHonor)}</td>
|
||||
<td className="armory-bg-c armory-bg-date">{fmtDate(m.date)}</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user