diff --git a/PadelClub/Data/TeamRegistration.swift b/PadelClub/Data/TeamRegistration.swift index 2d24670..9fcefab 100644 --- a/PadelClub/Data/TeamRegistration.swift +++ b/PadelClub/Data/TeamRegistration.swift @@ -43,6 +43,11 @@ final class TeamRegistration: ModelObject, Storable { players().anySatisfy({ $0.source == .onlineRegistration }) } + func unrankedOrUnknown() -> Bool { + players().anySatisfy({ $0.source == nil }) + } + + func isOutOfTournament() -> Bool { walkOut } diff --git a/PadelClub/Views/Team/EditingTeamView.swift b/PadelClub/Views/Team/EditingTeamView.swift index 1afd064..ab452e0 100644 --- a/PadelClub/Views/Team/EditingTeamView.swift +++ b/PadelClub/Views/Team/EditingTeamView.swift @@ -22,7 +22,9 @@ struct EditingTeamView: View { @State private var registrationDate : Date @State private var name: String @FocusState private var focusedField: TeamRegistration.CodingKeys? - + @State private var presentOnlineRegistrationWarning: Bool = false + @State private var currentWaitingList: TeamRegistration? + var messageSentFailed: Binding { Binding { sentError != nil @@ -43,6 +45,22 @@ struct EditingTeamView: View { _registrationDate = State(wrappedValue: team.registrationDate ?? Date()) } + private func _resetTeam() { + self.currentWaitingList = tournament.waitingListSortedTeams().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 { @@ -101,15 +119,9 @@ struct EditingTeamView: View { Toggle(isOn: .init(get: { return team.wildCardBracket }, set: { value in - team.resetPositions() - team.wildCardGroupStage = false - team.walkOut = false + _resetTeam() team.wildCardBracket = value - do { - try tournamentStore.teamRegistrations.addOrUpdate(instance: team) - } catch { - Logger.error(error) - } + _save() })) { Text("Wildcard Tableau") } @@ -117,15 +129,9 @@ struct EditingTeamView: View { Toggle(isOn: .init(get: { return team.wildCardGroupStage }, set: { value in - team.resetPositions() - team.wildCardBracket = false - team.walkOut = false + _resetTeam() team.wildCardGroupStage = value - do { - try tournamentStore.teamRegistrations.addOrUpdate(instance: team) - } catch { - Logger.error(error) - } + _save() })) { Text("Wildcard Poule") } @@ -133,15 +139,9 @@ struct EditingTeamView: View { Toggle(isOn: .init(get: { return team.walkOut }, set: { value in - team.resetPositions() - team.wildCardBracket = false - team.wildCardGroupStage = false + _resetTeam() team.walkOut = value - do { - try tournamentStore.teamRegistrations.addOrUpdate(instance: team) - } catch { - Logger.error(error) - } + _save() })) { Text("Forfait") } @@ -199,12 +199,9 @@ struct EditingTeamView: View { Section { RowButtonView("Effacer l'équipe", role: .destructive, systemImage: "trash") { + _resetTeam() team.deleteTeamScores() - do { - try tournamentStore.teamRegistrations.delete(instance: team) - } catch { - Logger.error(error) - } + _save() dismiss() } } footer: { @@ -213,6 +210,19 @@ struct EditingTeamView: View { } } } + .alert("Attention", isPresented: $presentOnlineRegistrationWarning, actions: { + if let currentWaitingList { + Button("Prévenir") { + + } + + Button("OK") { + self.currentWaitingList = nil + } + } + }, message: { + Text("Cette équipe, inscrite en ligne, rentre dans votre sélection suite à la modification que vous venez de faire, voulez-vous les prévenir ?") + }) .navigationBarBackButtonHidden(focusedField != nil) .toolbar(content: { if focusedField != nil { diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index 125e6bc..6138632 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -53,10 +53,86 @@ struct InscriptionManagerView: View { @State private var refreshResult: String? = nil @State private var refreshInProgress: Bool = false @State private var refreshStatus: Bool? + @State private var showLegendView: Bool = false var tournamentStore: TournamentStore { return self.tournament.tournamentStore } + + enum LegendPositionTip: Int, Identifiable, CaseIterable { + var id: Int { self.rawValue } + case groupStage + case bracket + + func legendDescriptionLabel() -> String { + return "" + } + + var isActive: Bool { + switch self { + case .groupStage: + return true + case .bracket: + return true + } + } + + var color: Color { + switch self { + case .groupStage: + return .red + case .bracket: + return .green + } + } + + var hideColorVariation: Bool { + switch self { + case .groupStage: + return true + case .bracket: + return true + } + } + } + + enum LegendInscriptionTip: Int, Identifiable, CaseIterable { + var id: Int { self.rawValue } + case groupStage + case bracket + + func legendDescriptionLabel() -> String { + return "" + } + + var isActive: Bool { + switch self { + case .groupStage: + return true + case .bracket: + return true + } + } + + var color: Color { + switch self { + case .groupStage: + return .red + case .bracket: + return .green + } + } + + var hideColorVariation: Bool { + switch self { + case .groupStage: + return true + case .bracket: + return true + } + } + + } enum SortingMode: Int, Identifiable, CaseIterable { var id: Int { self.rawValue } @@ -592,6 +668,8 @@ struct InscriptionManagerView: View { } } + let isImported = teams.anySatisfy({ $0.isImported() }) + if teams.isEmpty == false { if compactMode { Section { @@ -602,13 +680,19 @@ struct InscriptionManagerView: View { .environment(tournament) } label: { TeamRowView(team: team) + if isImported && team.isImported() == false { + Text("ne provient pas du fichier beach-padel").foregroundStyle(.red) + } } .swipeActions(edge: .trailing, allowsFullSwipe: true) { if tournament.enableOnlineRegistration == false { _teamDeleteButtonView(team) } } - .listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true) + .listRowView(isActive: team.hasRegisteredOnline(), color: .master, hideColorVariation: true) + .listRowView(isActive: team.unrankedOrUnknown(), color: .logoYellow, hideColorVariation: true) + .listRowView(isActive: isImported && team.isImported() == false, color: .red, hideColorVariation: false) + .listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true, alignment: .trailing) } } header: { if filterMode == .all && walkoutTeams.isEmpty == false { @@ -616,8 +700,32 @@ struct InscriptionManagerView: View { } else { Text("\(teams.count.formatted()) équipe\(teams.count.pluralSuffix)") } + } footer: { + FooterButtonView("Légende") { + showLegendView = true + } } .headerProminence(.increased) + .sheet(isPresented: $showLegendView) { + List { + Section { + ForEach(LegendInscriptionTip.allCases) { legend in + Text(legend.legendDescriptionLabel()) + .listRowView(isActive: legend.isActive, color: legend.color, hideColorVariation: legend.hideColorVariation) + } + } header: { + Text("Statut de l'inscription") + } + Section { + ForEach(LegendPositionTip.allCases) { legend in + Text(legend.legendDescriptionLabel()) + .listRowView(isActive: legend.isActive, color: legend.color, hideColorVariation: legend.hideColorVariation, alignment: .trailing) + } + } header: { + Text("Statut de la position dans le tournoi") + } + } + } } else { ForEach(teams) { team in let teamIndex = team.index(in: sortedTeams)