From a128634ac57e718dc5d76f394f38a2b839f4c3fb Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Thu, 23 May 2024 00:12:15 +0200 Subject: [PATCH] fix more stuff again --- PadelClub/Data/GroupStage.swift | 6 +- PadelClub/Data/Round.swift | 8 +- PadelClub/Data/Tournament.swift | 12 ++ PadelClub/Views/Match/MatchSummaryView.swift | 4 +- .../Navigation/Ongoing/OngoingView.swift | 39 +++++- .../Organizer/TournamentOrganizerView.swift | 2 +- PadelClub/Views/Planning/SchedulerView.swift | 124 +++++++++++++----- .../Screen/InscriptionManagerView.swift | 23 +++- .../Shared/TournamentCellView.swift | 2 +- .../TournamentInscriptionView.swift | 2 +- 10 files changed, 175 insertions(+), 47 deletions(-) diff --git a/PadelClub/Data/GroupStage.swift b/PadelClub/Data/GroupStage.swift index 941900b..690552f 100644 --- a/PadelClub/Data/GroupStage.swift +++ b/PadelClub/Data/GroupStage.swift @@ -304,7 +304,11 @@ class GroupStage: ModelObject, Storable { playedMatches.forEach { match in match.matchFormat = matchFormat } - try? DataStore.shared.matches.addOrUpdate(contentOfs: playedMatches) + do { + try DataStore.shared.matches.addOrUpdate(contentOfs: playedMatches) + } catch { + Logger.error(error) + } } override func deleteDependencies() throws { diff --git a/PadelClub/Data/Round.swift b/PadelClub/Data/Round.swift index d95e138..1abc4aa 100644 --- a/PadelClub/Data/Round.swift +++ b/PadelClub/Data/Round.swift @@ -369,7 +369,7 @@ class Round: ModelObject, Storable { func roundTitle(_ displayStyle: DisplayStyle = .wide) -> String { if parent != nil { - return seedInterval()?.localizedLabel(displayStyle) ?? "Pas trouvé" + return seedInterval()?.localizedLabel(displayStyle) ?? "Round pas trouvé" } return RoundRule.roundName(fromRoundIndex: index, displayStyle: displayStyle) } @@ -467,7 +467,11 @@ class Round: ModelObject, Storable { playedMatches.forEach { match in match.matchFormat = updatedMatchFormat } - try? DataStore.shared.matches.addOrUpdate(contentOfs: playedMatches) + do { + try DataStore.shared.matches.addOrUpdate(contentOfs: playedMatches) + } catch { + Logger.error(error) + } } override func deleteDependencies() throws { diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 956012a..2f43caf 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -338,6 +338,14 @@ class Tournament : ModelObject, Storable { case finished } + func eventLabel() -> String { + if let event = eventObject(), let name = event.name { + return name + } else { + return "" + } + } + func publishedTeamsDate() -> Date { startDate } @@ -749,6 +757,10 @@ class Tournament : ModelObject, Storable { func unsortedTeams() -> [TeamRegistration] { Store.main.filter { $0.tournament == self.id } } + + func unsortedTeamsWithoutWO() -> [TeamRegistration] { + Store.main.filter { $0.tournament == self.id && $0.walkOut == false } + } func duplicates(in players: [PlayerRegistration]) -> [PlayerRegistration] { var duplicates = [PlayerRegistration]() diff --git a/PadelClub/Views/Match/MatchSummaryView.swift b/PadelClub/Views/Match/MatchSummaryView.swift index d796d37..0bbf819 100644 --- a/PadelClub/Views/Match/MatchSummaryView.swift +++ b/PadelClub/Views/Match/MatchSummaryView.swift @@ -29,12 +29,12 @@ struct MatchSummaryView: View { if let groupStage = match.groupStageObject { self.roundTitle = groupStage.groupStageTitle() } else if let round = match.roundObject { - self.roundTitle = round.roundTitle() + self.roundTitle = round.roundTitle(.short) } else { self.roundTitle = nil } - self.matchTitle = match.matchTitle() + self.matchTitle = match.matchTitle(.short) if let court = match.courtName(), match.hasEnded() == false { self.courtName = court diff --git a/PadelClub/Views/Navigation/Ongoing/OngoingView.swift b/PadelClub/Views/Navigation/Ongoing/OngoingView.swift index 9d7cb90..6753f1c 100644 --- a/PadelClub/Views/Navigation/Ongoing/OngoingView.swift +++ b/PadelClub/Views/Navigation/Ongoing/OngoingView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import LeStorage struct OngoingView: View { @Environment(NavigationViewModel.self) private var navigation: NavigationViewModel @@ -16,20 +17,42 @@ struct OngoingView: View { var matches: [Match] { let sorting = sortByField ? fieldSorting : defaultSorting - return dataStore.matches.filter({ $0.startDate != nil && $0.endDate == nil && $0.courtIndex != nil }).sorted(using: sorting, order: .ascending) + let now = Date() + return dataStore.matches.filter({ $0.startDate != nil && $0.startDate! < now && $0.endDate == nil && $0.courtIndex != nil }).sorted(using: sorting, order: .ascending) } var body: some View { @Bindable var navigation = navigation NavigationStack(path: $navigation.ongoingPath) { - let matches = matches + let matches = matches.filter { $0.currentTournament()?.isDeleted == false } List { ForEach(matches) { match in Section { MatchRowView(match: match, matchViewStyle: .standardStyle) } header: { if let tournament = match.currentTournament() { - Text(tournament.tournamentTitle()) + HStack { + Text(tournament.tournamentTitle()) + Spacer() + if let club = tournament.club() { + Text("@" + club.clubTitle(.short)) + } + } + } else { + Text("Pas de tournoi") + } + } footer: { + HStack { + if let tournament = match.currentTournament() { + Text(tournament.eventLabel()) + } +#if DEBUG + Spacer() + FooterButtonView("copier l'id") { + let pasteboard = UIPasteboard.general + pasteboard.string = match.id + } +#endif } } } @@ -51,6 +74,16 @@ struct OngoingView: View { } label: { } + #if DEBUG + Button("effacer les mauvais matchs") { + let bad = matches.filter({ $0.currentTournament() == nil }) + do { + try dataStore.matches.delete(contentOfs: bad) + } catch { + Logger.error(error) + } + } + #endif //todo //presentFilterView.toggle() } label: { diff --git a/PadelClub/Views/Navigation/Organizer/TournamentOrganizerView.swift b/PadelClub/Views/Navigation/Organizer/TournamentOrganizerView.swift index 72f6afe..3a6ee6f 100644 --- a/PadelClub/Views/Navigation/Organizer/TournamentOrganizerView.swift +++ b/PadelClub/Views/Navigation/Organizer/TournamentOrganizerView.swift @@ -34,7 +34,7 @@ struct TournamentOrganizerView: View { HStack { ScrollView(.horizontal) { HStack { - ForEach(dataStore.tournaments) { tournament in + ForEach(dataStore.tournaments.filter({ $0.isDeleted == false })) { tournament in TournamentButtonView(tournament: tournament) } } diff --git a/PadelClub/Views/Planning/SchedulerView.swift b/PadelClub/Views/Planning/SchedulerView.swift index 9b22844..da758fc 100644 --- a/PadelClub/Views/Planning/SchedulerView.swift +++ b/PadelClub/Views/Planning/SchedulerView.swift @@ -30,23 +30,34 @@ struct SchedulerView: View { List { switch destination { case .scheduleGroupStage: - MatchFormatPickingView(matchFormat: $tournament.groupStageMatchFormat) { - Task { - tournament.matchScheduler()?.updateSchedule(tournament: tournament) + Section { + MatchFormatPickingView(matchFormat: $tournament.groupStageMatchFormat) { + Task { + tournament.matchScheduler()?.updateSchedule(tournament: tournament) + } } - } - .onChange(of: tournament.groupStageMatchFormat) { - let groupStages = tournament.groupStages() - groupStages.forEach { groupStage in - groupStage.updateMatchFormat(tournament.groupStageMatchFormat) + .onChange(of: tournament.groupStageMatchFormat) { + let groupStages = tournament.groupStages() + groupStages.forEach { groupStage in + groupStage.updateMatchFormat(tournament.groupStageMatchFormat) + } + do { + try dataStore.tournaments.addOrUpdate(instance: tournament) + try dataStore.groupStages.addOrUpdate(contentOfs: groupStages) + } catch { + Logger.error(error) + } + } - do { - try dataStore.tournaments.addOrUpdate(instance: tournament) - try dataStore.groupStages.addOrUpdate(contentOfs: groupStages) - } catch { - Logger.error(error) + } footer: { + if tournament.groupStageMatchFormat.weight > tournament.groupStageSmartMatchFormat().weight { + Button { + tournament.groupStageMatchFormat = tournament.groupStageSmartMatchFormat() + } label: { + Text("devrait être joué au moins en " + tournament.groupStageSmartMatchFormat().format + ", ") + Text("modifier ?").underline().foregroundStyle(.master) + } + .buttonStyle(.plain) } - } ForEach(tournament.groupStages()) { @@ -63,6 +74,19 @@ struct SchedulerView: View { } .headerProminence(.increased) .monospacedDigit() + .onChange(of: tournament.groupStageMatchFormat) { + let groupStages = tournament.groupStages() + tournament.groupStages().forEach { groupStage in + groupStage.updateMatchFormat(tournament.groupStageMatchFormat) + } + + do { + try dataStore.tournaments.addOrUpdate(instance: tournament) + try dataStore.groupStages.addOrUpdate(contentOfs: groupStages) + } catch { + Logger.error(error) + } + } } @ViewBuilder @@ -92,33 +116,67 @@ struct SchedulerView: View { } } header: { Text(round.titleLabel()) + } footer: { + let federalFormat = tournament.roundSmartMatchFormat(round.index) + if round.matchFormat.weight > federalFormat.weight { + Button { + round.updateMatchFormatAndAllMatches(federalFormat) + do { + try dataStore.rounds.addOrUpdate(instance: round) + } catch { + Logger.error(error) + } + } label: { + Text("devrait être joué au moins en " + federalFormat.format + ", ") + Text("modifier ?").underline().foregroundStyle(.master) + } + .buttonStyle(.plain) + } } - Section { - NavigationLink { - LoserRoundScheduleEditorView(upperRound: round, tournament: tournament) - .environment(tournament) - } label: { - LabeledContent { - let count = round.loserRounds().filter({ $0.isDisabled() == false }).count - Text(count.formatted() + " tour" + count.pluralSuffix) + if round.index != 0 { + Section { + NavigationLink { + LoserRoundScheduleEditorView(upperRound: round, tournament: tournament) + .environment(tournament) } label: { - if let startDate = round.getLoserRoundStartDate() { - HStack { - Text(startDate.formattedAsHourMinute()).font(.title3) - if let estimatedEndDate = round.estimatedLoserRoundEndDate(tournament.additionalEstimationDuration) { - Image(systemName: "arrowshape.forward.fill") - Text(estimatedEndDate.formattedAsHourMinute()).font(.title3) + LabeledContent { + let count = round.loserRounds().filter({ $0.isDisabled() == false }).count + Text(count.formatted() + " tour" + count.pluralSuffix) + } label: { + if let startDate = round.getLoserRoundStartDate() { + HStack { + Text(startDate.formattedAsHourMinute()).font(.title3) + if let estimatedEndDate = round.estimatedLoserRoundEndDate(tournament.additionalEstimationDuration) { + Image(systemName: "arrowshape.forward.fill") + Text(estimatedEndDate.formattedAsHourMinute()).font(.title3) + } } + Text(startDate.formattedAsDate()) + } else { + Text("Aucun horaire") } - Text(startDate.formattedAsDate()) - } else { - Text("Aucun horaire") + } + } + } header: { + Text("Match de classement \(round.roundTitle(.short))") + } footer: { + if round.index == 1, let semi = round.loserRounds().first { + let federalFormat = tournament.loserBracketSmartMatchFormat(1) + if semi.matchFormat.weight > federalFormat.weight { + Button { + round.updateMatchFormatAndAllMatches(federalFormat) + do { + try dataStore.rounds.addOrUpdate(instance: round) + } catch { + Logger.error(error) + } + } label: { + Text("devrait être joué au moins en " + federalFormat.format + ", ") + Text("modifier ?").underline().foregroundStyle(.master) + } + .buttonStyle(.plain) } } } - } header: { - Text("Match de classement \(round.roundTitle(.short))") } } } diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index 0c9a994..c0ec79a 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -531,12 +531,25 @@ struct InscriptionManagerView: View { private func _informationView(count: Int) -> some View { Section { + let unsortedTeamsWithoutWO = tournament.unsortedTeamsWithoutWO() + LabeledContent { + Text(unsortedTeamsWithoutWO.count.formatted() + "/" + tournament.teamCount.formatted()) + } label: { + Text("Paires inscrites") + } + + LabeledContent { + Text(max(0, unsortedTeamsWithoutWO.count - tournament.teamCount).formatted()) + } label: { + Text("Liste d'attente") + } + NavigationLink { InscriptionInfoView() .environment(tournament) } label: { LabeledContent { - Text(tournament.registrationIssues().formatted()).font(.largeTitle) + Text(tournament.registrationIssues().formatted()) } label: { Text("Problèmes détéctés") if let closedRegistrationDate = tournament.closedRegistrationDate { @@ -544,8 +557,6 @@ struct InscriptionManagerView: View { } } } - } header: { - Text(count.formatted() + "/" + tournament.teamCount.formatted() + " paires inscrites") } } @@ -849,6 +860,11 @@ struct InscriptionManagerView: View { private func _teamMenuOptionView(_ team: TeamRegistration) -> some View { Menu { Section { + Button("Copier") { + let pasteboard = UIPasteboard.general + pasteboard.string = team.playersPasteData() + } + Divider() Button("Changer les joueurs") { editedTeam = team team.unsortedPlayers().forEach { player in @@ -906,6 +922,7 @@ struct InscriptionManagerView: View { } label: { LabelDelete() } + // } header: { // Text(team.teamLabel(.short)) } diff --git a/PadelClub/Views/Tournament/Shared/TournamentCellView.swift b/PadelClub/Views/Tournament/Shared/TournamentCellView.swift index 3986974..9564134 100644 --- a/PadelClub/Views/Tournament/Shared/TournamentCellView.swift +++ b/PadelClub/Views/Tournament/Shared/TournamentCellView.swift @@ -71,7 +71,7 @@ struct TournamentCellView: View { Spacer() if let tournament = tournament as? Tournament, displayStyle == .wide { let hasStarted = tournament.inscriptionClosed() || tournament.hasStarted() - let count = hasStarted ? tournament.selectedSortedTeams().count : tournament.unsortedTeams().count + let count = hasStarted ? tournament.selectedSortedTeams().count : tournament.unsortedTeamsWithoutWO().count Text(count.formatted()) } else if let federalTournament = tournament as? FederalTournament { Button { diff --git a/PadelClub/Views/Tournament/TournamentInscriptionView.swift b/PadelClub/Views/Tournament/TournamentInscriptionView.swift index 868d261..ba99109 100644 --- a/PadelClub/Views/Tournament/TournamentInscriptionView.swift +++ b/PadelClub/Views/Tournament/TournamentInscriptionView.swift @@ -17,7 +17,7 @@ struct TournamentInscriptionView: View { Section { NavigationLink(value: Screen.inscription) { LabeledContent { - Text(tournament.unsortedTeams().count.formatted() + "/" + tournament.teamCount.formatted()) + Text(tournament.unsortedTeamsWithoutWO().count.formatted() + "/" + tournament.teamCount.formatted()) } label: { Text("Gestion des inscriptions") if let closedRegistrationDate = tournament.closedRegistrationDate {