diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index eaa172f..2fa8afd 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -1148,6 +1148,10 @@ extension Tournament: FederalTournamentHolder { } extension Tournament: TournamentBuildHolder { + func buildHolderTitle() -> String { + tournamentTitle() + } + var category: TournamentCategory { tournamentCategory } diff --git a/PadelClub/Manager/Network/NetworkFederalService.swift b/PadelClub/Manager/Network/NetworkFederalService.swift index 1a3be1b..666b049 100644 --- a/PadelClub/Manager/Network/NetworkFederalService.swift +++ b/PadelClub/Manager/Network/NetworkFederalService.swift @@ -92,7 +92,7 @@ class NetworkFederalService { } - func getClubFederalTournaments(page: Int, tournaments: [FederalTournament], club: String, codeClub: String, startDate: Date? = nil) async throws -> [FederalTournament] { + func getClubFederalTournaments(page: Int, tournaments: [FederalTournament], club: String, codeClub: String, startDate: Date? = nil, endDate: Date? = nil) async throws -> [FederalTournament] { if formId.isEmpty { do { @@ -103,8 +103,10 @@ class NetworkFederalService { } var dateComponent = "" - if let startDate { - dateComponent = "&date[start]=\(startDate.twoDigitsYearFormatted)" + if let startDate, let endDate { + dateComponent = "&date[start]=\(startDate.twoDigitsYearFormatted)&date[end]=\(endDate.endOfMonth.twoDigitsYearFormatted)" + } else if let startDate { + dateComponent = "&date[start]=\(startDate.twoDigitsYearFormatted)&date[end]=\(Calendar.current.date(byAdding: .month, value: 3, to: startDate)!.endOfMonth.twoDigitsYearFormatted)" } let parameters = """ diff --git a/PadelClub/Manager/PadelRule.swift b/PadelClub/Manager/PadelRule.swift index aeeae15..11118db 100644 --- a/PadelClub/Manager/PadelRule.swift +++ b/PadelClub/Manager/PadelRule.swift @@ -29,6 +29,7 @@ protocol TournamentBuildHolder: Identifiable { var category: TournamentCategory { get } var level: TournamentLevel { get } var age: FederalTournamentAge { get } + func buildHolderTitle() -> String } struct TournamentBuild: TournamentBuildHolder, Hashable, Codable, Identifiable { @@ -40,6 +41,10 @@ struct TournamentBuild: TournamentBuildHolder, Hashable, Codable, Identifiable { // var japFirstName: String? = nil // var japLastName: String? = nil + func buildHolderTitle() -> String { + localizedLabel() + } + var identifier: String { level.localizedLabel()+":"+category.localizedLabel()+":"+age.localizedLabel() } diff --git a/PadelClub/ViewModel/NavigationViewModel.swift b/PadelClub/ViewModel/NavigationViewModel.swift index 1a8467e..c0baba7 100644 --- a/PadelClub/ViewModel/NavigationViewModel.swift +++ b/PadelClub/ViewModel/NavigationViewModel.swift @@ -13,4 +13,5 @@ class NavigationViewModel { var selectedTab: TabDestination? var agendaDestination: AgendaDestination? = .activity var tournament: Tournament? + var federalTournaments: [FederalTournament] = [] } diff --git a/PadelClub/Views/Navigation/Agenda/ActivityView.swift b/PadelClub/Views/Navigation/Agenda/ActivityView.swift index 0709773..f86ba1b 100644 --- a/PadelClub/Views/Navigation/Agenda/ActivityView.swift +++ b/PadelClub/Views/Navigation/Agenda/ActivityView.swift @@ -17,10 +17,10 @@ struct ActivityView: View { @State private var presentToolbar: Bool = false @State private var newTournament: Tournament? @State private var viewStyle: AgendaDestination.ViewStyle = .list - @State private var federalTournaments: [FederalTournament] = [] @State private var isGatheringFederalTournaments: Bool = false @State private var error: Error? - + @State private var uuid: UUID = UUID() + var runningTournaments: [FederalTournamentHolder] { dataStore.tournaments.filter({ $0.endDate == nil }) } @@ -46,7 +46,7 @@ struct ActivityView: View { case .history: endedTournaments case .tenup: - federalTournaments + navigation.federalTournaments } } @@ -63,7 +63,8 @@ struct ActivityView: View { case .history: EventListView(tournaments: endedTournaments, viewStyle: viewStyle) case .tenup: - EventListView(tournaments: federalTournaments, viewStyle: viewStyle) + EventListView(tournaments: navigation.federalTournaments, viewStyle: viewStyle) + .id(uuid) } } .overlay { @@ -109,21 +110,22 @@ struct ActivityView: View { } .refreshable { if navigation.agendaDestination == .tenup { - federalTournaments.removeAll() + navigation.federalTournaments.removeAll() + NetworkFederalService.shared.formId = "" _gatherFederalTournaments() } } .task { if navigation.agendaDestination == .tenup && dataStore.clubs.isEmpty == false - && federalTournaments.isEmpty { + && navigation.federalTournaments.isEmpty { _gatherFederalTournaments() } } .onChange(of: navigation.agendaDestination) { if navigation.agendaDestination == .tenup && dataStore.clubs.isEmpty == false - && federalTournaments.isEmpty { + && navigation.federalTournaments.isEmpty { _gatherFederalTournaments() } } @@ -158,17 +160,16 @@ struct ActivityView: View { .frame(minHeight: 28) } .symbolVariant(viewStyle == .calendar ? .fill : .none) - - // - // Button { - // filterEnabled.toggle() - // } label: { - // Image(systemName: "line.3.horizontal.decrease.circle") - // .resizable() - // .scaledToFit() - // .frame(minHeight: 28) - // } - // .symbolVariant(filterEnabled ? .fill : .none) + + Button { + filterEnabled.toggle() + } label: { + Image(systemName: "line.3.horizontal.decrease.circle") + .resizable() + .scaledToFit() + .frame(minHeight: 28) + } + .symbolVariant(filterEnabled ? .fill : .none) } ToolbarItem(placement: .topBarTrailing) { @@ -195,16 +196,23 @@ struct ActivityView: View { private func _gatherFederalTournaments() { isGatheringFederalTournaments = true - NetworkFederalService.shared.formId = "" Task { do { try await dataStore.clubs.filter { $0.code != nil }.concurrentForEach { club in - federalTournaments += try await NetworkFederalService.shared.getClubFederalTournaments(page: 0, tournaments: [], club: club.name, codeClub: club.code!, startDate: .now.startOfMonth) + let newTournaments = try await NetworkFederalService.shared.getClubFederalTournaments(page: 0, tournaments: [], club: club.name, codeClub: club.code!, startDate: .now.startOfMonth) + + newTournaments.forEach { tournament in + if navigation.federalTournaments.contains(where: { $0.id == tournament.id }) == false { + navigation.federalTournaments.append(tournament) + } + } + } } catch { self.error = error } isGatheringFederalTournaments = false + uuid = UUID() } } @@ -269,6 +277,7 @@ struct ActivityView: View { Text("Aucun tournoi n'a pu être récupéré via tenup.") } actions: { RowButtonView("Rafraîchir") { + NetworkFederalService.shared.formId = "" _gatherFederalTournaments() } } diff --git a/PadelClub/Views/Navigation/Agenda/CalendarView.swift b/PadelClub/Views/Navigation/Agenda/CalendarView.swift index acbaa49..18316e1 100644 --- a/PadelClub/Views/Navigation/Agenda/CalendarView.swift +++ b/PadelClub/Views/Navigation/Agenda/CalendarView.swift @@ -13,6 +13,7 @@ import SwiftUI struct CalendarView: View { + @EnvironmentObject var dataStore: DataStore @Environment(NavigationViewModel.self) var navigation: NavigationViewModel let date: Date let tournaments: [FederalTournamentHolder] @@ -67,12 +68,29 @@ struct CalendarView: View { tournament.startDate = day.atNine() newTournament = tournament } + + Divider() - let tournamentsByDay = tournaments.filter { $0.startDate.dayInt == day.dayInt } + let tournamentsByDay = tournaments.filter { day.dayInt >= $0.startDate.dayInt && day.dayInt < $0.startDate.dayInt + $0.dayDuration } ForEach(tournamentsByDay, id: \.holderId) { tournamentHolder in if let tournament = tournamentHolder as? Tournament { - Button(tournament.tournamentTitle()) { - navigation.path.append(tournament) + Section { + Button(tournament.tournamentTitle()) { + navigation.path.append(tournament) + } + } header: { + Text("sur " + tournament.dayDuration.formatted() + " jour" + tournament.dayDuration.pluralSuffix) + } + } else if let tournament = tournamentHolder as? FederalTournament { + Menu { + ForEach(tournament.tournaments, id: \.id) { build in + Button(build.buildHolderTitle()) { + _createOrShow(federalTournament: tournament, existingTournament: event(forTournament: tournament)?.existingBuild(build), build: build) + } + } + } label: { + Text(tournament.clubLabel()) + Text("sur " + tournament.dayDuration.formatted() + " jour" + tournament.dayDuration.pluralSuffix) } } } @@ -116,6 +134,34 @@ struct CalendarView: View { } counts = Dictionary(mappedItems, uniquingKeysWith: +) } + + func event(forTournament tournament: FederalTournamentHolder) -> Event? { + guard let federalTournament = tournament as? FederalTournament else { return nil } + return dataStore.events.first(where: { $0.tenupId == federalTournament.id.string }) + } + + private func _createOrShow(federalTournament: FederalTournament, existingTournament: Tournament?, build: any TournamentBuildHolder) { + if let existingTournament { + navigation.agendaDestination = .activity + navigation.path.append(existingTournament) + } else { + let event = federalTournament.getEvent() + let newTournament = Tournament.newEmptyInstance() + newTournament.event = event.id + //todo + //newTournament.umpireMail() + //newTournament.jsonData = jsonData + newTournament.tournamentLevel = build.level + newTournament.tournamentCategory = build.category + newTournament.federalTournamentAge = build.age + newTournament.dayDuration = federalTournament.dayDuration + newTournament.startDate = federalTournament.startDate.atBeginningOfDay(hourInt: 9) + newTournament.setupFederalSettings() + try? dataStore.tournaments.addOrUpdate(instance: newTournament) + navigation.path.append(newTournament) + } + } + } #Preview { diff --git a/PadelClub/Views/Navigation/Agenda/EventListView.swift b/PadelClub/Views/Navigation/Agenda/EventListView.swift index eb661cf..2a272e0 100644 --- a/PadelClub/Views/Navigation/Agenda/EventListView.swift +++ b/PadelClub/Views/Navigation/Agenda/EventListView.swift @@ -9,23 +9,21 @@ import SwiftUI struct EventListView: View { @EnvironmentObject var dataStore: DataStore - + @Environment(NavigationViewModel.self) var navigation: NavigationViewModel + let tournaments: [FederalTournamentHolder] let viewStyle: AgendaDestination.ViewStyle - + var groupedTournamentsByDate: Dictionary { + Dictionary(grouping: navigation.agendaDestination == .tenup ? navigation.federalTournaments : tournaments) { $0.startDate.startOfMonth } + } + var body: some View { - let groupedTournamentsByDate = Dictionary(grouping: tournaments) { $0.startDate.startOfMonth } switch viewStyle { case .list: ForEach(groupedTournamentsByDate.keys.sorted(by: <), id: \.self) { section in if let _tournaments = groupedTournamentsByDate[section]?.sorted(by: \.startDate) { Section { - switch viewStyle { - case .list: - _listView(_tournaments) - case .calendar: - CalendarView(date: section, tournaments: _tournaments) - } + _listView(_tournaments) } header: { HStack { Text(section.monthYearFormatted) @@ -51,7 +49,34 @@ struct EventListView: View { } } .headerProminence(.increased) + .task { + if navigation.agendaDestination == .tenup + && dataStore.clubs.isEmpty == false + && _tournaments.isEmpty { + _gatherFederalTournaments(startDate: section) + } + } + } + } + } + + private func _gatherFederalTournaments(startDate: Date) { +// isGatheringFederalTournaments = true + Task { + do { + try await dataStore.clubs.filter { $0.code != nil }.concurrentForEach { club in + let newTournaments = try await NetworkFederalService.shared.getClubFederalTournaments(page: 0, tournaments: [], club: club.name, codeClub: club.code!, startDate: startDate, endDate: startDate.endOfMonth) + + newTournaments.forEach { tournament in + if navigation.federalTournaments.contains(where: { $0.id == tournament.id }) == false { + navigation.federalTournaments.append(tournament) + } + } + } + } catch { +// self.error = error } +// isGatheringFederalTournaments = false } }