// // TeamsCallingView.swift // PadelClub // // Created by razmig on 10/07/2024. // import SwiftUI import LeStorage import PadelClubData struct TeamsCallingView: View { @Environment(Tournament.self) var tournament: Tournament @EnvironmentObject var dataStore: DataStore let teams : [TeamRegistration] @State private var hideConfirmed: Bool = false @State private var hideGoodSummoned: Bool = false @State private var hideSummoned: Bool = false @State private var searchText: String = "" var filteredTeams: [TeamRegistration] { teams .filter({ hideConfirmed == false || $0.confirmed() == false }) .filter({ hideSummoned == false || $0.called() == false }) .filter({ hideGoodSummoned == false || tournament.isStartDateIsDifferentThanCallDate($0) == true }) .filter({ searchText.isEmpty || $0.contains(searchText) }) } var anyFilterEnabled: Bool { hideConfirmed || hideGoodSummoned || hideSummoned } var body: some View { List { if tournament.isPrivate { Section { RowButtonView("Rendre visible sur Padel Club") { tournament.isPrivate = false do { try dataStore.tournaments.addOrUpdate(instance: tournament) } catch { Logger.error(error) } } } footer: { Text("Si vous convoquez un tournoi privée, les joueurs n'auront pas le lien pour suivre le tournoi.") .foregroundStyle(.logoRed) } } PlayersWithoutContactView(players: teams.flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank)) let called = teams.filter { tournament.isStartDateIsDifferentThanCallDate($0) == false } let confirmed = teams.filter { $0.confirmed() } let justCalled = teams.filter { $0.called() } let label = "\(justCalled.count.formatted()) / \(teams.count.formatted())" let subtitle = "dont \(called.count.formatted()) au bon horaire" let confirmedLabel = "\(confirmed.count.formatted()) / \(teams.count.formatted())" if teams.isEmpty == false, searchText.isEmpty { Section { LabeledContent { Text(label).font(.title3) } label: { Text("Paire\(justCalled.count.pluralSuffix) convoquée\(justCalled.count.pluralSuffix)") Text(subtitle) } LabeledContent { Text(confirmedLabel).font(.title3) } label: { Text("Paire\(confirmed.count.pluralSuffix) confirmée\(confirmed.count.pluralSuffix)") } } footer: { Text("Vous pouvez filtrer cette liste en appuyant sur ") + Text(Image(systemName: "line.3.horizontal.decrease.circle")) } } if filteredTeams.isEmpty == false { Section { ForEach(filteredTeams) { team in TeamCallView(team: team) { searchText = "" } } } header: { HStack { Text("Paire\(filteredTeams.count.pluralSuffix)") Spacer() Text(filteredTeams.count.formatted()) } } footer: { CallView(teams: filteredTeams) } } else { ContentUnavailableView("Aucune équipe", systemImage: "person.2.slash") } } .toolbar(content: { ToolbarItem(placement: .topBarTrailing) { Menu { Toggle(isOn: $hideConfirmed) { Text("Masquer les confirmées") } Toggle(isOn: $hideSummoned) { Text("Masquer les convoquées") } Toggle(isOn: $hideGoodSummoned) { Text("Masquer les convoquées à la bonne heure") } } label: { LabelFilter() .symbolVariant(anyFilterEnabled ? .fill : .none) } } }) .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always)) .headerProminence(.increased) .navigationTitle("Statut des convocations") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.visible, for: .navigationBar) } } struct CallMenuOptionsView: View { @Environment(\.dismiss) private var dismiss @Environment(Tournament.self) var tournament: Tournament let team: TeamRegistration let action: (() -> Void)? var confirmed: Binding { Binding { team.confirmed() } set: { _ in team.toggleSummonConfirmation() do { try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team) } catch { Logger.error(error) } action?() } } var body: some View { List { Section { TeamRowView(team: team, displayCallDate: true) Toggle(isOn: confirmed) { Text("Confirmation reçue") } if team.expectedSummonDate() != nil { CallView(team: team, displayContext: .menu) } } footer: { CallView(teams: [team]) } Section { NavigationLink { EditingTeamView(team: team) .environment(tournament) } label: { Text("Détails de l'équipe") } } Section { RowButtonView("Effacer la date de convocation", role: .destructive) { team.callDate = nil do { try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team) } catch { Logger.error(error) } action?() dismiss() } } Section { RowButtonView("Indiquer comme convoquée", role: .destructive) { team.callDate = team.initialMatch()?.startDate ?? tournament.startDate do { try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team) } catch { Logger.error(error) } action?() dismiss() } } } .navigationTitle("Options de convocation") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.visible, for: .navigationBar) } }