You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
8.0 KiB
188 lines
8.0 KiB
//
|
|
// RoundSettingsView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 31/03/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import LeStorage
|
|
|
|
struct RoundSettingsView: View {
|
|
@EnvironmentObject var dataStore: DataStore
|
|
|
|
@Environment(\.isEditingTournamentSeed) private var isEditingTournamentSeed
|
|
@Environment(Tournament.self) var tournament: Tournament
|
|
|
|
var tournamentStore: TournamentStore {
|
|
return self.tournament.tournamentStore
|
|
}
|
|
|
|
var body: some View {
|
|
List {
|
|
if tournament.shouldVerifyBracket {
|
|
Section {
|
|
let issues = tournament.bracketTeamPlacementIssue()
|
|
DisclosureGroup {
|
|
ForEach(issues.shouldBeInIt, id: \.self) { id in
|
|
if let team: TeamRegistration = Store.main.findById(id) {
|
|
TeamRowView(team: team)
|
|
}
|
|
}
|
|
} label: {
|
|
LabeledContent {
|
|
Text(issues.shouldBeInIt.count.formatted())
|
|
} label: {
|
|
Text("Équipes à mettre dans le tableau")
|
|
}
|
|
}
|
|
DisclosureGroup {
|
|
ForEach(issues.shouldNotBeInIt, id: \.self) { id in
|
|
if let team = self.tournamentStore.teamRegistrations.findById(id) {
|
|
Menu {
|
|
Button("Retirer du tableau") {
|
|
team.resetBracketPosition()
|
|
do {
|
|
try self.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
} label: {
|
|
TeamRowView(team: team)
|
|
}
|
|
}
|
|
}
|
|
} label: {
|
|
LabeledContent {
|
|
Text(issues.shouldNotBeInIt.count.formatted())
|
|
} label: {
|
|
Text("Équipes à retirer du tableau")
|
|
}
|
|
}
|
|
|
|
RowButtonView("Valider l'état du tableau", role: .destructive) {
|
|
tournament.shouldVerifyBracket = false
|
|
do {
|
|
try dataStore.tournaments.addOrUpdate(instance: tournament)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
} footer: {
|
|
Text("Suite à un changement dans votre liste d'inscrits, veuillez vérifier l'intégrité de votre tableau et valider que tout est ok.")
|
|
}
|
|
}
|
|
|
|
// Section {
|
|
// RowButtonView("Enabled", role: .destructive) {
|
|
// let allMatches = tournament._allMatchesIncludingDisabled()
|
|
// allMatches.forEach({
|
|
// $0.disabled = false
|
|
// $0.byeState = false
|
|
// })
|
|
// try? dataStore.matches.addOrUpdate(contentOfs: allMatches)
|
|
// }
|
|
// }
|
|
Section {
|
|
RowButtonView("Retirer toutes les têtes de séries", role: .destructive) {
|
|
await _removeAllSeeds()
|
|
}
|
|
}
|
|
|
|
Section {
|
|
let roundIndex = tournament.rounds().count
|
|
RowButtonView("Ajouter " + RoundRule.roundName(fromRoundIndex: roundIndex)) {
|
|
let round = Round(tournament: tournament.id, index: roundIndex, matchFormat: tournament.matchFormat)
|
|
let matchCount = RoundRule.numberOfMatches(forRoundIndex: roundIndex)
|
|
let matchStartIndex = RoundRule.matchIndex(fromRoundIndex: roundIndex)
|
|
let nextRound = round.nextRound()
|
|
var currentIndex = 0
|
|
let matches = (0..<matchCount).map { index in //0 is final match
|
|
let computedIndex = index + matchStartIndex
|
|
let match = Match(round: round.id, index: computedIndex, matchFormat: round.matchFormat)
|
|
if let nextRound, let followingMatch = self.tournament.tournamentStore.matches.first(where: { $0.round == nextRound.id && $0.index == (computedIndex - 1) / 2 }) {
|
|
if followingMatch.disabled {
|
|
match.disabled = true
|
|
} else if computedIndex%2 == 1 && followingMatch.team(.one) != nil {
|
|
//index du match courant impair = position haut du prochain match
|
|
match.disabled = true
|
|
} else if computedIndex%2 == 0 && followingMatch.team(.two) != nil {
|
|
//index du match courant pair = position basse du prochain match
|
|
match.disabled = true
|
|
} else {
|
|
match.name = Match.setServerTitle(upperRound: round, matchIndex: currentIndex)
|
|
currentIndex += 1
|
|
}
|
|
} else {
|
|
match.name = Match.setServerTitle(upperRound: round, matchIndex: currentIndex)
|
|
currentIndex += 1
|
|
}
|
|
|
|
return match
|
|
}
|
|
do {
|
|
try tournamentStore.rounds.addOrUpdate(instance: round)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
do {
|
|
try tournamentStore.matches.addOrUpdate(contentOfs: matches)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
round.buildLoserBracket()
|
|
matches.filter { $0.disabled }.forEach { $0._toggleLoserMatchDisableState(true)
|
|
}
|
|
}
|
|
}
|
|
|
|
Section {
|
|
if let lastRound = tournament.rounds().first { // first is final, last round
|
|
RowButtonView("Supprimer " + lastRound.roundTitle(), role: .destructive) {
|
|
do {
|
|
let teams = lastRound.seeds()
|
|
teams.forEach { team in
|
|
team.resetBracketPosition()
|
|
}
|
|
try tournamentStore.teamRegistrations.addOrUpdate(contentOfs: teams)
|
|
try tournamentStore.rounds.delete(instance: lastRound)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func _removeAllSeeds() async {
|
|
tournament.unsortedTeams().forEach({ team in
|
|
team.bracketPosition = nil
|
|
})
|
|
let ts = tournament.allRoundMatches().flatMap { match in
|
|
match.teamScores
|
|
}
|
|
|
|
do {
|
|
try tournamentStore.teamScores.delete(contentOfs: ts)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
do {
|
|
try tournamentStore.teamRegistrations.addOrUpdate(contentOfs: tournament.unsortedTeams())
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
tournament.allRounds().forEach({ round in
|
|
round.enableRound()
|
|
})
|
|
self.isEditingTournamentSeed.wrappedValue = true
|
|
}
|
|
}
|
|
|
|
//#Preview {
|
|
// RoundSettingsView()
|
|
// .environment(Tournament.mock())
|
|
// .environmentObject(DataStore.shared)
|
|
//}
|
|
|