diff --git a/PadelClub/Data/GroupStage.swift b/PadelClub/Data/GroupStage.swift index ccb0baf..d23ab3d 100644 --- a/PadelClub/Data/GroupStage.swift +++ b/PadelClub/Data/GroupStage.swift @@ -94,6 +94,23 @@ class GroupStage: ModelObject, Storable { } } + func updateGroupStageState() { + if hasEnded(), let tournament = tournamentObject() { + do { + let teams = teams(true) + for (index, team) in teams { + team.qualified = index < tournament.qualifiedPerGroupStage + if team.bracketPosition != nil && team.qualified == false { + team.bracketPosition = nil + } + } + try DataStore.shared.teamRegistrations.addOrUpdate(contentOfs: teams) + } catch { + Logger.error(error) + } + } + } + func scoreLabel(forGroupStagePosition groupStagePosition: Int) -> (wins: String, losses: String, setsDifference: String?, gamesDifference: String?)? { if let scoreData = _score(forGroupStagePosition: groupStagePosition, nilIfEmpty: true) { let hideSetDifference = matchFormat.setsToWin == 1 diff --git a/PadelClub/Data/Match.swift b/PadelClub/Data/Match.swift index cf19e34..4496dfc 100644 --- a/PadelClub/Data/Match.swift +++ b/PadelClub/Data/Match.swift @@ -348,10 +348,7 @@ class Match: ModelObject, Storable { winningTeamId = teamScoreWinning.teamRegistration losingTeamId = teamScoreWalkout.teamRegistration - - // matchDescriptor.match?.tournament?.generateLoserBracket(for: matchDescriptor.match!.round, viewContext: viewContext, reset: false) - // matchDescriptor.match?.loserBracket?.generateLoserBracket(for: matchDescriptor.match!.round, viewContext: viewContext, reset: false) - // matchDescriptor.match?.currentTournament?.removeField(matchDescriptor.match?.fieldIndex) + groupStageObject?.updateGroupStageState() } func setScore(fromMatchDescriptor matchDescriptor: MatchDescriptor) { @@ -359,11 +356,9 @@ class Match: ModelObject, Storable { if endDate == nil { endDate = Date() } - // matchDescriptor.match?.tournament?.generateLoserBracket(for: matchDescriptor.match!.round, viewContext: viewContext, reset: false) - // matchDescriptor.match?.loserBracket?.generateLoserBracket(for: matchDescriptor.match!.round, viewContext: viewContext, reset: false) - // matchDescriptor.match?.currentTournament?.removeField(matchDescriptor.match?.fieldIndex) winningTeamId = team(matchDescriptor.winner)?.id losingTeamId = team(matchDescriptor.winner.otherTeam)?.id + groupStageObject?.updateGroupStageState() } func updateScore(fromMatchDescriptor matchDescriptor: MatchDescriptor) { diff --git a/PadelClub/Views/Components/GenericDestinationPickerView.swift b/PadelClub/Views/Components/GenericDestinationPickerView.swift index cdae4b9..1db550d 100644 --- a/PadelClub/Views/Components/GenericDestinationPickerView.swift +++ b/PadelClub/Views/Components/GenericDestinationPickerView.swift @@ -21,8 +21,8 @@ struct GenericDestinationPickerView: View { selectedDestination = nil } label: { Image(systemName: "wrench.and.screwdriver") + .foregroundColor(selectedDestination == nil ? .white : .black) } - .foregroundStyle(selectedDestination == nil ? .primary : .secondary) .padding() .background { Circle() diff --git a/PadelClub/Views/Components/MatchListView.swift b/PadelClub/Views/Components/MatchListView.swift index e54e5af..c1785f5 100644 --- a/PadelClub/Views/Components/MatchListView.swift +++ b/PadelClub/Views/Components/MatchListView.swift @@ -13,7 +13,7 @@ struct MatchListView: View { let matches: [Match] var matchViewStyle: MatchViewStyle = .sectionedStandardStyle - @State private var isExpanded: Bool = true + @State var isExpanded: Bool = true @ViewBuilder var body: some View { diff --git a/PadelClub/Views/GroupStage/GroupStageSettingsView.swift b/PadelClub/Views/GroupStage/GroupStageSettingsView.swift index c42cb38..5f3cbb5 100644 --- a/PadelClub/Views/GroupStage/GroupStageSettingsView.swift +++ b/PadelClub/Views/GroupStage/GroupStageSettingsView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import LeStorage struct GroupStageSettingsView: View { @EnvironmentObject var dataStore: DataStore @@ -25,17 +26,16 @@ struct GroupStageSettingsView: View { var body: some View { List { - Toggle(isOn: $nameAlphabetical) { - Text("Nommer les poules alphabétiquement") - } - Menu { - //menuAddGroupStage + Section { menuBuildAllGroupStages + } + + Section { menuGenerateGroupStage(.random) + } + + Section { menuGenerateGroupStage(.snake) - //menuGenerateGroupStage(.swiss) - } label: { - LabelOptions() } if tournament.missingQualifiedFromGroupStages().isEmpty == false && tournament.qualifiedTeams().count >= tournament.qualifiedFromGroupStage() && tournament.groupStageAdditionalQualified > 0 { @@ -52,115 +52,9 @@ struct GroupStageSettingsView: View { } } -// if (tournament.groupStagesAreWrong || (tournament.emptySlotInGroupStages > 0 && tournament.entriesCount >= tournament.teamsFromGroupStages)) { -// Section { -// RowButtonView("Reconstruire les poules") { -// confirmGroupStageRebuild = true -// } -// .modify { -// if UIDevice.current.userInterfaceIdiom == .pad { -// $0.alert("Êtes-vous sûr ?", isPresented: $confirmGroupStageRebuild) { -// -// Button(role: .destructive) { -// tournament.refreshGroupStages() -// save() -// } label: { -// Text("Reconstruire") -// } -// -// -// Button(role: .cancel) { -// -// } label: { -// Text("Annuler") -// } -// } message: { -// Text("Attention, cela peut modifier les poules existants.") -// -// } -// } else { -// $0.confirmationDialog("Êtes-vous sûr ?", isPresented: $confirmGroupStageRebuild) { -// Button(role: .destructive) { -// tournament.refreshGroupStages() -// save() -// } label: { -// Text("Reconstruire") -// } -// } message: { -// Text("Attention, cela peut modifier les poules existants.") -// } -// } -// } -// } header: { -// Text("Erreur détectée") -// } -// } -// - -// if tournament.isRoundSwissTournament() == false && (tournament.orderedGroupStages.allSatisfy({ $0.orderedMatches.count > 0 }) == false && tournament.groupStagesAreOver == false && tournament.groupStagesCount > 0) { -// Section { -// RowButtonView("Générer les matchs de poules") { -// startAllGroupStageConfirmation = true -// } -// .modify { -// if UIDevice.current.userInterfaceIdiom == .pad { -// $0.alert("Êtes-vous sûr ?", isPresented: $startAllGroupStageConfirmation) { -// Button("Générer") { -// tournament.orderedGroupStages.forEach { -// if $0.orderedMatches.isEmpty { -// $0.startGroupStage() -// } -// } -// save() -// } -// Button(role: .cancel) { -// -// } label: { -// Text("Annuler") -// } -// } -// -// } else { -// $0.confirmationDialog("Êtes-vous sûr ?", isPresented: $startAllGroupStageConfirmation) { -// Button("Générer") { -// tournament.orderedGroupStages.forEach { -// if $0.orderedMatches.isEmpty { -// $0.startGroupStage() -// } -// } -// save() -// } -// } -// } -// } -// } -// } -// - if tournament.groupStagesAreOver() == false { -// Section { -// GroupStageMatchAvailableToStartView(tournament: tournament, groupStageIndex: selectedGroupStageIndex) -// } header: { -// if selectedGroupStageIndex == -1 { -// Text("Matchs de poules prêt à démarrer") -// } else { -// Text("Matchs de la poule \(selectedGroupStageIndex) prêt à démarrer") -// } -// } footer: { -// Text("présence d'au moins 2 équipes d'une même poule ayant réglé.") -// } + Toggle(isOn: $nameAlphabetical) { + Text("Nommer les poules alphabétiquement") } - -// if tournament.teamsPerGroupStage == 3 && tournament.qualifiedPerGroupStage == 1 && tournament.numberOfGroupStages%2 == 0 && tournament.moreQualifiedFromGroupStages == 0 { -// Section { -// NavigationLink { -// GroupStageMissingMatchView(tournament: tournament) -// } label: { -// Text("Matchs de classement de poules") -// } -// } -// } - - } .onChange(of: nameAlphabetical) { let groupStages = tournament.groupStages() @@ -178,71 +72,30 @@ struct GroupStageSettingsView: View { } - var menuBuildAllGroupStages: some View { - Button(role: .destructive) { - tournament.deleteGroupStages() - tournament.buildGroupStages() - } label: { - Label("Refaire les poules", systemImage: "restart") - } + var menuBuildAllGroupStages: some View { + RowButtonView("Refaire les poules", role: .destructive) { + tournament.deleteGroupStages() + tournament.buildGroupStages() + _save() } - - @ViewBuilder - func menuGenerateGroupStage(_ mode: GroupStageOrderingMode) -> some View { - Button(role: .destructive) { - tournament.groupStageOrderingMode = mode - tournament.refreshGroupStages() - //save() - } label: { - Label("Poule \(mode.localizedLabel().lowercased())", systemImage: mode.systemImage) - } + } + + @ViewBuilder + func menuGenerateGroupStage(_ mode: GroupStageOrderingMode) -> some View { + RowButtonView("Poule \(mode.localizedLabel().lowercased())", role: .destructive, systemImage: mode.systemImage) { + tournament.groupStageOrderingMode = mode + tournament.refreshGroupStages() + _save() } + } -// func addGroupStage(_ size: Int64) { -// let groupStage = GroupStage(context: viewContext) -// groupStage.index = tournament.firstIndexToUseForNewGroupStage -// groupStage.size = Int64(size) -// groupStage.matchFormatRawValue = tournament.groupStageMatchFormatRawValue -// print("addGroupStage groupStagesCount", tournament.groupStagesCount) -// print("addGroupStage numberOfGroupStages", tournament.numberOfGroupStages) -// if tournament.groupStagesCount >= tournament.numberOfGroupStages { -// tournament.numberOfGroupStages += 1 -// } -// tournament.addToGroupStages(groupStage) -// save() -// } -// -// var menuAddGroupStage: some View { -// Menu { -// ForEach(-1...1) { index in -// let i = tournament.teamsPerGroupStage + Int64(index) -// Button { -// addGroupStage(i) -// } label: { -// Text("Poule de \(i)") -// } -// .disabled(i < 2) -// } -// } label: { -// Label("Ajouter une poule", systemImage: "server.rack") -// } -// -// } - - -// func save() { -// do { -// tournament.objectWillChange.send() -// try viewContext.save() -// viewContext.refreshAllObjects() -// } catch { -// // Replace this implementation with code to handle the error appropriately. -// // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. -// let nsError = error as NSError -// fatalError("Unresolved error \(nsError), \(nsError.userInfo)") -// } -// } - + private func _save() { + do { + try dataStore.tournaments.addOrUpdate(instance: tournament) + } catch { + Logger.error(error) + } + } } #Preview { diff --git a/PadelClub/Views/GroupStage/GroupStageTeamView.swift b/PadelClub/Views/GroupStage/GroupStageTeamView.swift index 5dec47f..7653ef3 100644 --- a/PadelClub/Views/GroupStage/GroupStageTeamView.swift +++ b/PadelClub/Views/GroupStage/GroupStageTeamView.swift @@ -15,21 +15,9 @@ struct GroupStageTeamView: View { var body: some View { List { - ForEach(team.players()) { player in - Section { - ImportedPlayerView(player: player) - } footer: { - HStack { - Button("contacter") { - } - Spacer() - Button { - player.hasArrived.toggle() - try? dataStore.playerRegistrations.addOrUpdate(instance: player) - } label: { - Label("présent", systemImage: player.hasArrived ? "checkmark.circle" : "circle") - } - } + Section { + ForEach(team.players()) { player in + EditablePlayerView(player: player, editingOptions: [.licenceId, .payment]) } } @@ -38,7 +26,7 @@ struct GroupStageTeamView: View { if team.qualified == false { RowButtonView("Qualifier l'équipe") { team.qualified = true - team.bracketPosition = nil +// team.bracketPosition = nil _save() } } @@ -54,41 +42,13 @@ struct GroupStageTeamView: View { } Section { - // if let deltaLabel = bracket.tournament?.deltaLabel(index, bracketIndex: bracket.index.intValue) { - // Section { - // Button(role: .destructive) { - // entrant.resetBracketPosition() - // save() - // } label: { - // Text(deltaLabel) - // } - // Divider() - // } header: { - // Text("Toute l'équipe, poids: " + entrant.updatedRank.formatted()) - // } - // } - // - // ForEach(entrant.orderedPlayers) { player in - // if let deltaLabel = bracket.tournament?.playerDeltaLabel(rank: entrant.otherPlayer(player)?.currentRank, positionInBracket: index, bracketIndex: bracket.index.intValue) { - // Section { - // Button(role: .destructive) { - // entrant.team?.removeFromPlayers(player) - // save() - // } label: { - // Text(deltaLabel) - // } - // Divider() - // } header: { - // Text(player.longLabel + ", rang: " + player.formattedRank) - // } - // } - // } - } header: { - Text("Remplacement") + RowButtonView("Remplacement") { + + } } Section { - RowButtonView("Retirer de la poule") { + RowButtonView("Retirer de la poule", role: .destructive) { team.groupStagePosition = nil team.groupStage = nil _save() diff --git a/PadelClub/Views/GroupStage/GroupStageView.swift b/PadelClub/Views/GroupStage/GroupStageView.swift index 2e6524f..ab74b59 100644 --- a/PadelClub/Views/GroupStage/GroupStageView.swift +++ b/PadelClub/Views/GroupStage/GroupStageView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import LeStorage struct GroupStageView: View { @EnvironmentObject var dataStore: DataStore @@ -15,21 +16,7 @@ struct GroupStageView: View { @State private var confirmRemoveAll: Bool = false @State private var confirmResetMatch: Bool = false @State private var groupStageName: String = "" - - private enum GroupStageSortingMode { - case auto - case score - case weight - } - - var sortByScore: Bool { - sortingMode == .auto ? groupStage.hasEnded() : sortingMode == .score - } - - func teamAt(atIndex index: Int) -> TeamRegistration? { - sortByScore ? groupStage.teams(sortByScore)[safe: index] : groupStage.teamAt(groupStagePosition: index) - } - + init(groupStage: GroupStage) { self.groupStage = groupStage _groupStageName = State(wrappedValue: groupStage.groupStageTitle()) @@ -38,7 +25,7 @@ struct GroupStageView: View { var body: some View { List { Section { - _groupStageView() + GroupStageScoreView(groupStage: groupStage, sortByScore: _sortByScore) } header: { if let startDate = groupStage.startDate { Text(startDate.formatted(Date.FormatStyle().weekday(.wide)).capitalized + " à partir de " + startDate.formattedAsHourMinute()) @@ -47,19 +34,9 @@ struct GroupStageView: View { HStack { Spacer() Button { - if sortingMode == .auto { - if groupStage.hasEnded() { - sortingMode = .weight - } else { - sortingMode = .score - } - } else if sortingMode == .weight { - sortingMode = .score - } else { - sortingMode = .weight - } + _updateSortingMode() } label: { - Label(sortByScore ? "tri par score" : "tri par poids", systemImage: "arrow.up.arrow.down").labelStyle(.titleOnly) + Label(_sortByScore ? "tri par score" : "tri par poids", systemImage: "arrow.up.arrow.down").labelStyle(.titleOnly) .underline() } .buttonStyle(.borderless) @@ -70,11 +47,11 @@ struct GroupStageView: View { MatchListView(section: "disponible", matches: groupStage.availableToStart()).id(UUID()) MatchListView(section: "en cours", matches: groupStage.runningMatches()).id(UUID()) MatchListView(section: "à lancer", matches: groupStage.readyMatches()).id(UUID()) - MatchListView(section: "terminés", matches: groupStage.finishedMatches()).id(UUID()) + MatchListView(section: "terminés", matches: groupStage.finishedMatches(), isExpanded: false).id(UUID()) } .onChange(of: groupStageName) { groupStage.name = groupStageName - try? dataStore.groupStages.addOrUpdate(instance: groupStage) + _save() } .toolbar { ToolbarItem(placement: .topBarTrailing) { @@ -84,65 +61,111 @@ struct GroupStageView: View { .navigationTitle($groupStageName) } - private func _groupStageView() -> some View { - ForEach(0..<(groupStage.size), id: \.self) { index in - if let team = teamAt(atIndex: index), let groupStagePosition = team.groupStagePosition { - NavigationLink { - GroupStageTeamView(groupStage: groupStage, team: team) - } label: { - HStack(alignment: .center) { + private enum GroupStageSortingMode { + case auto + case score + case weight + } + + private var _sortByScore: Bool { + sortingMode == .auto ? groupStage.hasEnded() : sortingMode == .score + } + + private func _updateSortingMode() { + if sortingMode == .auto { + if groupStage.hasEnded() { + sortingMode = .weight + } else { + sortingMode = .score + } + } else if sortingMode == .weight { + sortingMode = .score + } else { + sortingMode = .weight + } + } + + struct GroupStageScoreView: View { + @EnvironmentObject var dataStore: DataStore + let groupStage: GroupStage + let sortByScore: Bool + let teams: [TeamRegistration] + + init(groupStage: GroupStage, sortByScore: Bool) { + self.groupStage = groupStage + self.sortByScore = sortByScore + self.teams = groupStage.teams(sortByScore) + } + + private func _teamAt(atIndex index: Int) -> TeamRegistration? { + sortByScore ? teams[safe: index] : groupStage.teamAt(groupStagePosition: index) + } + + var body: some View { + ForEach(0..<(groupStage.size), id: \.self) { index in + if let team = _teamAt(atIndex: index), let groupStagePosition = team.groupStagePosition { + NavigationLink { + GroupStageTeamView(groupStage: groupStage, team: team) + } label: { VStack(alignment: .leading, spacing: 4.0) { HStack(spacing: 6.0) { Text("#\(groupStagePosition + 1)") Text("Poids \(team.weight)") + Spacer() + if team.qualified { + Text("qualifié") + } } .font(.footnote) HStack { if let teamName = team.name { - Text(teamName) + Text(teamName).font(.title) } else { VStack(alignment: .leading) { ForEach(team.players()) { player in - Text(player.playerLabel()) + Text(player.playerLabel()).lineLimit(1) } } } - - if team.qualified { - Image(systemName: "checkmark.seal") - } - } - } - Spacer() - if let score = groupStage.scoreLabel(forGroupStagePosition: groupStagePosition) { - VStack(alignment: .center) { - HStack(spacing: 0.0) { - Text(score.wins) - Text("/") - Text(score.losses) - }.bold() - if let setsDifference = score.setsDifference { - Text(setsDifference + " sets") - } - if let gamesDifference = score.gamesDifference { - Text(gamesDifference + " jeux") + Spacer() + if let score = groupStage.scoreLabel(forGroupStagePosition: groupStagePosition) { + VStack(alignment: .trailing) { + HStack(spacing: 0.0) { + Text(score.wins) + Text("/") + Text(score.losses) + }.font(.headline).monospacedDigit() + if let setsDifference = score.setsDifference { + HStack(spacing: 4.0) { + Text(setsDifference) + Text("sets") + }.font(.footnote) + } + if let gamesDifference = score.gamesDifference { + HStack(spacing: 4.0) { + Text(gamesDifference) + Text("jeux") + }.font(.footnote) + } + } } } } } - } - } else { - HStack(alignment: .center) { + .listRowView(isActive: team.qualified, color: .master) + } else { VStack(alignment: .leading, spacing: 0) { - HStack { - Text("#\(index + 1)") - } - .font(.caption) + Text("#\(index + 1)") + .font(.caption) TeamPickerView(teamPicked: { team in print(team.pasteData()) team.groupStage = groupStage.id team.groupStagePosition = index - try? dataStore.teamRegistrations.addOrUpdate(instance: team) + do { + try dataStore.teamRegistrations.addOrUpdate(instance: team) + } catch { + Logger.error(error) + } }) } } @@ -156,121 +179,15 @@ struct GroupStageView: View { Button("Retirer le nom") { groupStage.name = nil groupStageName = groupStage.groupStageTitle() - try? dataStore.groupStages.addOrUpdate(instance: groupStage) + _save() } } - -// if groupStage.playedMatches().isEmpty { -// Button { -// //groupStage.startGroupStage() -// //save() -// } label: { -// Text("Créer les matchs") -// } -// .buttonStyle(.borderless) -// } - Button("Retirer tout le monde", role: .destructive) { confirmRemoveAll = true } Button("Recommencer tous les matchs", role: .destructive) { confirmResetMatch = true } - - // Button { - // selectedMenuLink = .prepare - // } label: { - // Label("Préparer", systemImage: "calendar") - // } - // - // Menu { - // MenuWarnView(warningSender: groupStage) - // } label: { - // Label("Prévenir", systemImage: "person.crop.circle") - // } - // - // if groupStage.isBroadcasted() { - // Button { - // groupStage.refreshBroadcast() - // } label: { - // Label("Rafraîchir", systemImage: "arrow.up.circle.fill") - // } - // Button { - // groupStage.stopBroadcast() - // save() - // } label: { - // Label("Arrêter la diffusion", systemImage: "stop.circle.fill") - // } - // } else if groupStage.tournament?.canBroadcast() == true { - // Button { - // Task { - // try? await groupStage.broadcastGroupStage() - // save() - // } - // } label: { - // Label("Diffuser", systemImage: "airplayvideo") - // } - // } - // - // Divider() - // if groupStage.tournament?.canBroadcast() == true { - // Menu { - // Button { - // Task { - // try? await groupStage.broadcastGroupStageMatches() - // save() - // } - // } label: { - // Label("Diffuser", systemImage: "airplayvideo") - // } - // - // Button { - // groupStage.refreshBroadcastMatches() - // } label: { - // Label("Rafraîchir", systemImage: "arrow.up.circle.fill") - // } - // Button { - // groupStage.stopBroadcastMatches() - // save() - // } label: { - // Label("Arrêter la diffusion", systemImage: "stop.circle.fill") - // } - // } label: { - // Text("Diffusion des matchs") - // } - // } - // - // Divider() - // Menu { - // if groupStage.orderedMatches.isEmpty == false { - // Button(role: .destructive) { - // groupStage.startGroupStage() - // save() - // } label: { - // Label("Re-démarrer les matchs de la \(groupStage.titleLabel.lowercased())", systemImage: "trash") - // } - // } - // - // if groupStage.orderedMatches.isEmpty == false { - // Button(role: .destructive) { - // groupStage.removeMatches() - // save() - // } label: { - // Label("Supprimer les matchs de la \(groupStage.titleLabel.lowercased())", systemImage: "trash") - // } - // } - // - // Button(role: .destructive) { - // groupStage.tournament?.completeEntries.filter { $0.groupStagePosition == groupStage.index }.forEach { $0.resetGroupStagePosition() } - // groupStage.tournament?.removeFromGroupStages(groupStage) - // groupStage.tournament?.numberOfGroupStages -= 1 - // save() - // } label: { - // Label("Supprimer la \(groupStage.titleLabel.lowercased())", systemImage: "trash") - // } - // } label: { - // Text("Éditer") - // } } label: { LabelOptions() } @@ -281,7 +198,11 @@ struct GroupStageView: View { team.groupStagePosition = nil team.groupStage = nil } - try? dataStore.teamRegistrations.addOrUpdate(contentOfs: teams) + do { + try dataStore.teamRegistrations.addOrUpdate(contentOfs: teams) + } catch { + Logger.error(error) + } } } .confirmationDialog("Êtes-vous sûr de vouloir faire cela ?", isPresented: $confirmResetMatch, titleVisibility: .visible) { @@ -292,18 +213,11 @@ struct GroupStageView: View { } -// func save() { -// do { -// groupStage.objectWillChange.send() -// groupStage.tournament?.orderedGroupStages.forEach { $0.objectWillChange.send() } -// groupStage.tournament?.objectWillChange.send() -// -// try viewContext.save() -// } catch { -// // Replace this implementation with code to handle the error appropriately. -// // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. -// let nsError = error as NSError -// fatalError("Unresolved error \(nsError), \(nsError.userInfo)") -// } -// } + private func _save() { + do { + try dataStore.groupStages.addOrUpdate(instance: groupStage) + } catch { + Logger.error(error) + } + } } diff --git a/PadelClub/Views/GroupStage/GroupStagesView.swift b/PadelClub/Views/GroupStage/GroupStagesView.swift index f98d4b1..3628cb4 100644 --- a/PadelClub/Views/GroupStage/GroupStagesView.swift +++ b/PadelClub/Views/GroupStage/GroupStagesView.swift @@ -73,10 +73,10 @@ struct GroupStagesView: View { let runningMatches = allGroupStages.flatMap({ $0.runningMatches() }) let readyMatches = allGroupStages.flatMap({ $0.readyMatches() }) let finishedMatches = allGroupStages.flatMap({ $0.finishedMatches() }) - MatchListView(section: "disponible", matches: availableToStart, matchViewStyle: .standardStyle) - MatchListView(section: "en cours", matches: runningMatches, matchViewStyle: .standardStyle) - MatchListView(section: "à lancer", matches: readyMatches, matchViewStyle: .standardStyle) - MatchListView(section: "terminés", matches: finishedMatches, matchViewStyle: .standardStyle) + MatchListView(section: "disponible", matches: availableToStart, matchViewStyle: .standardStyle, isExpanded: false) + MatchListView(section: "en cours", matches: runningMatches, matchViewStyle: .standardStyle, isExpanded: false) + MatchListView(section: "à lancer", matches: readyMatches, matchViewStyle: .standardStyle, isExpanded: false) + MatchListView(section: "terminés", matches: finishedMatches, matchViewStyle: .standardStyle, isExpanded: false) } .navigationTitle("Toutes les poules") case .groupStage(let groupStage): diff --git a/PadelClub/Views/Player/Components/EditablePlayerView.swift b/PadelClub/Views/Player/Components/EditablePlayerView.swift index b75a617..788cc60 100644 --- a/PadelClub/Views/Player/Components/EditablePlayerView.swift +++ b/PadelClub/Views/Player/Components/EditablePlayerView.swift @@ -74,6 +74,13 @@ struct EditablePlayerView: View { } Section { + Button { + player.hasArrived.toggle() + try? dataStore.playerRegistrations.addOrUpdate(instance: player) + } label: { + Label("présent", systemImage: player.hasArrived ? "checkmark.circle" : "circle") + } + Button { editedLicenceId = player.licenceId ?? "" shouldPresentLicenceIdEdition = true diff --git a/PadelClub/Views/Score/EditScoreView.swift b/PadelClub/Views/Score/EditScoreView.swift index a1bba95..58d93a7 100644 --- a/PadelClub/Views/Score/EditScoreView.swift +++ b/PadelClub/Views/Score/EditScoreView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import LeStorage struct EditScoreView: View { @EnvironmentObject var dataStore: DataStore @@ -102,7 +103,11 @@ struct EditScoreView: View { func save() { if let match = matchDescriptor.match { - try? dataStore.matches.addOrUpdate(instance: match) + do { + try dataStore.matches.addOrUpdate(instance: match) + } catch { + Logger.error(error) + } } } } diff --git a/PadelClub/Views/Tournament/TournamentRunningView.swift b/PadelClub/Views/Tournament/TournamentRunningView.swift index 7ec5e46..95e360f 100644 --- a/PadelClub/Views/Tournament/TournamentRunningView.swift +++ b/PadelClub/Views/Tournament/TournamentRunningView.swift @@ -75,7 +75,7 @@ struct TournamentRunningView: View { MatchListView(section: "en cours", matches: tournament.runningMatches(allMatches)) // MatchListView(section: "à lancer", matches: tournament.readyMatches(allMatches)) // MatchListView(section: "disponible", matches: tournament.availableToStart(allMatches)) - MatchListView(section: "terminés", matches: tournament.finishedMatches(allMatches)) + MatchListView(section: "terminés", matches: tournament.finishedMatches(allMatches), isExpanded: false) } } diff --git a/PadelClub/Views/Tournament/TournamentView.swift b/PadelClub/Views/Tournament/TournamentView.swift index 7cc9690..e13f048 100644 --- a/PadelClub/Views/Tournament/TournamentView.swift +++ b/PadelClub/Views/Tournament/TournamentView.swift @@ -45,7 +45,7 @@ struct TournamentView: View { } } } footer: { - if tournament.inscriptionClosed() == false && tournament.state() == .build && tournament.unsortedTeams().isEmpty == false { + if tournament.inscriptionClosed() == false && tournament.state() == .build && tournament.unsortedTeams().isEmpty == false && tournament.hasStarted() == false { Button { tournament.lockRegistration() _save() diff --git a/PadelClub/Views/ViewModifiers/ListRowViewModifier.swift b/PadelClub/Views/ViewModifiers/ListRowViewModifier.swift index 6c21d80..ac26e22 100644 --- a/PadelClub/Views/ViewModifiers/ListRowViewModifier.swift +++ b/PadelClub/Views/ViewModifiers/ListRowViewModifier.swift @@ -8,11 +8,11 @@ import SwiftUI struct ListRowViewModifier: ViewModifier { - @State private var isActived = true + let isActive: Bool let color: Color func body(content: Content) -> some View { - if isActived { + if isActive { content .listRowBackground( color.variation() @@ -27,7 +27,7 @@ struct ListRowViewModifier: ViewModifier { } extension View { - func listRowView(color: Color) -> some View { - modifier(ListRowViewModifier(color: color)) + func listRowView(isActive: Bool = true, color: Color) -> some View { + modifier(ListRowViewModifier(isActive: isActive, color: color)) } }