mrrrp
This commit is contained in:
+70
-33
@@ -5536,37 +5536,12 @@ function inferSwissRounds(sides) {
|
||||
})
|
||||
}
|
||||
|
||||
function TeamTotals({ matches, navigate, highlight, onHover }) {
|
||||
const teams = useMemo(() => {
|
||||
const map = {}
|
||||
for (const match of matches) {
|
||||
const teamA = displayTeamName(match.team_a_name)
|
||||
const teamB = displayTeamName(match.team_b_name)
|
||||
const winner = displayTeamName(match.winner_name)
|
||||
for (const name of [teamA, teamB]) {
|
||||
if (!name) continue
|
||||
if (!map[name]) map[name] = { wins: 0, losses: 0 }
|
||||
if (winner) {
|
||||
if (winner === name) map[name].wins++
|
||||
else map[name].losses++
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.entries(map)
|
||||
.map(([name, s]) => ({ name, wins: s.wins, losses: s.losses, total: s.wins + s.losses }))
|
||||
.sort((a, b) => b.wins - a.wins || a.losses - b.losses || a.name.localeCompare(b.name))
|
||||
}, [matches])
|
||||
|
||||
if (!teams.length) return null
|
||||
|
||||
function TeamTotalsRoundTable({ teams, highlight, onHover, navigate }) {
|
||||
const active = Boolean(highlight)
|
||||
|
||||
if (!teams.length) return null
|
||||
return (
|
||||
<div className={`overflow-hidden rounded-lg border border-border bg-fury-white shadow-sm${active ? ' has-trace' : ''}`}>
|
||||
<p className="border-b border-border px-5 py-3 text-xs font-semibold uppercase tracking-wide text-fury-cyan">
|
||||
TEAM TOTALS
|
||||
</p>
|
||||
<div className="grid grid-cols-[1fr_3rem_3rem_4rem] gap-2 border-b border-border px-5 py-3 text-xs font-semibold uppercase tracking-wide text-text-soft">
|
||||
<div className="grid grid-cols-[1fr_3rem_3rem_4rem] gap-2 border-b border-border px-3 py-2 text-xs font-semibold uppercase tracking-wide text-text-soft">
|
||||
<p>Team</p>
|
||||
<p className="text-center">W</p>
|
||||
<p className="text-center">L</p>
|
||||
@@ -5577,7 +5552,7 @@ function TeamTotals({ matches, navigate, highlight, onHover }) {
|
||||
const wr = team.total > 0 ? Math.round(team.wins / team.total * 100) : 0
|
||||
return (
|
||||
<div
|
||||
className={`grid grid-cols-[1fr_3rem_3rem_4rem] items-center gap-2 border-b border-surface px-5 py-2.5 text-sm team-total-row${traced}`}
|
||||
className={`grid grid-cols-[1fr_3rem_3rem_4rem] items-center gap-2 border-b border-surface px-3 py-1.5 text-sm team-total-row${traced}`}
|
||||
key={team.name}
|
||||
onMouseEnter={() => onHover?.({ [team.name.toLowerCase()]: 'win' })}
|
||||
onMouseLeave={() => onHover?.(null)}
|
||||
@@ -5599,6 +5574,68 @@ function TeamTotals({ matches, navigate, highlight, onHover }) {
|
||||
)
|
||||
}
|
||||
|
||||
function TeamTotals({ sides, navigate, highlight, onHover }) {
|
||||
const roundTotals = useMemo(() => {
|
||||
return sides.flatMap((side) => {
|
||||
const running = {}
|
||||
return side.columns.map((column) => {
|
||||
for (const match of column.matches) {
|
||||
const teamA = displayTeamName(match.team_a_name)
|
||||
const teamB = displayTeamName(match.team_b_name)
|
||||
const winner = displayTeamName(match.winner_name)
|
||||
for (const name of [teamA, teamB]) {
|
||||
if (!name) continue
|
||||
if (!running[name]) running[name] = { wins: 0, losses: 0 }
|
||||
if (winner) {
|
||||
if (winner === name) running[name].wins++
|
||||
else running[name].losses++
|
||||
}
|
||||
}
|
||||
}
|
||||
const teams = Object.entries(running)
|
||||
.map(([name, s]) => ({ name, wins: s.wins, losses: s.losses, total: s.wins + s.losses }))
|
||||
.sort((a, b) => b.wins - a.wins || a.losses - b.losses || a.name.localeCompare(b.name))
|
||||
return { label: column.label, teams }
|
||||
})
|
||||
})
|
||||
}, [sides])
|
||||
|
||||
if (!roundTotals.length) return null
|
||||
|
||||
const active = Boolean(highlight)
|
||||
|
||||
return (
|
||||
<div className="bracket-side">
|
||||
<p className="mb-3 text-sm font-semibold uppercase tracking-wide text-fury-violet">
|
||||
TEAM TOTALS
|
||||
</p>
|
||||
<BracketViewport>
|
||||
<div className={`tournament-bracket-grid${active ? ' has-trace' : ''}`}>
|
||||
{roundTotals.map((round, index) => (
|
||||
<div className="tournament-list-column" key={index}>
|
||||
<button
|
||||
aria-expanded
|
||||
className="tournament-list-round-btn"
|
||||
type="button"
|
||||
>
|
||||
{round.label}
|
||||
</button>
|
||||
<div className="min-w-0 flex-1">
|
||||
<TeamTotalsRoundTable
|
||||
teams={round.teams}
|
||||
highlight={highlight}
|
||||
onHover={onHover}
|
||||
navigate={navigate}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</BracketViewport>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function TournamentDetailPage({ tournamentId, navigate }) {
|
||||
const [state, setState] = useState({ status: 'loading', data: null, error: null })
|
||||
|
||||
@@ -5627,8 +5664,8 @@ function TournamentDetailPage({ tournamentId, navigate }) {
|
||||
}, [matches])
|
||||
const bracketSides = sides.filter((side) => side.kind === 'bracket')
|
||||
const listSides = sides.filter((side) => side.kind === 'list')
|
||||
const swissMatches = useMemo(() => {
|
||||
return listSides.filter((s) => s.key === 'swiss').flatMap((s) => s.columns.flatMap((c) => c.matches))
|
||||
const swissSides = useMemo(() => {
|
||||
return listSides.filter((s) => s.key === 'swiss')
|
||||
}, [listSides])
|
||||
const standings = data?.standings || []
|
||||
const hasStandings = standings.length > 0
|
||||
@@ -5688,8 +5725,8 @@ function TournamentDetailPage({ tournamentId, navigate }) {
|
||||
{bracketSides.length ? <h2 className="text-lg font-semibold">Group stage</h2> : null}
|
||||
{hasStandings ? <TournamentStandings standings={standings} /> : null}
|
||||
{listSides.length ? <TournamentMatchList highlight={highlight} navigate={navigate} onHover={onHover} sides={listSides} /> : null}
|
||||
{swissMatches.length ? (
|
||||
<TeamTotals matches={swissMatches} navigate={navigate} highlight={highlight} onHover={onHover} />
|
||||
{swissSides.length ? (
|
||||
<TeamTotals sides={swissSides} navigate={navigate} highlight={highlight} onHover={onHover} />
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user