Refactored duels table

This commit is contained in:
2025-09-02 12:57:29 +02:00
parent 16b200bc7d
commit 83031f6526
2 changed files with 59 additions and 571 deletions

View File

@@ -1,6 +1,6 @@
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { formatNumber } from "@/lib/formatters"
import { getDuelsModeStats, getModeTitle } from "@/lib/hypixel/duels/duels"
import { getBestDuelsMode, getDuelsModeStats, getModeTitle } from "@/lib/hypixel/duels/duels"
import { NonNullStats } from "@/lib/schema/player"
export default function DuelsStatTable({ stats }: { stats: NonNullStats["Duels"] }) {
@@ -8,37 +8,37 @@ export default function DuelsStatTable({ stats }: { stats: NonNullStats["Duels"]
<Table>
<DuelsTableHeader />
<TableBody>
<Bedwars1v1Stats stats={stats} />
<Bedwars1v1RushStats stats={stats} />
<UHC1v1Stats stats={stats} />
<UHC2v2Stats stats={stats} />
<UHC4v4Stats stats={stats} />
<UHCMeetupStats stats={stats} />
<OP1v1Stats stats={stats} />
<OP2v2Stats stats={stats} />
<SkyWars1v1Stats stats={stats} />
<SkyWars2v2Stats stats={stats} />
<Bow1v1Stats stats={stats} />
<Blitz1v1Stats stats={stats} />
<MegaWalls1v1Stats stats={stats} />
<MegaWalls2v2Stats stats={stats} />
<Sumo1v1Stats stats={stats} />
<BowSpleef1v1Stats stats={stats} />
<ParkourFFAStats stats={stats} />
<Boxing1v1Stats stats={stats} />
<Classic1v1Stats stats={stats} />
<Classic2v2Stats stats={stats} />
<Potion1v1Stats stats={stats} />
<Combo1v1Stats stats={stats} />
<Quake1v1Stats stats={stats} />
<Spleef1v1Stats stats={stats} />
<Bridge1v1Stats stats={stats} />
<Bridge2v2Stats stats={stats} />
<Bridge3v3Stats stats={stats} />
<Bridge4v4Stats stats={stats} />
<Bridge2v2v2v2Stats stats={stats} />
<Bridge3v3v3v3Stats stats={stats} />
<DuelArenaStats stats={stats} />
<DuelsStat modeId="bedwars_two_one_duels" stats={stats} />
<DuelsStat modeId="bedwars_two_one_duels_rush" stats={stats} />
<DuelsStat modeId="uhc_duel" stats={stats} />
<DuelsStat modeId="uhc_doubles" stats={stats} />
<DuelsStat modeId="uhc_four" stats={stats} />
<DuelsStat modeId="uhc_meetup" stats={stats} />
<DuelsStat modeId="op_duel" stats={stats} />
<DuelsStat modeId="op_doubles" stats={stats} />
<DuelsStat modeId="sw_duel" stats={stats} />
<DuelsStat modeId="sw_doubles" stats={stats} />
<DuelsStat modeId="bow_duel" stats={stats} />
<DuelsStat modeId="blitz_duel" stats={stats} />
<DuelsStat modeId="mw_duel" stats={stats} />
<DuelsStat modeId="mw_doubles" stats={stats} />
<DuelsStat modeId="sumo_duel" stats={stats} />
<DuelsStat modeId="bowspleef_duel" stats={stats} />
<DuelsStat modeId="parkour_eight" stats={stats} />
<DuelsStat modeId="boxing_duel" stats={stats} />
<DuelsStat modeId="classic_duel" stats={stats} />
<DuelsStat modeId="classic_doubles" stats={stats} />
<DuelsStat modeId="potion_duel" stats={stats} />
<DuelsStat modeId="combo_duel" stats={stats} />
<DuelsStat modeId="quake_duel" stats={stats} />
<DuelsStat modeId="spleef_duel" stats={stats} />
<DuelsStat modeId="bridge_duel" stats={stats} />
<DuelsStat modeId="bridge_doubles" stats={stats} />
<DuelsStat modeId="bridge_threes" stats={stats} />
<DuelsStat modeId="bridge_four" stats={stats} />
<DuelsStat modeId="bridge_2v2v2v2" stats={stats} />
<DuelsStat modeId="bridge_3v3v3v3" stats={stats} />
<DuelsStat modeId="duel_arena" stats={stats} />
</TableBody>
</Table>
)
@@ -72,529 +72,25 @@ function DuelsTableHeader() {
)
}
function Bedwars1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
function DuelsStat(
{ modeId, stats }: { modeId: Parameters<typeof getModeTitle>[0], stats: NonNullStats["Duels"] }
) {
if (!stats) return null
const modeStats = getDuelsModeStats("bedwars_two_one_duels", stats)
const title = getModeTitle("bedwars_two_one_duels")
const modeStats = getDuelsModeStats(modeId, stats)
const title = getModeTitle(modeId)
const bestMode = getBestDuelsMode(stats) === modeId
const divisionLabel = "I"
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bedwars1v1RushStats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bedwars_two_one_duels_rush", stats)
const title = getModeTitle("bedwars_two_one_duels_rush")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function UHC1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("uhc_duel", stats)
const title = getModeTitle("uhc_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function UHC2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("uhc_doubles", stats)
const title = getModeTitle("uhc_doubles")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function UHC4v4Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("uhc_four", stats)
const title = getModeTitle("uhc_four")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function UHCMeetupStats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("uhc_meetup", stats)
const title = getModeTitle("uhc_meetup")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function OP1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("op_duel", stats)
const title = getModeTitle("op_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function OP2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("op_doubles", stats)
const title = getModeTitle("op_doubles")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function SkyWars1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("sw_duel", stats)
const title = getModeTitle("sw_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function SkyWars2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("sw_doubles", stats)
const title = getModeTitle("sw_doubles")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function MegaWalls1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("mw_duel", stats)
const title = getModeTitle("mw_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function MegaWalls2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("mw_doubles", stats)
const title = getModeTitle("mw_doubles")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bow1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bow_duel", stats)
const title = getModeTitle("bow_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Blitz1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("blitz_duel", stats)
const title = getModeTitle("blitz_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Sumo1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("sumo_duel", stats)
const title = getModeTitle("sumo_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function BowSpleef1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bowspleef_duel", stats)
const title = getModeTitle("bowspleef_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function ParkourFFAStats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("parkour_eight", stats)
const title = getModeTitle("parkour_eight")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Boxing1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("boxing_duel", stats)
const title = getModeTitle("boxing_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Classic1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("classic_duel", stats)
const title = getModeTitle("classic_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Classic2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("classic_doubles", stats)
const title = getModeTitle("classic_doubles")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Potion1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("potion_duel", stats)
const title = getModeTitle("potion_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Combo1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("combo_duel", stats)
const title = getModeTitle("combo_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bridge1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bridge_duel", stats)
const title = getModeTitle("bridge_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bridge2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bridge_doubles", stats)
const title = getModeTitle("bridge_doubles")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bridge3v3Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bridge_threes", stats)
const title = getModeTitle("bridge_threes")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bridge4v4Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bridge_four", stats)
const title = getModeTitle("bridge_four")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bridge2v2v2v2Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bridge_2v2v2v2", stats)
const title = getModeTitle("bridge_2v2v2v2")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Bridge3v3v3v3Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("bridge_3v3v3v3", stats)
const title = getModeTitle("bridge_3v3v3v3")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function DuelArenaStats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("duel_arena", stats)
const title = getModeTitle("duel_arena")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Quake1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("quake_duel", stats)
const title = getModeTitle("quake_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
</TableRow>
)
}
function Spleef1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) {
if (!stats) return null
const modeStats = getDuelsModeStats("spleef_duel", stats)
const title = getModeTitle("spleef_duel")
return (
<TableRow>
<TableCell>{title}</TableCell>
<TableCell>I</TableCell>
{modeStats.map((v, i) => {
return <TableCell key={i}>{typeof v === "number" ? formatNumber(v) : v}</TableCell>
})}
<TableCell className={bestMode ? "font-bold text-mc-light-purple" : undefined}>{title}</TableCell>
<TableCell>{divisionLabel}</TableCell>
{modeStats.map((v, i) => (
<TableCell className={bestMode ? "font-bold text-mc-light-purple" : undefined} key={i}>
{typeof v === "number" ? formatNumber(v) : v}
</TableCell>
))}
</TableRow>
)
}

View File

@@ -46,27 +46,19 @@ export function getMostPlayed(stats: NonNullable<NonNullStats["Duels"]>) {
type Mode = typeof MODES[number]["id"]
// export function getBestMode(stats: NonNullable<NonNullStats["Duels"]>) {
// const { wins_bedwars: solo } = getBedwarsModeStats("solo", stats, true)
// const { wins_bedwars: doubles } = getBedwarsModeStats("doubles", stats, true)
// const { wins_bedwars: threes } = getBedwarsModeStats("3s", stats, true)
// const { wins_bedwars: fours } = getBedwarsModeStats("4s", stats, true)
//
// const max = Math.max(solo, doubles, threes, fours)
//
// switch (max) {
// case solo:
// return "solo"
// case doubles:
// return "doubles"
// case threes:
// return "3s"
// case fours:
// return "4s"
// default:
// return null
// }
// }
export function getBestDuelsMode(stats: NonNullable<NonNullStats["Duels"]>) {
let best: typeof MODES[number] | null = null
let mostPlays = 0
for (const mode of MODES) {
const [, , , wins, losses] = getDuelsModeStats(mode.id, stats)
const plays = (wins as number || 0) + (losses as number || 0)
if (plays > mostPlays) {
mostPlays = plays
best = mode
}
}
return best === null ? null : best.id
}
export function getDuelsModeStats(mode: Mode, stats: NonNullable<NonNullStats["Duels"]>) {
return duelsModeStats(mode, stats)