diff --git a/PadelClub/Data/AppSettings.swift b/PadelClub/Data/AppSettings.swift index 6f08933..60be3e3 100644 --- a/PadelClub/Data/AppSettings.swift +++ b/PadelClub/Data/AppSettings.swift @@ -16,8 +16,48 @@ final class AppSettings: MicroStorable { var didCreateAccount: Bool = false var didRegisterAccount: Bool = false + //search tournament stuff + var tournamentCategories: Set + var tournamentLevels: Set + var tournamentAges: Set + var tournamentTypes: Set + var startDate: Date + var endDate: Date + var city: String + var distance: Double + var sortingOption: String + var nationalCup: Bool + var dayDuration: Int? + var dayPeriod: DayPeriod + + func resetSearch() { + tournamentAges = Set() + tournamentTypes = Set() + tournamentLevels = Set() + tournamentCategories = Set() + city = "" + distance = 30 + startDate = Date() + endDate = Calendar.current.date(byAdding: .month, value: 3, to: Date())! + sortingOption = "dateDebut+asc" + nationalCup = false + dayDuration = nil + dayPeriod = .all + } + required init() { - + tournamentAges = Set() + tournamentTypes = Set() + tournamentLevels = Set() + tournamentCategories = Set() + city = "" + distance = 30 + startDate = Date() + endDate = Calendar.current.date(byAdding: .month, value: 3, to: Date())! + sortingOption = "dateDebut+asc" + nationalCup = false + dayDuration = nil + dayPeriod = .all } required init(from decoder: Decoder) throws { @@ -25,11 +65,35 @@ final class AppSettings: MicroStorable { lastDataSource = try container.decodeIfPresent(String.self, forKey: ._lastDataSource) didCreateAccount = try container.decodeIfPresent(Bool.self, forKey: ._didCreateAccount) ?? false didRegisterAccount = try container.decodeIfPresent(Bool.self, forKey: ._didRegisterAccount) ?? false + tournamentCategories = try container.decodeIfPresent(Set.self, forKey: ._tournamentCategories) ?? Set() + tournamentLevels = try container.decodeIfPresent(Set.self, forKey: ._tournamentLevels) ?? Set() + tournamentAges = try container.decodeIfPresent(Set.self, forKey: ._tournamentAges) ?? Set() + tournamentTypes = try container.decodeIfPresent(Set.self, forKey: ._tournamentTypes) ?? Set() + startDate = try container.decodeIfPresent(Date.self, forKey: ._startDate) ?? Date() + endDate = try container.decodeIfPresent(Date.self, forKey: ._endDate) ?? Calendar.current.date(byAdding: .month, value: 3, to: Date())! + city = try container.decodeIfPresent(String.self, forKey: ._city) ?? "" + distance = try container.decodeIfPresent(Double.self, forKey: ._distance) ?? 30 + sortingOption = try container.decodeIfPresent(String.self, forKey: ._sortingOption) ?? "dateDebut+asc" + nationalCup = try container.decodeIfPresent(Bool.self, forKey: ._nationalCup) ?? false + dayDuration = try container.decodeIfPresent(Int.self, forKey: ._dayDuration) + dayPeriod = try container.decodeIfPresent(DayPeriod.self, forKey: ._dayPeriod) ?? .all } enum CodingKeys: String, CodingKey { case _lastDataSource = "lastDataSource" case _didCreateAccount = "didCreateAccount" case _didRegisterAccount = "didRegisterAccount" + case _tournamentCategories = "tournamentCategories" + case _tournamentLevels = "tournamentLevels" + case _tournamentAges = "tournamentAges" + case _tournamentTypes = "tournamentTypes" + case _startDate = "startDate" + case _endDate = "endDate" + case _city = "city" + case _distance = "distance" + case _sortingOption = "sortingOption" + case _nationalCup = "nationalCup" + case _dayDuration = "dayDuration" + case _dayPeriod = "dayPeriod" } } diff --git a/PadelClub/Data/Federal/FederalTournament.swift b/PadelClub/Data/Federal/FederalTournament.swift index 16360ce..63595b5 100644 --- a/PadelClub/Data/Federal/FederalTournament.swift +++ b/PadelClub/Data/Federal/FederalTournament.swift @@ -7,8 +7,8 @@ import Foundation import CoreLocation import LeStorage -enum DayPeriod: CaseIterable, Identifiable { - var id: Self { self } +enum DayPeriod: Int, CaseIterable, Identifiable, Codable { + var id: Int { self.rawValue } case all case weekend diff --git a/PadelClub/Views/Club/ClubSearchView.swift b/PadelClub/Views/Club/ClubSearchView.swift index cda6c72..fc022f1 100644 --- a/PadelClub/Views/Club/ClubSearchView.swift +++ b/PadelClub/Views/Club/ClubSearchView.swift @@ -140,7 +140,6 @@ struct ClubSearchView: View { RowButtonView("D'accord") { locationManager.lastError = nil } - .padding(.horizontal) } } else if clubMarkers.isEmpty == false && searching == false && _filteredClubs().isEmpty { ContentUnavailableView.search(text: searchedCity) @@ -172,7 +171,6 @@ struct ClubSearchView: View { locationManager.requestLocation() } } - .padding(.horizontal) } if error != nil { @@ -184,13 +182,11 @@ struct ClubSearchView: View { RowButtonView("Chercher une ville ou un code postal") { searchPresented = true } - .padding(.horizontal) if searchAttempted { RowButtonView("Créer un club manuellement") { newClub = club ?? Club.newEmptyInstance() } - .padding(.horizontal) } } } diff --git a/PadelClub/Views/Club/ClubsView.swift b/PadelClub/Views/Club/ClubsView.swift index 041f4ca..b5ea93e 100644 --- a/PadelClub/Views/Club/ClubsView.swift +++ b/PadelClub/Views/Club/ClubsView.swift @@ -159,11 +159,9 @@ struct ClubsView: View { RowButtonView("Créer un nouveau club", systemImage: "plus.circle.fill") { newClub = Club.newEmptyInstance() } - .padding(.horizontal) RowButtonView("Chercher un club", systemImage: "magnifyingglass.circle.fill") { presentClubSearchView = true } - .padding(.horizontal) } } diff --git a/PadelClub/Views/GroupStage/LoserBracketFromGroupStageView.swift b/PadelClub/Views/GroupStage/LoserBracketFromGroupStageView.swift index 08efa0e..776e75f 100644 --- a/PadelClub/Views/GroupStage/LoserBracketFromGroupStageView.swift +++ b/PadelClub/Views/GroupStage/LoserBracketFromGroupStageView.swift @@ -81,7 +81,6 @@ struct LoserBracketFromGroupStageView: View { isEditingLoserBracketGroupStage = true _addNewMatch() } - .padding(.horizontal) } } } diff --git a/PadelClub/Views/Navigation/Agenda/ActivityView.swift b/PadelClub/Views/Navigation/Agenda/ActivityView.swift index 596b360..835c9cd 100644 --- a/PadelClub/Views/Navigation/Agenda/ActivityView.swift +++ b/PadelClub/Views/Navigation/Agenda/ActivityView.swift @@ -122,7 +122,6 @@ struct ActivityView: View { RowButtonView("D'accord.") { self.error = nil } - .padding(.horizontal) } } else if isGatheringFederalTournaments { ProgressView() @@ -139,11 +138,9 @@ struct ActivityView: View { FooterButtonView("supprimer vos filtres") { federalDataViewModel.removeFilters() } - .padding(.horizontal) FooterButtonView("modifier vos filtres") { presentFilterView = true } - .padding(.horizontal) } } else { _dataEmptyView() @@ -403,13 +400,10 @@ struct ActivityView: View { RowButtonView("Créer un nouvel événement") { newTournament = Tournament.newEmptyInstance() } - .padding(.horizontal) RowButtonView("Importer via Tenup") { navigation.agendaDestination = .tenup } - .padding(.horizontal) SupportButtonView(contentIsUnavailable: true) - .padding(.horizontal) } } diff --git a/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift b/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift index d4e8ca7..2f64f44 100644 --- a/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift +++ b/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift @@ -10,6 +10,7 @@ import CoreLocation import CoreLocationUI struct TournamentLookUpView: View { + @EnvironmentObject var dataStore: DataStore @Environment(FederalDataViewModel.self) var federalDataViewModel: FederalDataViewModel @StateObject var locationManager = LocationManager() @Environment(\.dismiss) private var dismiss @@ -18,19 +19,8 @@ struct TournamentLookUpView: View { @State var page: Int = 0 @State var total: Int = 0 - @State private var tournamentCategories = Set() - @State private var tournamentLevels = Set() - @State private var tournamentAges = Set() - @State private var tournamentTypes = Set() @State private var searching: Bool = false - @State private var startDate: Date = Date() - @State private var endDate: Date = Calendar.current.date(byAdding: .month, value: 3, to: Date())! - @AppStorage("lastCity") private var city: String = "" - @State private var ligue: String = "" - @State private var distance: Double = 30 - @State private var sortingOption: String = "dateDebut+asc" @State private var requestedToGetAllPages: Bool = false - @State private var nationalCup: Bool = false @State private var revealSearchParameters: Bool = true @State private var presentAlert: Bool = false @@ -61,14 +51,18 @@ struct TournamentLookUpView: View { presentAlert = false } }, message: { - Text("Il y a beacoup de tournois pour cette requête, êtes-vous sûr de vouloir tout récupérer ? Sinon essayez d'affiner votre recherche.") + if dataStore.appSettings.city.isEmpty { + Text("Il est préférable de se localiser ou d'indiquer une ville pour réduire le nombre de résultat.") + } else { + Text("Il y a beacoup de tournois pour cette requête, êtes-vous sûr de vouloir tout récupérer ? Sinon essayez d'affiner votre recherche.") + } }) .toolbarBackground(.visible, for: .bottomBar, .navigationBar) .navigationTitle("Chercher un tournoi") .navigationBarTitleDisplayMode(.inline) .onChange(of: locationManager.city) { - if let newValue = locationManager.city, city.isEmpty { - city = newValue + if let newValue = locationManager.city, dataStore.appSettings.city.isEmpty { + dataStore.appSettings.city = newValue } } .toolbarTitleDisplayMode(.large) @@ -113,15 +107,9 @@ struct TournamentLookUpView: View { #endif Button(role: .destructive) { - tournamentLevels = Set() - tournamentCategories = Set() - city = "" + dataStore.appSettings.resetSearch() locationManager.location = nil locationManager.city = nil - distance = 30 - startDate = Date() - endDate = Calendar.current.date(byAdding: .month, value: 3, to: Date())! - sortingOption = "dateDebut+asc" revealSearchParameters = true federalDataViewModel.searchedFederalTournaments = [] federalDataViewModel.searchAttemptCount = 0 @@ -151,6 +139,7 @@ struct TournamentLookUpView: View { } private func runSearch() { + dataStore.appSettingsStorage.write() revealSearchParameters = false total = 0 page = 0 @@ -158,6 +147,9 @@ struct TournamentLookUpView: View { searching = true requestedToGetAllPages = false federalDataViewModel.searchAttemptCount += 1 + federalDataViewModel.dayPeriod = dataStore.appSettings.dayPeriod + federalDataViewModel.dayDuration = dataStore.appSettings.dayDuration + Task { await getNewPage() searching = false @@ -170,7 +162,7 @@ struct TournamentLookUpView: View { } private var distanceLimit: Measurement { - distanceLimit(distance: distance) + distanceLimit(distance: dataStore.appSettings.distance) } private func distanceLimit(distance: Double) -> Measurement { @@ -178,19 +170,19 @@ struct TournamentLookUpView: View { } private var categories: [TournamentCategory] { - tournamentCategories.compactMap { TournamentCategory(rawValue: $0) } + dataStore.appSettings.tournamentCategories.compactMap { TournamentCategory(rawValue: $0) } } private var levels: [TournamentLevel] { - tournamentLevels.compactMap { TournamentLevel(rawValue: $0) } + dataStore.appSettings.tournamentLevels.compactMap { TournamentLevel(rawValue: $0) } } private var ages: [FederalTournamentAge] { - tournamentAges.compactMap { FederalTournamentAge(rawValue: $0) } + dataStore.appSettings.tournamentAges.compactMap { FederalTournamentAge(rawValue: $0) } } private var types: [FederalTournamentType] { - tournamentTypes.compactMap { FederalTournamentType(rawValue: $0) } + dataStore.appSettings.tournamentTypes.compactMap { FederalTournamentType(rawValue: $0) } } func getNewPage() async { @@ -198,7 +190,7 @@ struct TournamentLookUpView: View { if NetworkFederalService.shared.formId.isEmpty { await getNewBuildForm() } else { - let commands = try await NetworkFederalService.shared.getAllFederalTournaments(sortingOption: sortingOption, page: page, startDate: startDate, endDate: endDate, city: city, distance: distance, categories: categories, levels: levels, lat: locationManager.location?.coordinate.latitude.formatted(.number.locale(Locale(identifier: "us"))), lng: locationManager.location?.coordinate.longitude.formatted(.number.locale(Locale(identifier: "us"))), ages: ages, types: types, nationalCup: nationalCup) + let commands = try await NetworkFederalService.shared.getAllFederalTournaments(sortingOption: dataStore.appSettings.sortingOption, page: page, startDate: dataStore.appSettings.startDate, endDate: dataStore.appSettings.endDate, city: dataStore.appSettings.city, distance: dataStore.appSettings.distance, categories: categories, levels: levels, lat: locationManager.location?.coordinate.latitude.formatted(.number.locale(Locale(identifier: "us"))), lng: locationManager.location?.coordinate.longitude.formatted(.number.locale(Locale(identifier: "us"))), ages: ages, types: types, nationalCup: dataStore.appSettings.nationalCup) let resultCommand = commands.first(where: { $0.results != nil }) if let newTournaments = resultCommand?.results?.items { newTournaments.forEach { ft in @@ -253,15 +245,9 @@ struct TournamentLookUpView: View { } } Button { - tournamentLevels = Set() - tournamentCategories = Set() - city = "" + dataStore.appSettings.resetSearch() locationManager.location = nil locationManager.city = nil - distance = 30 - startDate = Date() - endDate = Calendar.current.date(byAdding: .month, value: 3, to: Date())! - sortingOption = "dateDebut+asc" revealSearchParameters = true } label: { Label("Ré-initialiser la recherche", systemImage: "xmark.circle") @@ -271,12 +257,12 @@ struct TournamentLookUpView: View { @ViewBuilder var searchParametersView: some View { - @Bindable var federalDataViewModel = federalDataViewModel + @Bindable var appSettings = dataStore.appSettings Section { - DatePicker("Début", selection: $startDate, displayedComponents: .date) - DatePicker("Fin", selection: $endDate, displayedComponents: .date) - Picker(selection: $federalDataViewModel.dayDuration) { - Text("aucune").tag(nil as Int?) + DatePicker("Début", selection: $appSettings.startDate, displayedComponents: .date) + DatePicker("Fin", selection: $appSettings.endDate, displayedComponents: .date) + Picker(selection: $appSettings.dayDuration) { + Text("Aucune").tag(nil as Int?) Text(1.formatted()).tag(1 as Int?) Text(2.formatted()).tag(2 as Int?) Text(3.formatted()).tag(3 as Int?) @@ -284,16 +270,16 @@ struct TournamentLookUpView: View { Text("Durée max (en jours)") } - Picker(selection: $federalDataViewModel.dayPeriod) { + Picker(selection: $appSettings.dayPeriod) { ForEach(DayPeriod.allCases) { - Text($0.localizedDayPeriodLabel()).tag($0) + Text($0.localizedDayPeriodLabel().capitalized).tag($0) } } label: { Text("En semaine ou week-end") } HStack { - TextField("Ville", text: $city) + TextField("Ville", text: $appSettings.city) if let city = locationManager.city { Divider() Text(city).italic() @@ -311,7 +297,7 @@ struct TournamentLookUpView: View { } } - Picker(selection: $distance) { + Picker(selection: $appSettings.distance) { Text(distanceLimit(distance:30).formatted()).tag(30.0) Text(distanceLimit(distance:50).formatted()).tag(50.0) Text(distanceLimit(distance:60).formatted()).tag(60.0) @@ -324,7 +310,7 @@ struct TournamentLookUpView: View { Text("Distance max") } - Picker(selection: $sortingOption) { + Picker(selection: $appSettings.sortingOption) { Text("Distance").tag("_DIST_") Text("Date de début").tag("dateDebut+asc") Text("Date de fin").tag("dateFin+asc") @@ -333,7 +319,7 @@ struct TournamentLookUpView: View { } NavigationLink { - List(TournamentCategory.allCases, selection: $tournamentCategories) { type in + List([TournamentCategory.men, TournamentCategory.women, TournamentCategory.mix], selection: $appSettings.tournamentCategories) { type in Text(type.localizedLabel()) } .navigationTitle("Catégories") @@ -348,7 +334,7 @@ struct TournamentLookUpView: View { } NavigationLink { - List(TournamentLevel.allCases, selection: $tournamentLevels) { type in + List([TournamentLevel.p25, TournamentLevel.p100, TournamentLevel.p250, TournamentLevel.p500, TournamentLevel.p1000, TournamentLevel.p1500, TournamentLevel.p2000], selection: $appSettings.tournamentLevels) { type in Text(type.localizedLabel()) } .navigationTitle("Niveaux") @@ -363,7 +349,7 @@ struct TournamentLookUpView: View { } NavigationLink { - List(FederalTournamentAge.allCases, selection: $tournamentAges) { type in + List([FederalTournamentAge.senior, FederalTournamentAge.a45, FederalTournamentAge.a55, FederalTournamentAge.a17_18, FederalTournamentAge.a15_16, FederalTournamentAge.a13_14, FederalTournamentAge.a11_12], selection: $appSettings.tournamentAges) { type in Text(type.localizedLabel()) } .navigationTitle("Limites d'âge") @@ -372,7 +358,7 @@ struct TournamentLookUpView: View { HStack { Text("Limite d'âge") Spacer() - if tournamentAges.isEmpty || tournamentAges.count == FederalTournamentAge.allCases.count { + if dataStore.appSettings.tournamentAges.isEmpty || dataStore.appSettings.tournamentAges.count == FederalTournamentAge.allCases.count { Text("Tous les âges") .foregroundStyle(.secondary) } else { @@ -383,7 +369,7 @@ struct TournamentLookUpView: View { } NavigationLink { - List(FederalTournamentType.allCases, selection: $tournamentTypes) { type in + List(FederalTournamentType.allCases, selection: $appSettings.tournamentTypes) { type in Text(type.localizedLabel()) } .navigationTitle("Types de tournoi") @@ -392,7 +378,7 @@ struct TournamentLookUpView: View { HStack { Text("Type de tournoi") Spacer() - if tournamentTypes.isEmpty || tournamentTypes.count == FederalTournamentType.allCases.count { + if dataStore.appSettings.tournamentTypes.isEmpty || dataStore.appSettings.tournamentTypes.count == FederalTournamentType.allCases.count { Text("Tous les types") .foregroundStyle(.secondary) } else { @@ -402,7 +388,7 @@ struct TournamentLookUpView: View { } } - Picker(selection: $nationalCup) { + Picker(selection: $appSettings.nationalCup) { Text("N'importe").tag(false) Text("Uniquement").tag(true) } label: { @@ -416,7 +402,7 @@ struct TournamentLookUpView: View { } var categoriesLabel: some View { - if tournamentCategories.isEmpty || tournamentCategories.count == TournamentCategory.allCases.count { + if dataStore.appSettings.tournamentCategories.isEmpty || dataStore.appSettings.tournamentCategories.count == TournamentCategory.allCases.count { Text("Toutes les catégories") } else { Text(categories.map({ $0.localizedLabel() }).joined(separator: ", ")) @@ -424,7 +410,7 @@ struct TournamentLookUpView: View { } var levelsLabel: some View { - if tournamentLevels.isEmpty || tournamentLevels.count == TournamentLevel.allCases.count { + if dataStore.appSettings.tournamentLevels.isEmpty || dataStore.appSettings.tournamentLevels.count == TournamentLevel.allCases.count { Text("Tous les niveaux") } else { Text(levels.map({ $0.localizedLabel() }).joined(separator: ", ")) @@ -437,8 +423,8 @@ struct TournamentLookUpView: View { HStack { Text("Lieu") Spacer() - Text(city) - if distance >= 3000 { + Text(dataStore.appSettings.city) + if dataStore.appSettings.distance >= 3000 { Text("sans limite de distance") } else { Text("à moins de " + distanceLimit.formatted()) @@ -448,9 +434,9 @@ struct TournamentLookUpView: View { Text("Période") Spacer() Text("Du") - Text(startDate.twoDigitsYearFormatted) + Text(dataStore.appSettings.startDate.twoDigitsYearFormatted) Text("Au") - Text(endDate.twoDigitsYearFormatted) + Text(dataStore.appSettings.endDate.twoDigitsYearFormatted) } HStack { Text("Niveau") @@ -472,7 +458,7 @@ struct TournamentLookUpView: View { } var sortingOptionLabel: String { - switch sortingOption { + switch dataStore.appSettings.sortingOption { case "_DIST_": return "Distance" case "dateDebut+asc": return "Date de début" case "dateFin+asc": return "Date de fin" diff --git a/PadelClub/Views/Planning/CourtAvailabilitySettingsView.swift b/PadelClub/Views/Planning/CourtAvailabilitySettingsView.swift index 31b14ea..9ade115 100644 --- a/PadelClub/Views/Planning/CourtAvailabilitySettingsView.swift +++ b/PadelClub/Views/Planning/CourtAvailabilitySettingsView.swift @@ -114,7 +114,6 @@ struct CourtAvailabilitySettingsView: View { endDate = tournament.startDate.addingTimeInterval(5400) showingPopover = true } - .padding(.horizontal) } } } diff --git a/PadelClub/Views/Planning/PlanningByCourtView.swift b/PadelClub/Views/Planning/PlanningByCourtView.swift index ba1bdef..96302fd 100644 --- a/PadelClub/Views/Planning/PlanningByCourtView.swift +++ b/PadelClub/Views/Planning/PlanningByCourtView.swift @@ -51,7 +51,6 @@ struct PlanningByCourtView: View { RowButtonView("Horaire intelligent") { selectedScheduleDestination = nil } - .padding(.horizontal) } } } diff --git a/PadelClub/Views/Planning/PlanningView.swift b/PadelClub/Views/Planning/PlanningView.swift index 1e0c0fc..e490a08 100644 --- a/PadelClub/Views/Planning/PlanningView.swift +++ b/PadelClub/Views/Planning/PlanningView.swift @@ -40,7 +40,6 @@ struct PlanningView: View { RowButtonView("Horaire intelligent") { selectedScheduleDestination = nil } - .padding(.horizontal) } } } diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index e656aea..58f26f4 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -224,14 +224,11 @@ struct InscriptionManagerView: View { RowButtonView("Ajouter une équipe") { presentAddTeamView = true } - .padding(.horizontal) RowButtonView("Importer un fichier") { presentImportView = true } - .padding(.horizontal) } - .padding() } } }