diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index c8384c1..4a2c01b 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -771,6 +771,12 @@ FF967D0F2BAF63B000A9A3BD /* PlayerBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF967D0E2BAF63B000A9A3BD /* PlayerBlockView.swift */; }; FF9AC3952BE3627B00C2E883 /* GroupStageTeamReplacementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF9AC3942BE3627B00C2E883 /* GroupStageTeamReplacementView.swift */; }; FFA1B1292BB71773006CE248 /* PadelClubButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA1B1282BB71773006CE248 /* PadelClubButtonView.swift */; }; + FFA252A92CDB70520074E63F /* PlayerStatisticView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252A82CDB70520074E63F /* PlayerStatisticView.swift */; }; + FFA252AA2CDB70520074E63F /* PlayerStatisticView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252A82CDB70520074E63F /* PlayerStatisticView.swift */; }; + FFA252AB2CDB70520074E63F /* PlayerStatisticView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252A82CDB70520074E63F /* PlayerStatisticView.swift */; }; + FFA252AD2CDB734A0074E63F /* UmpireStatisticView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252AC2CDB734A0074E63F /* UmpireStatisticView.swift */; }; + FFA252AE2CDB734A0074E63F /* UmpireStatisticView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252AC2CDB734A0074E63F /* UmpireStatisticView.swift */; }; + FFA252AF2CDB734A0074E63F /* UmpireStatisticView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA252AC2CDB734A0074E63F /* UmpireStatisticView.swift */; }; FFA6D7852BB0B795003A31F3 /* FileImportManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA6D7842BB0B795003A31F3 /* FileImportManager.swift */; }; FFA6D7872BB0B7A2003A31F3 /* CloudConvert.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA6D7862BB0B7A2003A31F3 /* CloudConvert.swift */; }; FFB1C98B2C10255100B154A7 /* TournamentBroadcastRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFB1C98A2C10255100B154A7 /* TournamentBroadcastRowView.swift */; }; @@ -1156,6 +1162,8 @@ FF967D0E2BAF63B000A9A3BD /* PlayerBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerBlockView.swift; sourceTree = ""; }; FF9AC3942BE3627B00C2E883 /* GroupStageTeamReplacementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupStageTeamReplacementView.swift; sourceTree = ""; }; FFA1B1282BB71773006CE248 /* PadelClubButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PadelClubButtonView.swift; sourceTree = ""; }; + FFA252A82CDB70520074E63F /* PlayerStatisticView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerStatisticView.swift; sourceTree = ""; }; + FFA252AC2CDB734A0074E63F /* UmpireStatisticView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UmpireStatisticView.swift; sourceTree = ""; }; FFA6D7842BB0B795003A31F3 /* FileImportManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileImportManager.swift; sourceTree = ""; }; FFA6D7862BB0B7A2003A31F3 /* CloudConvert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudConvert.swift; sourceTree = ""; }; FFA6D78A2BB0BEB3003A31F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; @@ -1491,6 +1499,7 @@ children = ( FF089EBC2BB0287D00F0AEC7 /* PlayerView.swift */, FF1162842BD00279000C4809 /* PlayerDetailView.swift */, + FFA252A82CDB70520074E63F /* PlayerStatisticView.swift */, FF089EB02BB001EA00F0AEC7 /* Components */, ); path = Player; @@ -1693,6 +1702,7 @@ isa = PBXGroup; children = ( FF3F74F52B919E45004CFE0E /* UmpireView.swift */, + FFA252AC2CDB734A0074E63F /* UmpireStatisticView.swift */, FFD783FE2B91BA42000F62A6 /* PadelClubView.swift */, ); path = Umpire; @@ -2320,6 +2330,7 @@ FF967CF22BAECC0B00A9A3BD /* TeamScore.swift in Sources */, FF1162832BCFBE4E000C4809 /* EditablePlayerView.swift in Sources */, FF1162852BD00279000C4809 /* PlayerDetailView.swift in Sources */, + FFA252AE2CDB734A0074E63F /* UmpireStatisticView.swift in Sources */, FF5D0D762BB428B2005CB568 /* ListRowViewModifier.swift in Sources */, FF6EC9002B94794700EA7F5A /* PresentationContext.swift in Sources */, FFDB1C6D2BB2A02000F1E467 /* AppSettings.swift in Sources */, @@ -2474,6 +2485,7 @@ FF8F26452BAE0A3400650388 /* TournamentDurationManagerView.swift in Sources */, FF1DC5532BAB354A00FD8220 /* MockData.swift in Sources */, FF967D092BAF3D4000A9A3BD /* TeamDetailView.swift in Sources */, + FFA252A92CDB70520074E63F /* PlayerStatisticView.swift in Sources */, FF5DA18F2BB9268800A33061 /* GroupStagesSettingsView.swift in Sources */, FF663FBE2BE019EC0031AE83 /* TournamentFilterView.swift in Sources */, FF67615D2CC8ED6900CC9BF2 /* PreviewBracketPositionView.swift in Sources */, @@ -2600,6 +2612,7 @@ FF4CBF6C2C996C0600151637 /* TeamScore.swift in Sources */, FF4CBF6D2C996C0600151637 /* EditablePlayerView.swift in Sources */, FF4CBF6E2C996C0600151637 /* PlayerDetailView.swift in Sources */, + FFA252AF2CDB734A0074E63F /* UmpireStatisticView.swift in Sources */, FF4CBF6F2C996C0600151637 /* ListRowViewModifier.swift in Sources */, FF4CBF702C996C0600151637 /* PresentationContext.swift in Sources */, FF4CBF712C996C0600151637 /* AppSettings.swift in Sources */, @@ -2754,6 +2767,7 @@ FF4CBFFF2C996C0600151637 /* TournamentDurationManagerView.swift in Sources */, FF4CC0002C996C0600151637 /* MockData.swift in Sources */, FF4CC0012C996C0600151637 /* TeamDetailView.swift in Sources */, + FFA252AA2CDB70520074E63F /* PlayerStatisticView.swift in Sources */, FF4CC0022C996C0600151637 /* GroupStagesSettingsView.swift in Sources */, FF4CC0032C996C0600151637 /* TournamentFilterView.swift in Sources */, FF67615C2CC8ED6900CC9BF2 /* PreviewBracketPositionView.swift in Sources */, @@ -2859,6 +2873,7 @@ FF70FAEB2C90584900129CC2 /* TeamScore.swift in Sources */, FF70FAEC2C90584900129CC2 /* EditablePlayerView.swift in Sources */, FF70FAED2C90584900129CC2 /* PlayerDetailView.swift in Sources */, + FFA252AD2CDB734A0074E63F /* UmpireStatisticView.swift in Sources */, FF70FAEE2C90584900129CC2 /* ListRowViewModifier.swift in Sources */, FF70FAEF2C90584900129CC2 /* PresentationContext.swift in Sources */, FF70FAF02C90584900129CC2 /* AppSettings.swift in Sources */, @@ -3013,6 +3028,7 @@ FF70FB7E2C90584900129CC2 /* TournamentDurationManagerView.swift in Sources */, FF70FB7F2C90584900129CC2 /* MockData.swift in Sources */, FF70FB802C90584900129CC2 /* TeamDetailView.swift in Sources */, + FFA252AB2CDB70520074E63F /* PlayerStatisticView.swift in Sources */, FF70FB812C90584900129CC2 /* GroupStagesSettingsView.swift in Sources */, FF70FB822C90584900129CC2 /* TournamentFilterView.swift in Sources */, FF67615B2CC8ED6900CC9BF2 /* PreviewBracketPositionView.swift in Sources */, diff --git a/PadelClub/Views/Navigation/Umpire/UmpireStatisticView.swift b/PadelClub/Views/Navigation/Umpire/UmpireStatisticView.swift index dcea4eb..cf1aea4 100644 --- a/PadelClub/Views/Navigation/Umpire/UmpireStatisticView.swift +++ b/PadelClub/Views/Navigation/Umpire/UmpireStatisticView.swift @@ -6,13 +6,79 @@ // import SwiftUI +import LeStorage struct UmpireStatisticView: View { + @EnvironmentObject var dataStore: DataStore + + let walkoutTeams: [TeamRegistration] + let players: [PlayerRegistration] + let countedPlayers: [String: Int] + let countedWalkoutPlayers: [String: Int] + + init() { + let teams = DataStore.shared.tournaments.flatMap({ $0.unsortedTeams() }) + let wos = teams.filter({ $0.walkOut }) + self.walkoutTeams = wos + + var uniquePlayersDict = [String: PlayerRegistration]() + var playerCountDict = [String: Int]() + var playerWalkOutCountDict = [String: Int]() + + for team in teams { + for player in team.unsortedPlayers() { + if let licenceId = player.licenceId?.strippedLicense { + if team.walkOut { + uniquePlayersDict[licenceId] = player + playerWalkOutCountDict[licenceId, default: 0] += 1 + } + playerCountDict[licenceId, default: 0] += 1 + } + } + } + + self.players = Array(uniquePlayersDict.values).sorted(by: { a, b in + playerCountDict[a.licenceId!.strippedLicense!]! > playerCountDict[b.licenceId!.strippedLicense!]! + }) + self.countedPlayers = playerCountDict + self.countedWalkoutPlayers = playerWalkOutCountDict + } + var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + List { + Section { + LabeledContent { + Text(dataStore.tournaments.count.formatted()) + } label: { + Text("Tournois") + } + + LabeledContent { + Text(walkoutTeams.count.formatted()) + } label: { + Text("Équipes forfaites") + } + } + + if players.isEmpty == false { + Section { + ForEach(players) { player in + LabeledContent { + if let licenceId = player.licenceId?.strippedLicense, let count = countedPlayers[licenceId], let walkoutCount = countedWalkoutPlayers[licenceId] { + Text(walkoutCount.formatted() + " / " + count.formatted()) + .font(.title3) + } + } label: { + Text(player.playerLabel()) + } + } + } header: { + Text("Nombre de forfaits / participations") + } + } + } + .navigationTitle("Statistiques") + .navigationBarTitleDisplayMode(.inline) + .toolbarBackground(.visible, for: .navigationBar) } } - -#Preview { - UmpireStatisticView() -} diff --git a/PadelClub/Views/Navigation/Umpire/UmpireView.swift b/PadelClub/Views/Navigation/Umpire/UmpireView.swift index 347c4ba..7fb1421 100644 --- a/PadelClub/Views/Navigation/Umpire/UmpireView.swift +++ b/PadelClub/Views/Navigation/Umpire/UmpireView.swift @@ -121,6 +121,14 @@ struct UmpireView: View { Text("Il s'agit des clubs qui sont utilisés pour récupérer les tournois tenup.") } + Section { + NavigationLink { + UmpireStatisticView() + } label: { + Text("Statistiques de participations") + } + } + Section { @Bindable var user = dataStore.user diff --git a/PadelClub/Views/Player/PlayerDetailView.swift b/PadelClub/Views/Player/PlayerDetailView.swift index 45cb3e7..69c153a 100644 --- a/PadelClub/Views/Player/PlayerDetailView.swift +++ b/PadelClub/Views/Player/PlayerDetailView.swift @@ -34,7 +34,7 @@ struct PlayerDetailView: View { Form { Section { Toggle("Joueur sur place", isOn: $player.hasArrived) - + LabeledContent { TextField("Nom", text: $player.lastName) .keyboardType(.alphabet) @@ -47,7 +47,7 @@ struct PlayerDetailView: View { } label: { Text("Nom") } - + LabeledContent { TextField("Prénom", text: $player.firstName) .keyboardType(.alphabet) @@ -60,7 +60,7 @@ struct PlayerDetailView: View { } label: { Text("Prénom") } - + PlayerSexPickerView(player: player) if let birthdate = player.birthdate { @@ -109,7 +109,7 @@ struct PlayerDetailView: View { Text("Calculé en fonction du sexe") } } - + Section { LabeledContent { TextField("Licence", text: $licenceId) @@ -160,7 +160,7 @@ struct PlayerDetailView: View { Text("Téléphone") } } - + LabeledContent { TextField("Email", text: $email) .focused($focusedField, equals: ._email) @@ -207,6 +207,14 @@ struct PlayerDetailView: View { } } } + + Section { + NavigationLink { + PlayerStatisticView(player: player) + } label: { + Text("Statistiques de participations") + } + } } .toolbar { ToolbarItem(placement: .topBarTrailing) { diff --git a/PadelClub/Views/Player/PlayerStatisticView.swift b/PadelClub/Views/Player/PlayerStatisticView.swift index e396964..08fa3c4 100644 --- a/PadelClub/Views/Player/PlayerStatisticView.swift +++ b/PadelClub/Views/Player/PlayerStatisticView.swift @@ -6,13 +6,38 @@ // import SwiftUI +import LeStorage struct PlayerStatisticView: View { + let player: PlayerRegistration + + let teams: [TeamRegistration] + + init(player: PlayerRegistration) { + self.player = player + self.teams = DataStore.shared.tournaments.flatMap({ $0.unsortedTeams() }).filter({ $0.includes(player: player) + }) + } + + var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + List { + Section { + LabeledContent { + Text(teams.count.formatted()) + } label: { + Text("Participations") + } + LabeledContent { + Text(teams.filter({ $0.walkOut }).count.formatted()) + } label: { + Text("Forfaits") + } + } + } + .headerProminence(.increased) + .navigationTitle("Statistiques") + .navigationBarTitleDisplayMode(.inline) + .toolbarBackground(.visible, for: .navigationBar) } } - -#Preview { - PlayerStatisticView() -}