Tournaments
/
{tournament.name}
{tournament.name}
{tournament.status.replace('_', ' ').toUpperCase()}
{#if tournament.status === 'setup'}
Contestants
{tournament.contestants.length} total
e.key === 'Enter' && addContestant()} />
{addingContestant ? 'Adding...' : 'Add Contestant'}
{#if tournament.contestants.length > 0}
{#each tournament.contestants as contestant}
{contestant.name}
removeContestant(contestant._id)} > Remove
{/each}
Group Creation Method
Fixed number of groups
Max contestants per group
{#if groupCreationMethod === 'numGroups'}
Number of Groups
{:else}
Max Contestants Per Group
{/if}
{creatingGroups ? 'Creating...' : 'Create Groups & Start Tournament'}
{/if}
{/if} {#if tournament.status === 'group_stage'}
Group Stage
showManageContestantsModal = true}> Manage Contestants
Generate Bracket
Top contestants per group:
{#if previewBracket}
🔮 Bracket Preview
Based on current standings (Top {topNFromEachGroup} from each group)
{#each previewBracket.rounds as round, roundIndex}
{round.name}
{#each round.matches as match, matchIndex} {@const contestantIds = match.contestantIds || []}
{#if contestantIds.length === 0}
TBD
{:else} {#each contestantIds as contestantId, idx}
{getContestantName(contestantId)}
{#if idx < contestantIds.length - 1}
vs
{/if} {/each} {/if}
{/each}
{/each}
{/if} {#each tournament.groups as group}
{group.name}
Contestants:
{#each group.contestantIds as contestantId, i}
{getContestantName(contestantId)}{i < group.contestantIds.length - 1 ? ', ' : ''}
{/each}
{#each group.matches as match}
Match
{match.completed ? 'Completed' : 'In Progress'}
{#each Array(tournament.roundsPerMatch) as _, roundIndex} {@const roundNumber = roundIndex + 1} {@const existingRound = match.rounds.find(r => r.roundNumber === roundNumber)}
Round {roundNumber}
{#if existingRound}
{#each match.contestantIds as contestantId}
{getContestantName(contestantId)}
{existingRound.scores[contestantId] || 0} pts
{/each}
{:else}
openScoreEntry(group._id, match._id, roundNumber)} > Enter Scores
{/if}
{/each}
{#if match.rounds.length > 0}
Total Scores:
{#each match.contestantIds as contestantId}
{getContestantName(contestantId)}
{getTotalScore(match, contestantId)} pts
{/each}
{/if}
{/each} {#if group.standings && group.standings.length > 0}
Standings
Pos
Contestant
Total Score
{#each group.standings as standing}
{standing.position}
{getContestantName(standing.contestantId)}
{standing.totalScore}
{/each}
{/if}
{/each}
{/if} {#if tournament.status === 'bracket' || tournament.status === 'completed'}
🏆 Championship Bracket
{#if tournament.status === 'completed' && winnerName}
🏆 Champion: {winnerName}
{/if}
{#each [...tournament.bracket.rounds].reverse() as round, roundIndex} {@const visibleMatches = round.matches.filter(m => (m.contestantIds && m.contestantIds.length > 0) || roundIndex === 0)} {#if visibleMatches.length > 0}
{round.name}
{#each visibleMatches as match, matchIndex} {@const contestantIds = match.contestantIds || []}
{#if contestantIds.length === 0}
TBD
{:else} {#each contestantIds as contestantId, idx}
{getContestantName(contestantId)}
{#if match.rounds.length > 0}
{getTotalScore(match, contestantId)}
{/if}
{#if idx < contestantIds.length - 1}
vs
{/if} {/each} {/if} {#if contestantIds.length >= (tournament.matchSize || 2) && !match.completed}
{#each Array(tournament.roundsPerMatch) as _, roundIdx} {@const roundNumber = roundIdx + 1} {@const existingRound = match.rounds.find(r => r.roundNumber === roundNumber)} {#if existingRound}
R{roundNumber} ✓
{:else}
openBracketScoreEntry(match._id, roundNumber)} > R{roundNumber}
{/if} {/each}
{/if} {#if match.winnerId}
🏆 {getContestantName(match.winnerId)}
{/if}
{/each}
{/if} {/each}
{#if tournament.runnersUpBracket}
🥉 Runners-Up Bracket (Consolation)
{#each tournament.runnersUpBracket.rounds as round, roundIndex}
{round.name}
{#each round.matches as match, matchIndex} {@const contestantIds = match.contestantIds || []}
{#if contestantIds.length === 0}
TBD
{:else} {#each contestantIds as contestantId, idx}
{getContestantName(contestantId)}
{#if match.rounds.length > 0}
{getTotalScore(match, contestantId)}
{/if}
{#if idx < contestantIds.length - 1}
vs
{/if} {/each} {/if} {#if contestantIds.length >= (tournament.matchSize || 2) && !match.completed}
{#each Array(tournament.roundsPerMatch) as _, roundIdx} {@const roundNumber = roundIdx + 1} {@const existingRound = match.rounds.find(r => r.roundNumber === roundNumber)} {#if existingRound}
R{roundNumber} ✓
{:else}
openBracketScoreEntry(match._id, roundNumber)} > R{roundNumber}
{/if} {/each}
{/if} {#if match.winnerId}
🥉 {getContestantName(match.winnerId)}
{/if}
{/each}
{/each}
{/if} {/if}
{#if activeScoreEntry}
activeScoreEntry = null}>
e.stopPropagation()}>
Enter Scores - Round {activeScoreEntry.roundNumber}
activeScoreEntry = null}>×
{#each Object.keys(scoreInputs) as contestantId}
{getContestantName(contestantId)}
{/each}
{/if} {#if showManageContestantsModal}
showManageContestantsModal = false}>
e.stopPropagation()}>
Manage Contestants
showManageContestantsModal = false}>×
Add New Contestant
e.key === 'Enter' && addMidTournamentContestant()} />
{addingMidTournamentContestant ? 'Adding...' : 'Add Contestant'}
All Contestants
{#each tournament.contestants as contestant}
{contestant.name}
{#if contestant.dnf}
DNF
{/if}
toggleDNF(contestant._id, contestant.dnf)} > {contestant.dnf ? 'Reactivate' : 'Mark DNF'}
{/each}
{/if} {#if showConfetti}
{#each confettiPieces as piece (piece.id)}
{/each}
{/if}