diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index ece45dc..db5ca97 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -3344,7 +3344,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.1.15; + MARKETING_VERSION = 1.1.16; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3389,7 +3389,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.1.15; + MARKETING_VERSION = 1.1.16; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/PadelClub/Data/Match.swift b/PadelClub/Data/Match.swift index b80f645..5afa194 100644 --- a/PadelClub/Data/Match.swift +++ b/PadelClub/Data/Match.swift @@ -517,7 +517,7 @@ defer { return (groupStageObject.index + 1) * 100 + groupStageObject.indexOf(index) } guard let roundObject else { return index } - return roundObject.isLoserBracket() ? (roundObject.index + 1) * 10000 + indexInRound() : (roundObject.index + 1) * 1000 + indexInRound() + return (300 - (roundObject.theoryCumulativeMatchCount * 10 + roundObject.index * 22)) * 10 + indexInRound() } func previousMatches() -> [Match] { @@ -540,8 +540,10 @@ defer { func setWalkOut(_ teamPosition: TeamPosition) { let teamScoreWalkout = teamScore(teamPosition) ?? TeamScore(match: id, team: team(teamPosition)) teamScoreWalkout.walkOut = 0 + teamScoreWalkout.score = matchFormat.defaultWalkOutScore(true).compactMap({ String($0) }).joined(separator: ",") let teamScoreWinning = teamScore(teamPosition.otherTeam) ?? TeamScore(match: id, team: team(teamPosition.otherTeam)) teamScoreWinning.walkOut = nil + teamScoreWinning.score = matchFormat.defaultWalkOutScore(false).compactMap({ String($0) }).joined(separator: ",") do { try self.tournamentStore.teamScores.addOrUpdate(contentOfs: [teamScoreWalkout, teamScoreWinning]) } catch { diff --git a/PadelClub/Data/TeamRegistration.swift b/PadelClub/Data/TeamRegistration.swift index 6744812..8a9066e 100644 --- a/PadelClub/Data/TeamRegistration.swift +++ b/PadelClub/Data/TeamRegistration.swift @@ -645,6 +645,14 @@ final class TeamRegistration: ModelObject, Storable { func shouldDisplayRankAndWeight() -> Bool { unsortedPlayers().count > 0 } + + func bracketMatchTitleAndQualifiedStatus() -> String? { + let values = [qualified ? "Qualifié" : nil, initialMatch()?.roundAndMatchTitle()].compactMap({ $0 }) + if values.isEmpty { + return nil + } + return values.joined(separator: " -> ") + } enum CodingKeys: String, CodingKey { case _id = "id" diff --git a/PadelClub/Views/Match/Components/MatchDateView.swift b/PadelClub/Views/Match/Components/MatchDateView.swift index 51ccc19..5dd2187 100644 --- a/PadelClub/Views/Match/Components/MatchDateView.swift +++ b/PadelClub/Views/Match/Components/MatchDateView.swift @@ -30,7 +30,7 @@ struct MatchDateView: View { } var currentDate: Date { - Date().withoutSeconds() + Date() } var body: some View { diff --git a/PadelClub/Views/Match/Components/PlayerBlockView.swift b/PadelClub/Views/Match/Components/PlayerBlockView.swift index d4c8d73..e2a7e15 100644 --- a/PadelClub/Views/Match/Components/PlayerBlockView.swift +++ b/PadelClub/Views/Match/Components/PlayerBlockView.swift @@ -151,7 +151,7 @@ struct PlayerBlockView: View { } } } - } else if let team { + } else if let team, hasWon == false, isWalkOut == false { TeamWeightView(team: team, teamPosition: teamPosition) } } diff --git a/PadelClub/Views/Match/MatchDetailView.swift b/PadelClub/Views/Match/MatchDetailView.swift index 45f0444..9e19053 100644 --- a/PadelClub/Views/Match/MatchDetailView.swift +++ b/PadelClub/Views/Match/MatchDetailView.swift @@ -495,7 +495,7 @@ struct MatchDetailView: View { Text("Horaire") } .onChange(of: startDateSetup) { - let date = Date().withoutSeconds() + let date = Date() switch startDateSetup { case .customDate: break diff --git a/PadelClub/Views/Score/FollowUpMatchView.swift b/PadelClub/Views/Score/FollowUpMatchView.swift index 78cda7f..27a88a1 100644 --- a/PadelClub/Views/Score/FollowUpMatchView.swift +++ b/PadelClub/Views/Score/FollowUpMatchView.swift @@ -217,6 +217,11 @@ struct FollowUpMatchView: View { } #if DEBUG Spacer() + if let roundObject = match.roundObject { + Text(roundObject.index.formatted()) + Text(roundObject.theoryCumulativeMatchCount.formatted()) + } + Text(match.computedOrder.formatted()) FooterButtonView("copier l'id") { let pasteboard = UIPasteboard.general pasteboard.string = match.id diff --git a/PadelClub/Views/Shared/SelectablePlayerListView.swift b/PadelClub/Views/Shared/SelectablePlayerListView.swift index 4210ef9..16b7d7e 100644 --- a/PadelClub/Views/Shared/SelectablePlayerListView.swift +++ b/PadelClub/Views/Shared/SelectablePlayerListView.swift @@ -427,7 +427,9 @@ struct MySearchView: View { searchViewModel.selectedPlayers.insert(player) } label: { ImportedPlayerView(player: player, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true) + .contentShape(Rectangle()) } + .frame(maxWidth: .infinity) .buttonStyle(.plain) } } header: { diff --git a/PadelClub/Views/Team/EditingTeamView.swift b/PadelClub/Views/Team/EditingTeamView.swift index 8f06955..7263dfd 100644 --- a/PadelClub/Views/Team/EditingTeamView.swift +++ b/PadelClub/Views/Team/EditingTeamView.swift @@ -20,11 +20,11 @@ struct EditingTeamView: View { @State private var sentError: ContactManagerError? = nil @State private var showSubscriptionView: Bool = false @State private var registrationDate : Date + @State private var walkOut : Bool + @State private var wildCardBracket : Bool + @State private var wildCardGroupStage : Bool @State private var name: String @FocusState private var focusedField: TeamRegistration.CodingKeys? - @State private var presentOnlineRegistrationWarning: Bool = false - @State private var currentWaitingList: TeamRegistration? - @State private var presentTeamToWarn: Bool = false var messageSentFailed: Binding { Binding { @@ -36,6 +36,22 @@ struct EditingTeamView: View { } } + var hasChanged: Binding { + Binding { + if tournament.enableOnlineRegistration == false { + return false + } + + return + registrationDate != team.registrationDate + || walkOut != team.walkOut + || wildCardBracket != team.wildCardBracket + || wildCardGroupStage != team.wildCardGroupStage + + } set: { _ in + } + } + var tournamentStore: TournamentStore { return self.tournament.tournamentStore } @@ -44,25 +60,18 @@ struct EditingTeamView: View { self.team = team _name = .init(wrappedValue: team.name ?? "") _registrationDate = State(wrappedValue: team.registrationDate ?? Date()) + _walkOut = State(wrappedValue: team.walkOut) + _wildCardBracket = State(wrappedValue: team.wildCardBracket) + _wildCardGroupStage = State(wrappedValue: team.wildCardGroupStage) } private func _resetTeam() { - let selectedSortedTeams = tournament.selectedSortedTeams() - self.currentWaitingList = tournament.waitingListSortedTeams(selectedSortedTeams: selectedSortedTeams).filter({ $0.hasRegisteredOnline() }).first team.resetPositions() team.wildCardGroupStage = false team.walkOut = false team.wildCardBracket = false } - private func _checkOnlineRegistrationWarning() { - guard let currentWaitingList else { return } - let selectedSortedTeams = tournament.selectedSortedTeams().map({ $0.id }) - if selectedSortedTeams.contains(currentWaitingList.id) { - presentOnlineRegistrationWarning = true - } - } - var body: some View { List { Section { @@ -92,10 +101,6 @@ struct EditingTeamView: View { .headerProminence(.increased) Section { - DatePicker(selection: $registrationDate) { - Text("Inscription") - Text(registrationDate.localizedWeekDay().capitalized) - } if let callDate = team.callDate { LabeledContent() { Text(callDate.localizedDate()) @@ -117,34 +122,23 @@ struct EditingTeamView: View { Text("Équipe sur place") } } + } + + Section { + DatePicker(selection: $registrationDate) { + Text("Inscription") + Text(registrationDate.localizedWeekDay().capitalized) + } - Toggle(isOn: .init(get: { - return team.wildCardBracket - }, set: { value in - _resetTeam() - team.wildCardBracket = value - _save() - })) { + Toggle(isOn: $wildCardBracket) { Text("Wildcard Tableau") } - Toggle(isOn: .init(get: { - return team.wildCardGroupStage - }, set: { value in - _resetTeam() - team.wildCardGroupStage = value - _save() - })) { + Toggle(isOn: $wildCardGroupStage) { Text("Wildcard Poule") - } + }.disabled(tournament.groupStageCount == 0) - Toggle(isOn: .init(get: { - return team.walkOut - }, set: { value in - _resetTeam() - team.walkOut = value - _save() - })) { + Toggle(isOn: $walkOut) { Text("Forfait") } } @@ -216,30 +210,24 @@ struct EditingTeamView: View { } } } - .sheet(isPresented: $presentTeamToWarn) { - if let currentWaitingList { - NavigationStack { - EditingTeamView(team: currentWaitingList) - } - .tint(.master) + .alert("Attention", isPresented: hasChanged, actions: { + Button("Confirmer") { + _resetTeam() + team.registrationDate = registrationDate + team.wildCardBracket = wildCardBracket + team.wildCardGroupStage = wildCardGroupStage + team.walkOut = walkOut + _save() } - } - .alert("Attention", isPresented: $presentOnlineRegistrationWarning, actions: { - if currentWaitingList != nil { - - Button("Voir l'équipe") { - self.presentTeamToWarn = true - } - - Button("OK") { - self.currentWaitingList = nil - self.presentOnlineRegistrationWarning = false - } + + Button("Annuler", role: .cancel) { + registrationDate = team.registrationDate ?? Date() + walkOut = team.walkOut + wildCardBracket = team.wildCardBracket + wildCardGroupStage = team.wildCardGroupStage } }, message: { - if let currentWaitingList { - Text("L'équipe \(currentWaitingList.teamLabel(separator: "/")), inscrite en ligne, rentre dans votre sélection suite à la modification que vous venez de faire, voulez-vous les prévenir ?") - } + Text("Ce changement peut entraîner l'entrée ou la sortie d'une équipe de votre sélection. Padel Club préviendra automatiquement une équipe inscrite en ligne de son nouveau statut.") }) .navigationBarBackButtonHidden(focusedField != nil) .toolbar(content: { @@ -327,8 +315,19 @@ struct EditingTeamView: View { } } .onChange(of: registrationDate) { - team.registrationDate = registrationDate - _save() + if tournament.enableOnlineRegistration == false { + team.registrationDate = registrationDate + _save() + } + } + .onChange(of: [walkOut, wildCardBracket, wildCardGroupStage]) { + if tournament.enableOnlineRegistration == false { + _resetTeam() + team.walkOut = walkOut + team.wildCardBracket = wildCardBracket + team.wildCardGroupStage = wildCardGroupStage + _save() + } } .toolbarBackground(.visible, for: .navigationBar) .navigationTitle("Édition de l'équipe") @@ -369,8 +368,6 @@ struct EditingTeamView: View { } catch { Logger.error(error) } - - _checkOnlineRegistrationWarning() } private var _networkErrorMessage: String { diff --git a/PadelClub/Views/Team/TeamPickerView.swift b/PadelClub/Views/Team/TeamPickerView.swift index 0515283..73b8d59 100644 --- a/PadelClub/Views/Team/TeamPickerView.swift +++ b/PadelClub/Views/Team/TeamPickerView.swift @@ -134,11 +134,19 @@ struct TeamPickerView: View { // presentTeamPickerView = false // } } label: { - TeamRowView(team: team) - .contentShape(Rectangle()) + VStack(alignment: .leading) { + if let roundAndMatchTitle = team.bracketMatchTitleAndQualifiedStatus() { + Text(roundAndMatchTitle) + .font(.headline) + .frame(maxWidth: .infinity, alignment: .leading) + } + TeamRowView(team: team) + } + .contentShape(Rectangle()) } .frame(maxWidth: .infinity) .buttonStyle(.plain) + .id(team.id) .listRowView(isActive: matchTypeContext == .loserBracket && round?.teams().map({ $0.id }).contains(team.id) == true, color: .green, hideColorVariation: true) // .confirmationDialog("Attention", isPresented: confirmationRequest, titleVisibility: .visible) { // Button("Retirer du tableau", role: .destructive) { diff --git a/PadelClub/Views/Team/TeamRowView.swift b/PadelClub/Views/Team/TeamRowView.swift index 4a1ba04..bb32774 100644 --- a/PadelClub/Views/Team/TeamRowView.swift +++ b/PadelClub/Views/Team/TeamRowView.swift @@ -9,6 +9,8 @@ import SwiftUI struct TeamRowView: View { @EnvironmentObject var dataStore: DataStore + @Environment(\.isEditingTournamentSeed) private var isEditingTournamentSeed + var team: TeamRegistration var teamPosition: TeamPosition? = nil var displayCallDate: Bool = false @@ -20,7 +22,9 @@ struct TeamRowView: View { TeamWeightView(team: team, teamPosition: teamPosition, teamIndex: teamIndex) } label: { VStack(alignment: .leading) { - TeamHeadlineView(team: team) + if isEditingTournamentSeed.wrappedValue == false { + TeamHeadlineView(team: team) + } TeamView(team: team) } if displayCallDate { diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index 9ffefae..af7383c 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -247,7 +247,7 @@ struct InscriptionManagerView: View { if tournament.enableOnlineRegistration { RowButtonView("Rafraîchir la liste", cornerRadius: 20) { - await _refreshList() + await _refreshList(forced: true) } } else if tournament.onlineRegistrationCanBeEnabled() { RowButtonView("Inscription en ligne") { @@ -259,13 +259,15 @@ struct InscriptionManagerView: View { } } .task { - await _refreshList() + await _refreshList(forced: false) } .refreshable { - await _refreshList() + await _refreshList(forced: true) } .onAppear { - _setHash(currentSelectedSortedTeams: selectedSortedTeams) + if tournament.enableOnlineRegistration == false || refreshStatus == true { + _setHash(currentSelectedSortedTeams: selectedSortedTeams) + } } .onDisappear { _handleHashDiff(selectedSortedTeams: selectedSortedTeams) @@ -544,7 +546,8 @@ struct InscriptionManagerView: View { // try? tournamentStore.playerRegistrations.addOrUpdate(contentOfs: players) // } // - private func _refreshList() async { + private func _refreshList(forced: Bool) async { + if refreshStatus == true, forced == false { return } if tournament.enableOnlineRegistration == false { return } if tournament.hasEnded() { return } if tournament.refreshInProgress { return } diff --git a/PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift b/PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift index bc1445f..13c38d2 100644 --- a/PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift +++ b/PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift @@ -75,8 +75,8 @@ struct RegistrationSetupView: View { var body: some View { List { - if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false { - Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Pour l'instant Padel Club ne saura pas les prévenir automatiquement, vous devrez les contacter via l'écran de gestion des inscriptions.") + if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false, tournament.hasEnded() == false, tournament.hasStarted() == false { + Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.") .foregroundStyle(.logoRed) } diff --git a/PadelClub/Views/Tournament/Screen/TableStructureView.swift b/PadelClub/Views/Tournament/Screen/TableStructureView.swift index 19cfc4c..1d8b8a0 100644 --- a/PadelClub/Views/Tournament/Screen/TableStructureView.swift +++ b/PadelClub/Views/Tournament/Screen/TableStructureView.swift @@ -60,8 +60,8 @@ struct TableStructureView: View { @ViewBuilder var body: some View { List { - if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false { - Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Pour l'instant Padel Club ne saura pas les prévenir automatiquement, vous devrez les contacter via l'écran de gestion des inscriptions.") + if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false, tournament.hasEnded() == false, tournament.hasStarted() == false { + Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.") .foregroundStyle(.logoRed) }