|
|
|
|
@ -238,96 +238,98 @@ struct TableStructureView: View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Section { |
|
|
|
|
if groupStageCount > 0 { |
|
|
|
|
if selectedTournament == nil { |
|
|
|
|
|
|
|
|
|
Section { |
|
|
|
|
if groupStageCount > 0 { |
|
|
|
|
if structurePreset != .doubleGroupStage { |
|
|
|
|
LabeledContent { |
|
|
|
|
Text(teamsFromGroupStages.formatted()) |
|
|
|
|
} label: { |
|
|
|
|
Text("Équipes en poule") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LabeledContent { |
|
|
|
|
Text((qualifiedFromGroupStage + (groupStageCount > 0 ? groupStageAdditionalQualified : 0)).formatted()) |
|
|
|
|
} label: { |
|
|
|
|
Text("Équipes qualifiées de poule") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if structurePreset != .doubleGroupStage { |
|
|
|
|
LabeledContent { |
|
|
|
|
Text(teamsFromGroupStages.formatted()) |
|
|
|
|
Text(tsPure.formatted()) |
|
|
|
|
} label: { |
|
|
|
|
Text("Équipes en poule") |
|
|
|
|
Text("Équipes à placer en tableau") |
|
|
|
|
|
|
|
|
|
if groupStageCount > 0 && tsPure > 0 && (tsPure > teamCount / 2 || tsPure < teamCount / 8 || tsPure < qualifiedFromGroupStage + groupStageAdditionalQualified) { |
|
|
|
|
Text("Attention !").foregroundStyle(.red) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if groupStageCount > 0 { |
|
|
|
|
// LabeledContent { |
|
|
|
|
// Text(tf.formatted()) |
|
|
|
|
// } label: { |
|
|
|
|
// Text("Effectif tableau") |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
} else { |
|
|
|
|
LabeledContent { |
|
|
|
|
Text((qualifiedFromGroupStage + (groupStageCount > 0 ? groupStageAdditionalQualified : 0)).formatted()) |
|
|
|
|
let mp1 = teamsPerGroupStage * (teamsPerGroupStage - 1) / 2 * groupStageCount |
|
|
|
|
let mp2 = (groupStageCount * (groupStageCount - 1) / 2) * teamsPerGroupStage |
|
|
|
|
Text((mp1 + mp2).formatted()) |
|
|
|
|
} label: { |
|
|
|
|
Text("Équipes qualifiées de poule") |
|
|
|
|
Text("Total de matchs") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if structurePreset != .doubleGroupStage { |
|
|
|
|
|
|
|
|
|
LabeledContent { |
|
|
|
|
Text(tsPure.formatted()) |
|
|
|
|
FooterButtonView("configurer") { |
|
|
|
|
showSeedRepartition = true |
|
|
|
|
} |
|
|
|
|
} label: { |
|
|
|
|
Text("Équipes à placer en tableau") |
|
|
|
|
|
|
|
|
|
if groupStageCount > 0 && tsPure > 0 && (tsPure > teamCount / 2 || tsPure < teamCount / 8 || tsPure < qualifiedFromGroupStage + groupStageAdditionalQualified) { |
|
|
|
|
Text("Attention !").foregroundStyle(.red) |
|
|
|
|
if tournament.state() == .build { |
|
|
|
|
Text("Répartition des équipes") |
|
|
|
|
} else if selectedTournament != nil { |
|
|
|
|
Text("La configuration du tournoi séléctionné sera utilisée.") |
|
|
|
|
} else { |
|
|
|
|
Text(_seeds()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.onAppear { |
|
|
|
|
if seedRepartition.isEmpty && tournament.state() == .initial && selectedTournament == nil { |
|
|
|
|
seedRepartition = HeadManagerView.place(heads: tsPure, teamsInBracket: tf, initialSeedRound: nil) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if groupStageCount > 0 { |
|
|
|
|
// LabeledContent { |
|
|
|
|
// Text(tf.formatted()) |
|
|
|
|
// } label: { |
|
|
|
|
// Text("Effectif tableau") |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
} else { |
|
|
|
|
LabeledContent { |
|
|
|
|
let mp1 = teamsPerGroupStage * (teamsPerGroupStage - 1) / 2 * groupStageCount |
|
|
|
|
let mp2 = (groupStageCount * (groupStageCount - 1) / 2) * teamsPerGroupStage |
|
|
|
|
Text((mp1 + mp2).formatted()) |
|
|
|
|
} label: { |
|
|
|
|
Text("Total de matchs") |
|
|
|
|
} footer: { |
|
|
|
|
if tsPure > 0 && structurePreset != .doubleGroupStage, groupStageCount > 0, tsPure < qualifiedFromGroupStage + groupStageAdditionalQualified { |
|
|
|
|
Text("Le nombre de têtes de série ne devrait pas être inférieur au nombre de paires qualifiées sortantes.").foregroundStyle(.red) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LabeledContent { |
|
|
|
|
FooterButtonView("configurer") { |
|
|
|
|
showSeedRepartition = true |
|
|
|
|
} |
|
|
|
|
} label: { |
|
|
|
|
if tournament.state() == .build { |
|
|
|
|
Text("Répartition des équipes") |
|
|
|
|
} else if selectedTournament != nil { |
|
|
|
|
Text("La configuration du tournoi séléctionné sera utilisée.") |
|
|
|
|
} else { |
|
|
|
|
Text(_seeds()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.onAppear { |
|
|
|
|
if seedRepartition.isEmpty && tournament.state() == .initial && selectedTournament == nil { |
|
|
|
|
seedRepartition = HeadManagerView.place(heads: tsPure, teamsInBracket: tf, initialSeedRound: nil) |
|
|
|
|
if structurePreset.hasWildcards() && tournament.level.wildcardArePossible() { |
|
|
|
|
Section { |
|
|
|
|
Toggle("Avec wildcards", isOn: $buildWildcards) |
|
|
|
|
} footer: { |
|
|
|
|
Text("Padel Club réservera des places pour eux dans votre liste d'inscription.") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} footer: { |
|
|
|
|
if tsPure > 0 && structurePreset != .doubleGroupStage, groupStageCount > 0, tsPure < qualifiedFromGroupStage + groupStageAdditionalQualified { |
|
|
|
|
Text("Le nombre de têtes de série ne devrait pas être inférieur au nombre de paires qualifiées sortantes.").foregroundStyle(.red) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if structurePreset.hasWildcards() && tournament.level.wildcardArePossible() { |
|
|
|
|
Section { |
|
|
|
|
Toggle("Avec wildcards", isOn: $buildWildcards) |
|
|
|
|
} footer: { |
|
|
|
|
Text("Padel Club réservera des places pour eux dans votre liste d'inscription.") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if tournament.rounds().isEmpty && tournament.state() == .build { |
|
|
|
|
Section { |
|
|
|
|
RowButtonView("Ajouter un tableau", role: .destructive) { |
|
|
|
|
tournament.buildBracket(minimalBracketTeamCount: 4) |
|
|
|
|
|
|
|
|
|
if tournament.rounds().isEmpty && tournament.state() == .build { |
|
|
|
|
Section { |
|
|
|
|
RowButtonView("Ajouter un tableau", role: .destructive) { |
|
|
|
|
tournament.buildBracket(minimalBracketTeamCount: 4) |
|
|
|
|
} |
|
|
|
|
} footer: { |
|
|
|
|
Text("Vous pourrez ensuite modifier le nombre de tour dans l'écran de réglages du tableau.") |
|
|
|
|
} |
|
|
|
|
} footer: { |
|
|
|
|
Text("Vous pourrez ensuite modifier le nombre de tour dans l'écran de réglages du tableau.") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if tournament.state() != .initial { |
|
|
|
|
if seedRepartition.isEmpty == false { |
|
|
|
|
Section { |
|
|
|
|
@ -661,7 +663,7 @@ struct TableStructureView: View { |
|
|
|
|
tournament.tournamentStore?.matches.addOrUpdate(contentOfs: tournament._allMatchesIncludingDisabled()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if seedRepartition.count > 0 { |
|
|
|
|
if seedRepartition.count > 0, selectedTournament == nil { |
|
|
|
|
await _handleSeedRepartition() |
|
|
|
|
} |
|
|
|
|
} else if (rebuildEverything == false && requirements.contains(.groupStage)) { |
|
|
|
|
@ -683,13 +685,16 @@ struct TableStructureView: View { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func _handleSeedRepartition() async { |
|
|
|
|
while tournament.rounds().count < seedRepartition.count { |
|
|
|
|
await tournament.addNewRound(tournament.rounds().count) |
|
|
|
|
let rounds = tournament.rounds() |
|
|
|
|
var roundsCount = rounds.count |
|
|
|
|
while roundsCount < seedRepartition.count { |
|
|
|
|
await tournament.addNewRound(roundsCount) |
|
|
|
|
roundsCount += 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if seedRepartition.reduce(0, +) > 0 { |
|
|
|
|
let rounds = tournament.rounds() |
|
|
|
|
let roundsToDelete = rounds.suffix(rounds.count - seedRepartition.count) |
|
|
|
|
let roundsToDelete = rounds.prefix(rounds.count - seedRepartition.count) |
|
|
|
|
for round in roundsToDelete { |
|
|
|
|
await tournament.removeRound(round) |
|
|
|
|
} |
|
|
|
|
|