|
|
|
|
@ -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<TournamentCategory.ID>() |
|
|
|
|
@State private var tournamentLevels = Set<TournamentLevel.ID>() |
|
|
|
|
@State private var tournamentAges = Set<FederalTournamentAge.ID>() |
|
|
|
|
@State private var tournamentTypes = Set<FederalTournamentType.ID>() |
|
|
|
|
@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<UnitLength> { |
|
|
|
|
distanceLimit(distance: distance) |
|
|
|
|
distanceLimit(distance: dataStore.appSettings.distance) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func distanceLimit(distance: Double) -> Measurement<UnitLength> { |
|
|
|
|
@ -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" |
|
|
|
|
|