bracket visualization bug fixes

This commit is contained in:
2026-03-13 16:13:20 +01:00
parent b164f287af
commit 82f5da58f8
3 changed files with 53 additions and 11 deletions

View File

@@ -120,11 +120,11 @@ export class MatchService {
[matchId],
(err, match: any) => {
if (err) return reject(err);
if (!match) return reject(new Error('Match nicht gefunden'));
if (!match) return reject(new Error('Match not found'));
// Validate that the winnerId is one of the participants
if (match.team1Id !== winnerId && match.team2Id !== winnerId) {
return reject(new Error('Der Sieger muss eines der Teams dieses Matches sein'));
return reject(new Error('Winner must be one of the match participants'));
}
// Update the match with winner
@@ -182,7 +182,7 @@ export class MatchService {
[matchId],
(err, match: any) => {
if (err) return reject(err);
if (!match) return reject(new Error('Match nicht gefunden'));
if (!match) return reject(new Error('Match not found'));
const previousWinnerId = match.winnerId;

View File

@@ -178,4 +178,17 @@ Folgende Dateien wurden in diesem Prompt verändert:
- Style the tournament list and detail page to look closer to the rest of the app.
Folgende Dateien wurden in diesem Prompt verändert:
- frontend_splatournament_manager/lib/widgets/available_tournament_list.dart
- frontend_splatournament_manager/lib/pages/tournament_detail_page.dart
- frontend_splatournament_manager/lib/pages/tournament_detail_page.dart
- The bracket visualization shows enough space for 8 teams when the max team amount is only 4 and the bracket was initialized.
Folgende Dateien wurden in diesem Prompt verändert:
- frontend_splatournament_manager/lib/pages/tournament_bracket_page.dart
- The winner isn't being shown in the final card.
Folgende Dateien wurden in diesem Prompt verändert:
- frontend_splatournament_manager/lib/pages/tournament_bracket_page.dart
- lock the matches if the next game match winner was already chosen.
Folgende Dateien wurden in diesem Prompt verändert:
- backend_splatournament_manager/src/services/match-service.ts
- frontend_splatournament_manager/lib/pages/tournament_bracket_page.dart

View File

@@ -236,7 +236,11 @@ class _BracketBoard extends StatelessWidget {
}
double _cardTop(int round, int index) {
final slotHeight = _baseSlotHeight * (1 << round).toDouble();
if (round == roundCount - 1) {
final contentHeight = bracketSize * _baseSlotHeight.toDouble();
return _headerHeight + (contentHeight - _cardHeight) / 2;
}
final slotHeight = _baseSlotHeight * (1 << (round + 1)).toDouble();
return _headerHeight + index * slotHeight + (slotHeight - _cardHeight) / 2;
}
@@ -266,7 +270,9 @@ class _BracketBoard extends StatelessWidget {
// Build bracket
for (int round = 0; round < roundCount; round++) {
final cardsInRound = bracketSize ~/ (1 << round);
final cardsInRound = round == roundCount - 1
? 1
: bracketSize ~/ (1 << (round + 1));
final left = round * (_cardWidth + _connectorWidth);
// Round label
@@ -292,7 +298,16 @@ class _BracketBoard extends StatelessWidget {
// Match cards
for (int i = 0; i < cardsInRound; i++) {
final match = _findMatch(round, i);
final isSieger = round == roundCount - 1;
final match = isSieger
? _findMatch(round - 1, 0)
: _findMatch(round, i);
// Lock match if its downstream match already has a winner
final downstreamMatch = (!isSieger && round < roundCount - 2)
? _findMatch(round + 1, i ~/ 2)
: null;
final isLocked = downstreamMatch != null && downstreamMatch.hasWinner;
children.add(
Positioned(
@@ -303,7 +318,11 @@ class _BracketBoard extends StatelessWidget {
child: _MatchCard(
match: match,
teamMap: teamMap,
onTap: match != null && match.canBePlayed && !match.hasWinner
showWinnerOnly: isSieger,
isLocked: isLocked,
onTap: isSieger || isLocked
? null
: match != null && match.canBePlayed && !match.hasWinner
? () {
final team1 = teamMap[match.team1Id];
final team2 = teamMap[match.team2Id];
@@ -395,8 +414,16 @@ class _MatchCard extends StatelessWidget {
final Match? match;
final Map<int, Team> teamMap;
final VoidCallback? onTap;
final bool showWinnerOnly;
final bool isLocked;
const _MatchCard({this.match, required this.teamMap, this.onTap});
const _MatchCard({
this.match,
required this.teamMap,
this.onTap,
this.showWinnerOnly = false,
this.isLocked = false,
});
@override
Widget build(BuildContext context) {
@@ -429,7 +456,9 @@ class _MatchCard extends StatelessWidget {
elevation: match!.hasWinner ? 3 : 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: match!.hasWinner
side: isLocked
? BorderSide(color: colorScheme.outlineVariant, width: 1)
: match!.hasWinner
? BorderSide(color: colorScheme.primary, width: 2)
: BorderSide.none,
),
@@ -438,7 +467,7 @@ class _MatchCard extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (team1 != null && team2 != null) ...[
if (!showWinnerOnly && team1 != null && team2 != null) ...[
_TeamLabel(
team: team1,
isWinner: match!.winnerId == team1.id,