// // TournamentRankView.swift // PadelClub // // Created by Razmig Sarkissian on 30/04/2024. // import SwiftUI import LeStorage struct TournamentRankView: View { @Environment(Tournament.self) var tournament: Tournament @EnvironmentObject var dataStore: DataStore @State private var rankings: [Int: [TeamRegistration]] = [:] var body: some View { List { Section { let matchs = tournament.runningMatches(tournament.allMatches()) let rankingPublished = tournament.selectedSortedTeams().allSatisfy({ $0.finalRanking != nil }) LabeledContent { Text(matchs.count.formatted()) } label: { Text("Matchs en cours") } LabeledContent { if rankingPublished { Image(systemName: "checkmark") } else { Image(systemName: "xmark") } } label: { Text("Classement publiƩ") } RowButtonView(rankingPublished ? "Re-publier le classement" : "Publier le classement", role: .destructive) { rankings.keys.sorted().forEach { rank in if let rankedTeams = rankings[rank] { rankedTeams.forEach { team in team.finalRanking = rank team.pointsEarned = tournament.tournamentLevel.points(for: rank - 1, count: tournament.teamCount) } } } _save() } } footer: { FooterButtonView("masquer le classement", role: .destructive) { tournament.unsortedTeams().forEach { team in team.finalRanking = nil team.pointsEarned = nil } _save() } } let keys = rankings.keys.sorted() ForEach(keys, id: \.self) { key in if let rankedTeams = rankings[key] { ForEach(rankedTeams) { team in HStack { VStack(alignment: .trailing) { VStack(alignment: .trailing, spacing: -8.0) { ZStack(alignment: .trailing) { Text(tournament.teamCount.formatted()).hidden() Text(key.formatted()) } .monospacedDigit() .font(.largeTitle) .fontWeight(.bold) Text(key.ordinalFormattedSuffix()).font(.caption) } if let index = tournament.indexOf(team: team) { let rankingDifference = index - (key - 1) if rankingDifference > 0 { HStack(spacing: 0.0) { Text(rankingDifference.formatted(.number.sign(strategy: .always()))) .monospacedDigit() Image(systemName: "arrowtriangle.up.fill") .imageScale(.small) } .foregroundColor(.green) } else if rankingDifference < 0 { HStack(spacing: 0.0) { Text(rankingDifference.formatted(.number.sign(strategy: .always()))) .monospacedDigit() Image(systemName: "arrowtriangle.down.fill") .imageScale(.small) } .foregroundColor(.red) } else { Text("--") } } } Divider() VStack(alignment: .leading) { ForEach(team.players()) { player in VStack(alignment: .leading, spacing: -4.0) { Text(player.playerLabel()).bold() HStack(alignment: .firstTextBaseline, spacing: 0.0) { Text(player.rankLabel()) if let rank = player.getRank() { Text(rank.ordinalFormattedSuffix()) .font(.caption) } } } } } Spacer() VStack(alignment: .trailing) { HStack(alignment: .lastTextBaseline, spacing: 0.0) { Text(tournament.tournamentLevel.points(for: key - 1, count: tournament.teamCount).formatted(.number.sign(strategy: .always()))) Text("pts").font(.caption) } } } } } } } .onAppear { let finalRanks = tournament.finalRanking() finalRanks.keys.sorted().forEach { rank in if let rankedTeamIds = finalRanks[rank] { rankings[rank] = rankedTeamIds.compactMap { Store.main.findById($0) } } } } .navigationTitle("Classement") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.visible, for: .navigationBar) } private func _save() { do { try dataStore.teamRegistrations.addOrUpdate(contentOfs: tournament.unsortedTeams()) } catch { Logger.error(error) } } } #Preview { TournamentRankView() }