diff --git a/PadelClub/Data/Match.swift b/PadelClub/Data/Match.swift index 745e456..fb20842 100644 --- a/PadelClub/Data/Match.swift +++ b/PadelClub/Data/Match.swift @@ -608,6 +608,8 @@ defer { func canBeStarted(inMatches matches: [Match]) -> Bool { let teams = teamScores guard teams.count == 2 else { return false } + guard hasEnded() == false else { return false } + guard hasStarted() == false else { return false } return teams.compactMap({ $0.team }).allSatisfy({ $0.canPlay() && isTeamPlaying($0, inMatches: matches) == false }) } diff --git a/PadelClub/Data/TeamRegistration.swift b/PadelClub/Data/TeamRegistration.swift index 87cf1e7..98cbae4 100644 --- a/PadelClub/Data/TeamRegistration.swift +++ b/PadelClub/Data/TeamRegistration.swift @@ -7,6 +7,7 @@ import Foundation import LeStorage +import SwiftUI @Observable final class TeamRegistration: ModelObject, Storable { @@ -272,6 +273,25 @@ final class TeamRegistration: ModelObject, Storable { return bracketPosition != nil } + func positionLabel() -> String? { + if groupStagePosition != nil { return "Poule" } + if let initialRound = initialRound() { + return initialRound.roundTitle() + } else { + return nil + } + } + + func initialRoundColor() -> Color? { + if walkOut { return Color.logoRed } + if groupStagePosition != nil { return Color.mint } + if let initialRound = initialRound(), let colorHex = RoundRule.colors[safe: initialRound.index] { + return Color(uiColor: .init(fromHex: colorHex)) + } else { + return nil + } + } + func resetGroupeStagePosition() { if let groupStage { let matches = self.tournamentStore.matches.filter({ $0.groupStage == groupStage }).map { $0.id } diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 79287fa..333ae94 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -7,6 +7,7 @@ import Foundation import LeStorage +import SwiftUI @Observable final class Tournament : ModelObject, Storable { @@ -906,7 +907,20 @@ defer { return "Attente" } } - + + func cutLabelColor(index: Int?, teamCount: Int?) -> Color { + guard let index else { return Color.gray } + let _teamCount = teamCount ?? selectedSortedTeams().count + let bracketCut = bracketCut(teamCount: _teamCount) + if index < bracketCut { + return Color.cyan + } else if index - bracketCut < groupStageCut() && _teamCount > 0 { + return Color.indigo + } else { + return Color.gray + } + } + func unsortedTeamsWithoutWO() -> [TeamRegistration] { return self.tournamentStore.teamRegistrations.filter { $0.walkOut == false } // return Store.main.filter { $0.tournament == self.id && $0.walkOut == false } @@ -1410,7 +1424,7 @@ defer { } func moreQualifiedToDraw() -> Int { - return max(qualifiedTeams().count - (qualifiedFromGroupStage() + groupStageAdditionalQualified), 0) + return max((qualifiedFromGroupStage() + groupStageAdditionalQualified) - qualifiedTeams().count, 0) } func missingQualifiedFromGroupStages() -> [TeamRegistration] { diff --git a/PadelClub/Extensions/Color+Extensions.swift b/PadelClub/Extensions/Color+Extensions.swift index 60fb159..cb5359b 100644 --- a/PadelClub/Extensions/Color+Extensions.swift +++ b/PadelClub/Extensions/Color+Extensions.swift @@ -6,6 +6,7 @@ // import SwiftUI +import UIKit extension Color { @@ -33,3 +34,36 @@ extension Color { } } + +extension UIColor { + /// Initialises NSColor from a hexadecimal string. Color is clear if string is invalid. + /// - Parameter fromHex: supported formats are "#RGB", "#RGBA", "#RRGGBB", "#RRGGBBAA", with or without the # character + public convenience init(fromHex:String) { + var r = 0, g = 0, b = 0, a = 255 + let offset = fromHex.hasPrefix("#") ? 1 : 0 + let ch = fromHex.map{$0} + switch(ch.count - offset) { + case 8: + a = 16 * (ch[offset+6].hexDigitValue ?? 0) + (ch[offset+7].hexDigitValue ?? 0) + fallthrough + case 6: + r = 16 * (ch[offset+0].hexDigitValue ?? 0) + (ch[offset+1].hexDigitValue ?? 0) + g = 16 * (ch[offset+2].hexDigitValue ?? 0) + (ch[offset+3].hexDigitValue ?? 0) + b = 16 * (ch[offset+4].hexDigitValue ?? 0) + (ch[offset+5].hexDigitValue ?? 0) + break + case 4: + a = 16 * (ch[offset+3].hexDigitValue ?? 0) + (ch[offset+3].hexDigitValue ?? 0) + fallthrough + case 3: // Three digit #0D3 is the same as six digit #00DD33 + r = 16 * (ch[offset+0].hexDigitValue ?? 0) + (ch[offset+0].hexDigitValue ?? 0) + g = 16 * (ch[offset+1].hexDigitValue ?? 0) + (ch[offset+1].hexDigitValue ?? 0) + b = 16 * (ch[offset+2].hexDigitValue ?? 0) + (ch[offset+2].hexDigitValue ?? 0) + break + default: + a = 0 + break + } + self.init(red: CGFloat(r)/255, green: CGFloat(g)/255, blue: CGFloat(b)/255, alpha: CGFloat(a)/255) + + } +} diff --git a/PadelClub/Extensions/Date+Extensions.swift b/PadelClub/Extensions/Date+Extensions.swift index 0c20d51..1a31a36 100644 --- a/PadelClub/Extensions/Date+Extensions.swift +++ b/PadelClub/Extensions/Date+Extensions.swift @@ -227,4 +227,8 @@ extension Date { func localizedDay() -> String { self.formatted(.dateTime.weekday(.wide).day()) } + + func localizedWeekDay() -> String { + self.formatted(.dateTime.weekday(.wide)) + } } diff --git a/PadelClub/Utils/PadelRule.swift b/PadelClub/Utils/PadelRule.swift index b722152..0af54b5 100644 --- a/PadelClub/Utils/PadelRule.swift +++ b/PadelClub/Utils/PadelRule.swift @@ -1444,6 +1444,8 @@ enum PlayersCountRange: Int, CaseIterable { } enum RoundRule { + static let colors = ["#d4afb9", "#d1cfe2", "#9cadce", "#7ec4cf", "#daeaf6", "#caffbf"] + static func loserBrackets(index: Int) -> [String] { switch index { case 1: diff --git a/PadelClub/Views/Components/FortuneWheelView.swift b/PadelClub/Views/Components/FortuneWheelView.swift index 3005457..ac659d1 100644 --- a/PadelClub/Views/Components/FortuneWheelView.swift +++ b/PadelClub/Views/Components/FortuneWheelView.swift @@ -336,7 +336,7 @@ struct FortuneWheelView: View { let strings = segments[index].segmentLabel(.short) ForEach(strings, id: \.self) { string in Text(string).bold() - .font(.caption) + .font(.subheadline) } } .offset(x: -20) diff --git a/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift b/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift index 6200a90..6ef48da 100644 --- a/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift +++ b/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift @@ -20,8 +20,8 @@ struct GroupStagesSettingsView: View { var body: some View { List { - if tournament.moreQualifiedToDraw() > 0 { - let missingQualifiedFromGroupStages = tournament.missingQualifiedFromGroupStages() + let missingQualifiedFromGroupStages = tournament.missingQualifiedFromGroupStages() + Section { let name = "\((tournament.groupStageAdditionalQualified + 1).ordinalFormatted())" NavigationLink("Tirage au sort d'un \(name)") { SpinDrawView(drawees: ["Qualification d'un \(name)"], segments: missingQualifiedFromGroupStages) { results in @@ -35,6 +35,13 @@ struct GroupStagesSettingsView: View { } } } + .disabled(tournament.moreQualifiedToDraw() == 0 || missingQualifiedFromGroupStages.isEmpty) + } footer: { + if tournament.moreQualifiedToDraw() == 0 { + Text("Aucune équipe supplémentaire à qualifier. Vous pouvez en rajouter en modifier le paramètre dans structure.") + } else if missingQualifiedFromGroupStages.isEmpty { + Text("Aucune équipe supplémentaire à tirer au sort. Attendez la fin des poules.") + } } if tournament.shouldVerifyGroupStage { diff --git a/PadelClub/Views/Team/Components/TeamHeaderView.swift b/PadelClub/Views/Team/Components/TeamHeaderView.swift index 3e386cc..6e896a1 100644 --- a/PadelClub/Views/Team/Components/TeamHeaderView.swift +++ b/PadelClub/Views/Team/Components/TeamHeaderView.swift @@ -42,12 +42,20 @@ struct TeamHeaderView: View { Text("").font(.caption) Text("WO") } else if let teamIndex, let tournament { + let positionLabel = team.positionLabel() + let cutLabel = tournament.cutLabel(index: teamIndex, teamCount: teamCount) if team.isWildCard() { Text("wildcard").font(.caption).italic() + Text(positionLabel ?? cutLabel) } else { - Text("").font(.caption) + if let positionLabel { + Text("placée").font(.caption) + Text(positionLabel) + } else { + Text("estimée").font(.caption) + Text(cutLabel) + } } - Text(tournament.cutLabel(index: teamIndex, teamCount: teamCount)) } } } diff --git a/PadelClub/Views/Team/EditingTeamView.swift b/PadelClub/Views/Team/EditingTeamView.swift index 27b0c73..6b56ee4 100644 --- a/PadelClub/Views/Team/EditingTeamView.swift +++ b/PadelClub/Views/Team/EditingTeamView.swift @@ -50,7 +50,7 @@ struct EditingTeamView: View { } Section { - DatePicker(registrationDate.formatted(.dateTime.weekday()), selection: $registrationDate) + DatePicker(registrationDate.localizedWeekDay(), selection: $registrationDate) } header: { Text("Date d'inscription") } @@ -101,7 +101,7 @@ struct EditingTeamView: View { _save() } .headerProminence(.increased) - .navigationTitle("Édition") + .navigationTitle("Statut de l'équipe") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.visible, for: .navigationBar) } diff --git a/PadelClub/Views/Team/TeamRowView.swift b/PadelClub/Views/Team/TeamRowView.swift index 9c25d55..0b3550d 100644 --- a/PadelClub/Views/Team/TeamRowView.swift +++ b/PadelClub/Views/Team/TeamRowView.swift @@ -20,8 +20,14 @@ struct TeamRowView: View { if let name = team.name { Text(name).foregroundStyle(.secondary) } - ForEach(team.players()) { player in - Text(player.playerLabel()) + + if team.players().isEmpty == false { + ForEach(team.players()) { player in + Text(player.playerLabel()) + } + } else { + Text("Place réservée") + Text("Place réservée") } } if displayCallDate { diff --git a/PadelClub/Views/Tournament/Screen/Components/CloseDatePicker.swift b/PadelClub/Views/Tournament/Screen/Components/CloseDatePicker.swift index a0f92e2..32082ac 100644 --- a/PadelClub/Views/Tournament/Screen/Components/CloseDatePicker.swift +++ b/PadelClub/Views/Tournament/Screen/Components/CloseDatePicker.swift @@ -15,7 +15,8 @@ struct CloseDatePicker: View { var body: some View { DatePicker(selection: $closedRegistrationDate) { - Text("Date de clôture") + Text("Date de clôture").font(.caption) + Text(closedRegistrationDate.localizedWeekDay().capitalized) } .onChange(of: closedRegistrationDate) { tournament.closedRegistrationDate = closedRegistrationDate diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index 16f2616..dce6202 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -49,7 +49,7 @@ struct InscriptionManagerView: View { @State private var showSubscriptionView: Bool = false @State private var confirmDuplicate: Bool = false @State private var presentAddTeamView: Bool = false - @State private var compactMode: Bool = false + @State private var compactMode: Bool = true @State private var pasteString: String? var tournamentStore: TournamentStore { @@ -89,19 +89,63 @@ struct InscriptionManagerView: View { case waiting case bracket case groupStage + case wildcardGroupStage + case wildcardBracket + func emptyLocalizedLabelDescription() -> String { + switch self { + case .wildcardBracket: + return "Vous n'avez aucune wildcard en tableau." + case .wildcardGroupStage: + return "Vous n'avez aucune wildcard en poule." + case .all: + return "Vous n'avez encore aucune équipe inscrite." + case .walkOut: + return "Vous n'avez aucune équipe forfait." + case .waiting: + return "Vous n'avez aucune équipe en liste d'attente." + case .bracket: + return "Vous n'avez placé aucune équipe dans le tableau." + case .groupStage: + return "Vous n'avez placé aucune équipe en poule." + } + } + + func emptyLocalizedLabelTitle() -> String { + switch self { + case .wildcardBracket: + return "Aucune wildcard en tableau" + case .wildcardGroupStage: + return "Aucune wildcard en poule" + case .all: + return "Aucune équipe inscrite" + case .walkOut: + return "Aucune équipe forfait" + case .waiting: + return "Aucune équipe en attente" + case .bracket: + return "Aucune équipe dans le tableau" + case .groupStage: + return "Aucune équipe en poule" + } + } + func localizedLabel(_ displayStyle: DisplayStyle = .wide) -> String { switch self { + case .wildcardBracket: + return displayStyle == .wide ? "Wildcard Tableau" : "wc tableau" + case .wildcardGroupStage: + return displayStyle == .wide ? "Wildcard Poule" : "wc poule" case .all: - return displayStyle == .wide ? "Équipes inscrites / souhaitées" : "Paires inscrites" + return displayStyle == .wide ? "Équipes inscrites" : "inscris" case .bracket: - return displayStyle == .wide ? "En Tableau" : "Tableau" + return displayStyle == .wide ? "En Tableau" : "tableau" case .groupStage: - return displayStyle == .wide ? "En Poule" : "Poule" + return displayStyle == .wide ? "En Poule" : "poule" case .walkOut: - return displayStyle == .wide ? "Forfaits" : "Forfait" + return displayStyle == .wide ? "Forfaits" : "forfait" case .waiting: - return displayStyle == .wide ? "Liste d'attente" : "Attente" + return displayStyle == .wide ? "Liste d'attente" : "attente" } } } @@ -313,7 +357,7 @@ struct InscriptionManagerView: View { Divider() Picker(selection: $filterMode) { ForEach(FilterMode.allCases) { - Text($0.localizedLabel(.short)).tag($0) + Text($0.localizedLabel()).tag($0) } } label: { } @@ -415,10 +459,14 @@ struct InscriptionManagerView: View { var teams = sortedTeams switch filterMode { + case .wildcardBracket: + teams = teams.filter({ $0.wildCardBracket }) + case .wildcardGroupStage: + teams = teams.filter({ $0.wildCardGroupStage }) case .walkOut: teams = teams.filter({ $0.walkOut }) case .bracket: - teams = teams.filter({ $0.inRound() }) + teams = teams.filter({ $0.inRound() && $0.inGroupStage() == false }) case .groupStage: teams = teams.filter({ $0.inGroupStage() }) default: @@ -469,39 +517,53 @@ struct InscriptionManagerView: View { } } } - if compactMode { - Section { - ForEach(teams) { team in - let teamIndex = team.index(in: sortedTeams) - NavigationLink { - _teamCompactTeamEditionView(team) - .environment(tournament) - } label: { - TeamRowView(team: team) + + if teams.isEmpty == false { + if compactMode { + Section { + ForEach(teams) { team in + let teamIndex = team.index(in: sortedTeams) + NavigationLink { + _teamCompactTeamEditionView(team) + .environment(tournament) + } label: { + TeamRowView(team: team) + } + .swipeActions(edge: .trailing, allowsFullSwipe: true) { + _teamDeleteButtonView(team) + } + .listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: selectedSortedTeams.count), hideColorVariation: true) } - .swipeActions(edge: .trailing, allowsFullSwipe: true) { - _teamDeleteButtonView(team) + } header: { + if filterMode == .all { + Text("\(teams.count.formatted()) équipe\(teams.count.pluralSuffix) dont \(walkoutTeams.count.formatted()) forfait\(walkoutTeams.count.pluralSuffix)") + } else { + Text("\(teams.count.formatted()) équipe\(teams.count.pluralSuffix)") } } - } header: { - LabeledContent { - Text(teams.count.formatted()) - } label: { - Text("Équipe\(teams.count.pluralSuffix)") + .headerProminence(.increased) + } else { + ForEach(teams) { team in + let teamIndex = team.index(in: sortedTeams) + Section { + TeamDetailView(team: team) + } header: { + TeamHeaderView(team: team, teamIndex: filterMode == .waiting ? nil : teamIndex, tournament: tournament, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count) + } footer: { + _teamFooterView(team) + } + .headerProminence(.increased) } } - .headerProminence(.increased) - } else { - ForEach(teams) { team in - let teamIndex = team.index(in: sortedTeams) - Section { - TeamDetailView(team: team) - } header: { - TeamHeaderView(team: team, teamIndex: filterMode == .waiting ? nil : teamIndex, tournament: tournament, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count) - } footer: { - _teamFooterView(team) + } else if filterMode != .all { + ContentUnavailableView { + Label(filterMode.emptyLocalizedLabelTitle(), systemImage: "person.2.slash") + } description: { + Text(filterMode.emptyLocalizedLabelDescription()) + } actions: { + RowButtonView("Supprimer le filtre") { + filterMode = .all } - .headerProminence(.increased) } } } @@ -526,7 +588,8 @@ struct InscriptionManagerView: View { EditingTeamView(team: team) .environment(tournament) } label: { - Text("Éditer une donnée de l'équipe") + Text("Modifier le statut de l'équipe") + Text("Nom de l'équipe, date d'inscription, présence, position") } NavigationLink { @@ -676,10 +739,14 @@ struct InscriptionManagerView: View { private func _teamCountForFilterMode(filterMode: FilterMode) -> String { switch filterMode { + case .wildcardBracket: + return tournament.selectedSortedTeams().filter({ $0.wildCardBracket }).count.formatted() + case .wildcardGroupStage: + return tournament.selectedSortedTeams().filter({ $0.wildCardGroupStage }).count.formatted() case .all: - return unsortedTeamsWithoutWO.count.formatted() + " / " + tournament.teamCount.formatted() + return unsortedTeamsWithoutWO.count.formatted() case .bracket: - return tournament.selectedSortedTeams().filter({ $0.inRound() }).count.formatted() + return tournament.selectedSortedTeams().filter({ $0.inRound() && $0.inGroupStage() == false }).count.formatted() case .groupStage: return tournament.selectedSortedTeams().filter({ $0.inGroupStage() }).count.formatted() case .walkOut: @@ -695,83 +762,57 @@ struct InscriptionManagerView: View { private func _informationView() -> some View { Section { HStack { - VStack(alignment: .leading, spacing: 0) { - Text("Inscriptions").font(.caption) - Text(unsortedTeamsWithoutWO.count.formatted()).font(.largeTitle) - } - .frame(maxWidth: .infinity) - .contentShape(Rectangle()) - .onTapGesture { - self.filterMode = .all +// VStack(alignment: .leading, spacing: 0) { +// Text("Inscriptions").font(.caption) +// Text(unsortedTeamsWithoutWO.count.formatted()).font(.largeTitle) +// } +// .frame(maxWidth: .infinity) +// .contentShape(Rectangle()) +// .onTapGesture { +// self.filterMode = .all +// } +// + ForEach([FilterMode.all, FilterMode.waiting, FilterMode.walkOut]) { filterMode in + _filterModeView(filterMode: filterMode) } - VStack(alignment: .leading, spacing: 0) { - Text("Paires souhaitées").font(.caption) - Text(tournament.teamCount.formatted()).font(.largeTitle) - } - .frame(maxWidth: .infinity) - Button { presentAddTeamView = true } label: { - Label { - Text("Ajouter une équipe") - } icon: { - Image(systemName: "person.2.fill") - .resizable() - .scaledToFit() - .frame(height:44) - } - .labelStyle(.iconOnly) - .overlay(alignment: .bottomTrailing) { - Image(systemName: "plus.circle.fill") - .foregroundColor(.master) - .background ( - Color(.systemBackground) - .clipShape(.circle) - ) - } + Image(systemName: "plus.circle.fill") + .resizable() + .scaledToFit() + .frame(maxWidth: .infinity) } - .buttonBorderShape(.roundedRectangle) - .buttonStyle(.borderedProminent) - .frame(maxWidth: .infinity) + .labelStyle(.iconOnly) + .buttonStyle(.borderless) + .padding(10) } + .padding(.bottom, -4) .fixedSize(horizontal: false, vertical: false) - .padding(.horizontal, -8) - + .listRowSeparator(.hidden) HStack { - ForEach([FilterMode.waiting, FilterMode.walkOut, FilterMode.groupStage, FilterMode.bracket]) { filterMode in - - Button { - if self.filterMode == filterMode { - self.filterMode = .all - } else { - self.filterMode = filterMode - } - } label: { - VStack(alignment: .leading, spacing: 0) { - Text(filterMode.localizedLabel(.short)).font(.caption) - Text(_teamCountForFilterMode(filterMode: filterMode)).font(.largeTitle) - } - .frame(maxWidth: .infinity) - .contentShape(Rectangle()) - } - .buttonBorderShape(.roundedRectangle) - .buttonStyle(.borderedProminent) - .tint(self.filterMode == filterMode ? .master : .beige) + ForEach([FilterMode.groupStage, FilterMode.bracket, FilterMode.wildcardGroupStage, FilterMode.wildcardBracket]) { filterMode in + _filterModeView(filterMode: filterMode) } } - .foregroundStyle(.primary) + .padding(.bottom, -4) .fixedSize(horizontal: false, vertical: false) - - NavigationLink { - InscriptionInfoView() - .environment(tournament) - } label: { - LabeledContent { - Text(tournament.registrationIssues().formatted()) + .listRowSeparator(.hidden) + + let registrationIssues = tournament.registrationIssues() + if registrationIssues > 0 { + NavigationLink { + InscriptionInfoView() + .environment(tournament) } label: { - Text("Problèmes détéctés") + LabeledContent { + Text(tournament.registrationIssues().formatted()) + .foregroundStyle(.logoRed) + .fontWeight(.bold) + } label: { + Text("Problèmes détéctés") + } } } @@ -794,7 +835,30 @@ struct InscriptionManagerView: View { } } } -// + + private func _filterModeView(filterMode: FilterMode) -> some View { + + Button { + if self.filterMode == filterMode { + self.filterMode = .all + } else { + self.filterMode = filterMode + } + } label: { + VStack(alignment: .center, spacing: -2) { + Text(filterMode.localizedLabel(.short)).font(.caption).padding(.horizontal, -8) + Text(_teamCountForFilterMode(filterMode: filterMode)).font(.largeTitle) + } + .frame(maxWidth: .infinity) + .contentShape(Rectangle()) + } + .buttonBorderShape(.roundedRectangle) + .buttonStyle(.borderedProminent) + .foregroundStyle(.primary) + .tint(self.filterMode == filterMode ? .master : .beige) + + } +// // @ViewBuilder // private func _informationView() -> some View { // Section { @@ -1012,7 +1076,7 @@ struct InscriptionManagerView: View { EditingTeamView(team: team) .environment(tournament) } label: { - Text("Éditer une donnée de l'équipe") + Text("Modifier une donnée de l'équipe") } Divider() Toggle(isOn: .init(get: { diff --git a/PadelClub/Views/Tournament/TournamentView.swift b/PadelClub/Views/Tournament/TournamentView.swift index 531b7a4..fa14f46 100644 --- a/PadelClub/Views/Tournament/TournamentView.swift +++ b/PadelClub/Views/Tournament/TournamentView.swift @@ -118,16 +118,18 @@ struct TournamentView: View { .navigationBarTitleDisplayMode(.inline) .toolbarTitleMenu { if let event = tournament.eventObject() { - Picker(selection: selectedTournamentId) { - ForEach(event.tournaments) { tournament in - Text(tournament.tournamentTitle(.title)).tag(tournament.id as String) + if presentationContext == .agenda { + Picker(selection: selectedTournamentId) { + ForEach(event.tournaments) { tournament in + Text(tournament.tournamentTitle(.title)).tag(tournament.id as String) + } + } label: { + } - } label: { + Divider() } - Divider() - NavigationLink(value: Screen.event) { Text("Gestion de l'événement") } @@ -148,7 +150,7 @@ struct TournamentView: View { } } - if (presentationContext == .agenda || tournament.state() == .running) && tournament.isCanceled == false { + if tournament.isCanceled == false { ToolbarItem(placement: .topBarTrailing) { Menu { @@ -170,34 +172,29 @@ struct TournamentView: View { } label: { Label("Voir dans le gestionnaire", systemImage: "line.diagonal.arrow") } + Divider() } - Divider() - if tournament.state() == .running || tournament.state() == .finished { - NavigationLink(value: Screen.event) { - Text("Gestion de l'événement") - } - - - NavigationLink(value: Screen.settings) { - LabelSettings() - } - NavigationLink(value: Screen.structure) { - LabelStructure() - } - - NavigationLink(value: Screen.broadcast) { - Label("Publication", systemImage: "airplayvideo") - } - - NavigationLink(value: Screen.print) { - Label("Imprimer", systemImage: "printer") - } + NavigationLink(value: Screen.event) { + Text("Gestion de l'événement") + } + NavigationLink(value: Screen.settings) { + LabelSettings() + } + NavigationLink(value: Screen.structure) { + LabelStructure() + } + NavigationLink(value: Screen.broadcast) { + Label("Publication", systemImage: "airplayvideo") } + NavigationLink(value: Screen.print) { + Label("Imprimer", systemImage: "printer") + } + Divider() - + NavigationLink { TournamentStatusView(tournament: tournament) } label: {