From af36a6ecc46648cdeed3c04f53a2fd03e44c787e Mon Sep 17 00:00:00 2001 From: Raz Date: Tue, 1 Apr 2025 11:39:16 +0200 Subject: [PATCH] fix tenup stuff and signature stuff --- PadelClub.xcodeproj/project.pbxproj | 24 ++--- PadelClub/Data/CustomUser.swift | 8 ++ .../Data/Federal/FederalTournament.swift | 97 ++++++++++++++++++- PadelClub/Utils/ContactManager.swift | 4 +- .../Utils/Network/NetworkFederalService.swift | 36 +++++-- .../CallMessageCustomizationView.swift | 14 ++- PadelClub/Views/Calling/CallView.swift | 2 +- PadelClub/Views/Calling/SendToAllView.swift | 2 +- .../TournamentGeneralSettingsView.swift | 2 +- 9 files changed, 160 insertions(+), 29 deletions(-) diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index 9c8eac9..d26004a 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -3640,7 +3640,7 @@ CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; @@ -3666,7 +3666,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3686,7 +3686,7 @@ CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; @@ -3711,7 +3711,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3803,7 +3803,7 @@ CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; @@ -3829,7 +3829,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3849,7 +3849,7 @@ CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; @@ -3874,7 +3874,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3895,7 +3895,7 @@ CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; @@ -3918,7 +3918,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3938,7 +3938,7 @@ CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; @@ -3960,7 +3960,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/PadelClub/Data/CustomUser.swift b/PadelClub/Data/CustomUser.swift index 22de699..a1b58e9 100644 --- a/PadelClub/Data/CustomUser.swift +++ b/PadelClub/Data/CustomUser.swift @@ -126,6 +126,14 @@ class CustomUser: BaseCustomUser, UserBase { } } + func getSummonsMessageSignature() -> String? { + if let summonsMessageSignature, summonsMessageSignature.isEmpty == false { + return summonsMessageSignature + } else { + return nil + } + } + // enum CodingKeys: String, CodingKey { // case _id = "id" // case _lastUpdate = "lastUpdate" diff --git a/PadelClub/Data/Federal/FederalTournament.swift b/PadelClub/Data/Federal/FederalTournament.swift index 202a5d7..dc6aef9 100644 --- a/PadelClub/Data/Federal/FederalTournament.swift +++ b/PadelClub/Data/Federal/FederalTournament.swift @@ -50,7 +50,7 @@ struct FederalTournament: Identifiable, Codable { } - let id: Int + let id: String var millesime: Int? var libelle: String? var tmc: Bool? @@ -92,6 +92,101 @@ struct FederalTournament: Identifiable, Codable { var prixEspece: Int? var distanceEnMetres: Double? + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + // Handle id that could be string or int + if let idString = try? container.decode(String.self, forKey: .id) { + id = idString + } else if let idInt = try? container.decode(Int.self, forKey: .id) { + id = String(idInt) + } else { + throw DecodingError.dataCorruptedError(forKey: .id, in: container, + debugDescription: "Expected String or Int for id") + } + + // Regular decoding for simple properties + millesime = try container.decodeIfPresent(Int.self, forKey: .millesime) + libelle = try container.decodeIfPresent(String.self, forKey: .libelle) + tmc = try container.decodeIfPresent(Bool.self, forKey: .tmc) + tarifAdulteChampionnat = try container.decodeIfPresent(Double.self, forKey: .tarifAdulteChampionnat) + type = try container.decodeIfPresent(String.self, forKey: .type) + ageReel = try container.decodeIfPresent(Bool.self, forKey: .ageReel) + naturesTerrains = try container.decodeIfPresent([JSONAny].self, forKey: .naturesTerrains) + idsArbitres = try container.decodeIfPresent([JSONAny].self, forKey: .idsArbitres) + tarifJeuneChampionnat = try container.decodeIfPresent(Double.self, forKey: .tarifJeuneChampionnat) + international = try container.decodeIfPresent(Bool.self, forKey: .international) + inscriptionEnLigne = try container.decodeIfPresent(Bool.self, forKey: .inscriptionEnLigne) + categorieTournoi = try container.decodeIfPresent(CategorieTournoi.self, forKey: .categorieTournoi) + prixLot = try container.decodeIfPresent(Int.self, forKey: .prixLot) + paiementEnLigne = try container.decodeIfPresent(Bool.self, forKey: .paiementEnLigne) + reductionAdherentJeune = try container.decodeIfPresent(Double.self, forKey: .reductionAdherentJeune) + reductionAdherentAdulte = try container.decodeIfPresent(Double.self, forKey: .reductionAdherentAdulte) + paiementEnLigneObligatoire = try container.decodeIfPresent(Bool.self, forKey: .paiementEnLigneObligatoire) + villeEngagement = try container.decodeIfPresent(String.self, forKey: .villeEngagement) + senior = try container.decodeIfPresent(Bool.self, forKey: .senior) + veteran = try container.decodeIfPresent(Bool.self, forKey: .veteran) + inscriptionEnLigneEnCours = try container.decodeIfPresent(Bool.self, forKey: .inscriptionEnLigneEnCours) + avecResultatPublie = try container.decodeIfPresent(Bool.self, forKey: .avecResultatPublie) + code = try container.decodeIfPresent(String.self, forKey: .code) + categorieAge = try container.decodeIfPresent(CategorieAge.self, forKey: .categorieAge) + codeComite = try container.decodeIfPresent(String.self, forKey: .codeComite) + installations = try container.decodeIfPresent([JSONAny].self, forKey: .installations) + reductionEpreuveSupplementaireJeune = try container.decodeIfPresent(Double.self, forKey: .reductionEpreuveSupplementaireJeune) + reductionEpreuveSupplementaireAdulte = try container.decodeIfPresent(Double.self, forKey: .reductionEpreuveSupplementaireAdulte) + nomComite = try container.decodeIfPresent(String.self, forKey: .nomComite) + naturesEpreuves = try container.decodeIfPresent([Serie].self, forKey: .naturesEpreuves) + jeune = try container.decodeIfPresent(Bool.self, forKey: .jeune) + courrielEngagement = try container.decodeIfPresent(String.self, forKey: .courrielEngagement) + nomClub = try container.decodeIfPresent(String.self, forKey: .nomClub) + installation = try container.decodeIfPresent(Installation.self, forKey: .installation) + categorieAgeMax = try container.decodeIfPresent(CategorieAge.self, forKey: .categorieAgeMax) + tournoiInterne = try container.decodeIfPresent(Bool.self, forKey: .tournoiInterne) + nomLigue = try container.decodeIfPresent(String.self, forKey: .nomLigue) + nomEngagement = try container.decodeIfPresent(String.self, forKey: .nomEngagement) + codeLigue = try container.decodeIfPresent(String.self, forKey: .codeLigue) + modeleDeBalle = try container.decodeIfPresent(ModeleDeBalle.self, forKey: .modeleDeBalle) + jugeArbitre = try container.decodeIfPresent(JugeArbitre.self, forKey: .jugeArbitre) + adresse2Engagement = try container.decodeIfPresent(String.self, forKey: .adresse2Engagement) + epreuves = try container.decodeIfPresent([Epreuve].self, forKey: .epreuves) + serie = try container.decodeIfPresent(Serie.self, forKey: .serie) + codePostalEngagement = try container.decodeIfPresent(String.self, forKey: .codePostalEngagement) + codeClub = try container.decodeIfPresent(String.self, forKey: .codeClub) + prixEspece = try container.decodeIfPresent(Int.self, forKey: .prixEspece) + distanceEnMetres = try container.decodeIfPresent(Double.self, forKey: .distanceEnMetres) + + // Custom decoding for dateDebut + if let dateContainer = try? container.nestedContainer(keyedBy: DateKeys.self, forKey: .dateDebut) { + if let dateString = try? dateContainer.decode(String.self, forKey: .date) { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSSSS" + dateDebut = dateFormatter.date(from: dateString) + } + } + + // Custom decoding for dateFin + if let dateContainer = try? container.nestedContainer(keyedBy: DateKeys.self, forKey: .dateFin) { + if let dateString = try? dateContainer.decode(String.self, forKey: .date) { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSSSS" + dateFin = dateFormatter.date(from: dateString) + } + } + + // Custom decoding for dateValidation + if let dateContainer = try? container.nestedContainer(keyedBy: DateKeys.self, forKey: .dateValidation) { + if let dateString = try? dateContainer.decode(String.self, forKey: .date) { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSSSS" + dateValidation = dateFormatter.date(from: dateString) + } + } + } + + private enum DateKeys: String, CodingKey { + case date + } + var dayPeriod: DayPeriod { if let dateDebut { let day = dateDebut.get(.weekday) diff --git a/PadelClub/Utils/ContactManager.swift b/PadelClub/Utils/ContactManager.swift index 23e0bac..512a939 100644 --- a/PadelClub/Utils/ContactManager.swift +++ b/PadelClub/Utils/ContactManager.swift @@ -91,7 +91,7 @@ Il est conseillé de vous présenter 10 minutes avant de jouer.\n\nMerci de me c text = text.replacingOccurrences(of: "#jour", with: "\(date.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide)))") text = text.replacingOccurrences(of: "#horaire", with: "\(date.formatted(Date.FormatStyle().hour().minute()))") - let signature = DataStore.shared.user.summonsMessageSignature ?? DataStore.shared.user.defaultSignature(tournament) + let signature = DataStore.shared.user.getSummonsMessageSignature() ?? DataStore.shared.user.defaultSignature(tournament) text = text.replacingOccurrences(of: "#signature", with: signature) return text @@ -109,7 +109,7 @@ Il est conseillé de vous présenter 10 minutes avant de jouer.\n\nMerci de me c let clubName = tournament?.clubName ?? "" let message = DataStore.shared.user.summonsMessageBody ?? defaultCustomMessage - let signature = DataStore.shared.user.summonsMessageSignature ?? DataStore.shared.user.defaultSignature(tournament) + let signature = DataStore.shared.user.getSummonsMessageSignature() ?? DataStore.shared.user.defaultSignature(tournament) let localizedCalled = "convoqué" + (tournament?.tournamentCategory == .women ? "e" : "") + "s" diff --git a/PadelClub/Utils/Network/NetworkFederalService.swift b/PadelClub/Utils/Network/NetworkFederalService.swift index 846427b..05eedd9 100644 --- a/PadelClub/Utils/Network/NetworkFederalService.swift +++ b/PadelClub/Utils/Network/NetworkFederalService.swift @@ -33,17 +33,37 @@ class NetworkFederalService { return decoder }() - func runTenupTask(request: URLRequest) async throws -> T { - let task = try await URLSession.shared.data(for: request) - if request.httpMethod == "PUT" { - print("tried PUT: \(request.url!)") - if let urlResponse = task.1 as? HTTPURLResponse { - print(urlResponse.statusCode) + func runTenupTask(request: URLRequest) async throws -> T { + let (data, response) = try await URLSession.shared.data(for: request) + + // Print request info + print("Request: \(request.httpMethod ?? "GET") \(request.url?.absoluteString ?? "")") + + // Print response status + if let httpResponse = response as? HTTPURLResponse { + print("Status code: \(httpResponse.statusCode)") + } + + // Print JSON data before decoding + if let jsonObject = try? JSONSerialization.jsonObject(with: data) { + print("Response JSON: \(jsonObject)") + } else { + print("Response is not a valid JSON") + // Try to print as string if not JSON + if let stringResponse = String(data: data, encoding: .utf8) { + print("Response as string: \(stringResponse)") } } - return try tenupJsonDecoder.decode(T.self, from: task.0) + + // Now try to decode + do { + return try tenupJsonDecoder.decode(T.self, from: data) + } catch { + print("Decoding error: \(error)") + throw error + } } - + func federalClubs(country: String = "fr", city: String, radius: Double, location: CLLocation? = nil) async throws -> FederalClubResponse { /* diff --git a/PadelClub/Views/Calling/CallMessageCustomizationView.swift b/PadelClub/Views/Calling/CallMessageCustomizationView.swift index b7ce6d3..c1979b8 100644 --- a/PadelClub/Views/Calling/CallMessageCustomizationView.swift +++ b/PadelClub/Views/Calling/CallMessageCustomizationView.swift @@ -29,7 +29,7 @@ struct CallMessageCustomizationView: View { init(tournament: Tournament) { self.tournament = tournament _customCallMessageBody = State(wrappedValue: DataStore.shared.user.summonsMessageBody ?? (DataStore.shared.user.summonsUseFullCustomMessage ? "" : ContactType.defaultCustomMessage)) - _customCallMessageSignature = State(wrappedValue: DataStore.shared.user.summonsMessageSignature ?? DataStore.shared.user.defaultSignature(tournament)) + _customCallMessageSignature = State(wrappedValue: DataStore.shared.user.getSummonsMessageSignature() ?? DataStore.shared.user.defaultSignature(tournament)) _customClubName = State(wrappedValue: tournament.clubName ?? "Lieu du tournoi") _summonsAvailablePaymentMethods = State(wrappedValue: DataStore.shared.user.summonsAvailablePaymentMethods ?? ContactType.defaultAvailablePaymentMethods) } @@ -144,8 +144,16 @@ struct CallMessageCustomizationView: View { } private func _save() { - self.dataStore.user.summonsMessageBody = customCallMessageBody - self.dataStore.user.summonsMessageSignature = customCallMessageSignature + if customCallMessageBody.isEmpty { + self.dataStore.user.summonsMessageBody = nil + } else { + self.dataStore.user.summonsMessageBody = customCallMessageBody + } + if customCallMessageSignature.isEmpty { + self.dataStore.user.summonsMessageSignature = nil + } else { + self.dataStore.user.summonsMessageSignature = customCallMessageSignature + } self.dataStore.user.summonsAvailablePaymentMethods = summonsAvailablePaymentMethods self.dataStore.saveUser() } diff --git a/PadelClub/Views/Calling/CallView.swift b/PadelClub/Views/Calling/CallView.swift index cc8e152..4f77917 100644 --- a/PadelClub/Views/Calling/CallView.swift +++ b/PadelClub/Views/Calling/CallView.swift @@ -139,7 +139,7 @@ struct CallView: View { func finalMessage(reSummon: Bool, forcedEmptyMessage: Bool) -> String { if simpleMode || forcedEmptyMessage { - let signature = dataStore.user.summonsMessageSignature ?? dataStore.user.defaultSignature(tournament) + let signature = dataStore.user.getSummonsMessageSignature() ?? dataStore.user.defaultSignature(tournament) return "\n\n\n\n" + signature } diff --git a/PadelClub/Views/Calling/SendToAllView.swift b/PadelClub/Views/Calling/SendToAllView.swift index 91509d6..2cae54d 100644 --- a/PadelClub/Views/Calling/SendToAllView.swift +++ b/PadelClub/Views/Calling/SendToAllView.swift @@ -261,7 +261,7 @@ struct SendToAllView: View { message.append(tournament.shareURL(pageLink)?.absoluteString) } - let signature = dataStore.user.summonsMessageSignature ?? dataStore.user.defaultSignature(tournament) + let signature = dataStore.user.getSummonsMessageSignature() ?? dataStore.user.defaultSignature(tournament) message.append(signature) diff --git a/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift b/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift index ddd76fa..3e90db3 100644 --- a/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift +++ b/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift @@ -338,7 +338,7 @@ struct TournamentGeneralSettingsView: View { .onSubmit { _confirmUmpireContact() } - if dataStore.user.summonsMessageSignature != nil, umpireCustomContact != dataStore.user.fullName() { + if dataStore.user.getSummonsMessageSignature() != nil, umpireCustomContact != dataStore.user.fullName() { Text("Attention vous avez une signature personnalisée contenant un contact différent.").foregroundStyle(.logoRed) FooterButtonView("retirer la personnalisation ?") {