import { DUNGEON_LEADERBOARD_PAGE_SIZE, type LeaderboardScope } from "../app/dungeonLeaderboardClient"; import { formatDungeonDuration, type DungeonClearFilter, type DungeonLeaderboard as LeaderboardData } from "../game/dungeonRunTypes"; import { ControllerButton } from "./ControllerButton"; import { DungeonRunDetails } from "./DungeonRunDetails"; import "./dungeonRuns.css"; export function DungeonLeaderboard({ dungeonTitle, data, scope, loading, filter, onFilter, expanded, onExpand, offset, onPage, onRefresh, difficultyLabel, onDifficulty, selectedId, select }: { readonly dungeonTitle: string; readonly data: LeaderboardData; readonly scope: LeaderboardScope; readonly loading: boolean; readonly filter: DungeonClearFilter; readonly onFilter: (filter: DungeonClearFilter) => void; readonly expanded: ReadonlySet; readonly onExpand: (id: string) => void; readonly offset: number; readonly onPage: (offset: number) => void; readonly onRefresh: () => void; readonly difficultyLabel: string; readonly onDifficulty?: () => void; readonly selectedId: string; readonly select: (id: string) => void; }) { const controls = { selectedId, select }; return

{scope === "world" ? "World leaderboard" : "This device · offline leaderboard"}

Fastest expeditions

onFilter("final")}>Final Boss clears All entries onFilter("full")}>Full dungeon clears All bosses
{onDifficulty ? {difficultyLabel} ↻ : {difficultyLabel}} {data.total} {data.total === 1 ? "run" : "runs"} Refresh
{loading ?

Loading run times…

: data.entries.length === 0 ?

No {filter === "full" ? "full dungeon" : "final boss"} clears yet. Complete a run to set the first time.

:
    {data.entries.map((entry) =>
  1. onExpand(entry.id)}> #{entry.rank}{entry.party.find((member) => !member.npc)?.name ?? entry.party[0]?.name ?? "Party"} {entry.fullClear ? "All bosses" : `${entry.killedBossIds.length} bosses`} · {new Date(entry.finishedAt).toLocaleDateString()} {expanded.has(entry.id) ?
    : null}
  2. )}
}
{data.total > DUNGEON_LEADERBOARD_PAGE_SIZE ? : null}
; }