From 5f0eaa156bf3c6810f4b2137456fb448231926b8 Mon Sep 17 00:00:00 2001 From: Raz Date: Mon, 2 Dec 2024 10:43:10 +0100 Subject: [PATCH] wip online reg --- PadelClub.xcodeproj/project.pbxproj | 8 ++-- PadelClub/Data/Tournament.swift | 43 ++++++++++++------- PadelClub/Extensions/String+Extensions.swift | 4 ++ PadelClub/Views/Club/ClubDetailView.swift | 4 +- .../TournamentGeneralSettingsView.swift | 35 ++++++++------- .../Screen/TournamentSettingsView.swift | 2 +- PadelClubTests/ServerDataTests.swift | 3 +- 7 files changed, 60 insertions(+), 39 deletions(-) diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index 1464dc8..a7e9392 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -3527,7 +3527,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\""; @@ -3549,7 +3549,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.24; + MARKETING_VERSION = 1.0.34; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3569,7 +3569,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; @@ -3590,7 +3590,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.24; + MARKETING_VERSION = 1.0.34; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 40a8aeb..317e06c 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -70,8 +70,7 @@ final class Tournament : ModelObject, Storable { var minimumPlayerPerTeam: Int = 2 var maximumPlayerPerTeam: Int = 2 var information: String? = nil - var displayEntryFeeInformation: Bool = false - + @ObservationIgnored var navigationPath: [Screen] = [] @@ -122,16 +121,20 @@ final class Tournament : ModelObject, Storable { case _loserBracketMode = "loserBracketMode" case _initialSeedRound = "initialSeedRound" case _initialSeedCount = "initialSeedCount" - case _accountIsRequired = "account_is_required" - case _licenseIsRequired = "license_is_required" - case _minimumPlayerPerTeam = "minimum_player_per_team" - case _maximumPlayerPerTeam = "maximum_player_per_team" + case _enableOnlineRegistration = "enableOnlineRegistration" + case _registrationDateLimit = "registrationDateLimit" + case _openingRegistrationDate = "openingRegistrationDate" + case _targetTeamCount = "targetTeamCount" + case _waitingListLimit = "waitingListLimit" + case _accountIsRequired = "accountIsRequired" + case _licenseIsRequired = "licenseIsRequired" + case _minimumPlayerPerTeam = "minimumPlayerPerTeam" + case _maximumPlayerPerTeam = "maximumPlayerPerTeam" case _information = "information" - case _displayEntryFeeInformation = "displayEntryFeeInformation" } - internal init(event: String? = nil, name: String? = nil, startDate: Date = Date(), endDate: Date? = nil, creationDate: Date = Date(), isPrivate: Bool = false, groupStageFormat: MatchFormat? = nil, roundFormat: MatchFormat? = nil, loserRoundFormat: MatchFormat? = nil, groupStageSortMode: GroupStageOrderingMode, groupStageCount: Int = 4, rankSourceDate: Date? = nil, dayDuration: Int = 1, teamCount: Int = 24, teamSorting: TeamSortingType? = nil, federalCategory: TournamentCategory, federalLevelCategory: TournamentLevel, federalAgeCategory: FederalTournamentAge, closedRegistrationDate: Date? = nil, groupStageAdditionalQualified: Int = 0, courtCount: Int = 2, prioritizeClubMembers: Bool = false, qualifiedPerGroupStage: Int = 1, teamsPerGroupStage: Int = 4, entryFee: Double? = nil, additionalEstimationDuration: Int = 0, isDeleted: Bool = false, publishTeams: Bool = false, publishSummons: Bool = false, publishGroupStages: Bool = false, publishBrackets: Bool = false, shouldVerifyBracket: Bool = false, shouldVerifyGroupStage: Bool = false, hideTeamsWeight: Bool = false, publishTournament: Bool = false, hidePointsEarned: Bool = false, publishRankings: Bool = false, loserBracketMode: LoserBracketMode = .automatic, initialSeedRound: Int = 0, initialSeedCount: Int = 0, accountIsRequired: Bool = true, licenseIsRequired: Bool = true, minimumPlayerPerTeam: Int = 2, maximumPlayerPerTeam: Int = 2, information: String? = nil, displayEntryFeeInformation: Bool = false) { + internal init(event: String? = nil, name: String? = nil, startDate: Date = Date(), endDate: Date? = nil, creationDate: Date = Date(), isPrivate: Bool = false, groupStageFormat: MatchFormat? = nil, roundFormat: MatchFormat? = nil, loserRoundFormat: MatchFormat? = nil, groupStageSortMode: GroupStageOrderingMode, groupStageCount: Int = 4, rankSourceDate: Date? = nil, dayDuration: Int = 1, teamCount: Int = 24, teamSorting: TeamSortingType? = nil, federalCategory: TournamentCategory, federalLevelCategory: TournamentLevel, federalAgeCategory: FederalTournamentAge, closedRegistrationDate: Date? = nil, groupStageAdditionalQualified: Int = 0, courtCount: Int = 2, prioritizeClubMembers: Bool = false, qualifiedPerGroupStage: Int = 1, teamsPerGroupStage: Int = 4, entryFee: Double? = nil, additionalEstimationDuration: Int = 0, isDeleted: Bool = false, publishTeams: Bool = false, publishSummons: Bool = false, publishGroupStages: Bool = false, publishBrackets: Bool = false, shouldVerifyBracket: Bool = false, shouldVerifyGroupStage: Bool = false, hideTeamsWeight: Bool = false, publishTournament: Bool = false, hidePointsEarned: Bool = false, publishRankings: Bool = false, loserBracketMode: LoserBracketMode = .automatic, initialSeedRound: Int = 0, initialSeedCount: Int = 0, enableOnlineRegistration: Bool = false, registrationDateLimit: Date? = nil, openingRegistrationDate: Date? = nil, targetTeamCount: Int? = nil, waitingListLimit: Int? = nil, accountIsRequired: Bool = true, licenseIsRequired: Bool = true, minimumPlayerPerTeam: Int = 2, maximumPlayerPerTeam: Int = 2, information: String? = nil) { self.event = event self.name = name self.startDate = startDate @@ -185,14 +188,17 @@ final class Tournament : ModelObject, Storable { self.loserBracketMode = loserBracketMode self.initialSeedRound = initialSeedRound self.initialSeedCount = initialSeedCount - + self.enableOnlineRegistration = enableOnlineRegistration + self.registrationDateLimit = registrationDateLimit + self.openingRegistrationDate = openingRegistrationDate + self.targetTeamCount = targetTeamCount + self.waitingListLimit = waitingListLimit + self.accountIsRequired = accountIsRequired self.licenseIsRequired = licenseIsRequired self.minimumPlayerPerTeam = minimumPlayerPerTeam self.maximumPlayerPerTeam = maximumPlayerPerTeam self.information = information - self.displayEntryFeeInformation = displayEntryFeeInformation - } required init(from decoder: Decoder) throws { @@ -240,15 +246,17 @@ final class Tournament : ModelObject, Storable { loserBracketMode = try container.decodeIfPresent(LoserBracketMode.self, forKey: ._loserBracketMode) ?? .automatic initialSeedRound = try container.decodeIfPresent(Int.self, forKey: ._initialSeedRound) ?? 0 initialSeedCount = try container.decodeIfPresent(Int.self, forKey: ._initialSeedCount) ?? 0 - + enableOnlineRegistration = try container.decodeIfPresent(Bool.self, forKey: ._enableOnlineRegistration) ?? false + registrationDateLimit = try container.decodeIfPresent(Date.self, forKey: ._registrationDateLimit) + openingRegistrationDate = try container.decodeIfPresent(Date.self, forKey: ._openingRegistrationDate) + targetTeamCount = try container.decodeIfPresent(Int.self, forKey: ._targetTeamCount) + waitingListLimit = try container.decodeIfPresent(Int.self, forKey: ._waitingListLimit) accountIsRequired = try container.decodeIfPresent(Bool.self, forKey: ._accountIsRequired) ?? true licenseIsRequired = try container.decodeIfPresent(Bool.self, forKey: ._licenseIsRequired) ?? true minimumPlayerPerTeam = try container.decodeIfPresent(Int.self, forKey: ._minimumPlayerPerTeam) ?? 2 maximumPlayerPerTeam = try container.decodeIfPresent(Int.self, forKey: ._maximumPlayerPerTeam) ?? 2 information = try container.decodeIfPresent(String.self, forKey: ._information) - displayEntryFeeInformation = try container.decodeIfPresent(Bool.self, forKey: ._displayEntryFeeInformation) ?? false - } fileprivate static let _numberFormatter: NumberFormatter = NumberFormatter() @@ -337,12 +345,17 @@ final class Tournament : ModelObject, Storable { try container.encode(loserBracketMode, forKey: ._loserBracketMode) try container.encode(initialSeedRound, forKey: ._initialSeedRound) try container.encode(initialSeedCount, forKey: ._initialSeedCount) + try container.encode(enableOnlineRegistration, forKey: ._enableOnlineRegistration) + try container.encodeIfPresent(registrationDateLimit, forKey: ._registrationDateLimit) + try container.encodeIfPresent(openingRegistrationDate, forKey: ._openingRegistrationDate) + try container.encodeIfPresent(targetTeamCount, forKey: ._targetTeamCount) + try container.encodeIfPresent(waitingListLimit, forKey: ._waitingListLimit) + try container.encode(accountIsRequired, forKey: ._accountIsRequired) try container.encode(licenseIsRequired, forKey: ._licenseIsRequired) try container.encode(minimumPlayerPerTeam, forKey: ._minimumPlayerPerTeam) try container.encode(maximumPlayerPerTeam, forKey: ._maximumPlayerPerTeam) try container.encode(information, forKey: ._information) - try container.encode(displayEntryFeeInformation, forKey: ._displayEntryFeeInformation) } fileprivate func _encodePayment(container: inout KeyedEncodingContainer) throws { diff --git a/PadelClub/Extensions/String+Extensions.swift b/PadelClub/Extensions/String+Extensions.swift index 37094b9..491f0c6 100644 --- a/PadelClub/Extensions/String+Extensions.swift +++ b/PadelClub/Extensions/String+Extensions.swift @@ -18,6 +18,10 @@ extension String { String(trimmed.prefix(length)) } + func prefixMultilineTrimmed(_ length: Int) -> String { + String(trimmedMultiline.prefix(length)) + } + var trimmed: String { replaceCharactersFromSet(characterSet: .newlines, replacementString: " ").trimmingCharacters(in: .whitespacesAndNewlines) } diff --git a/PadelClub/Views/Club/ClubDetailView.swift b/PadelClub/Views/Club/ClubDetailView.swift index 285c564..a7748ea 100644 --- a/PadelClub/Views/Club/ClubDetailView.swift +++ b/PadelClub/Views/Club/ClubDetailView.swift @@ -135,9 +135,9 @@ struct ClubDetailView: View { .onChange(of: acronymMode) { focusedField = ._acronym if acronymMode == .custom { - club.acronym = "" + //club.acronym = "" } else { - club.acronym = club.automaticShortName().uppercased() + //club.acronym = club.automaticShortName().uppercased() } } } footer: { diff --git a/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift b/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift index 48ce125..30a4a6c 100644 --- a/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift +++ b/PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift @@ -44,11 +44,25 @@ struct TournamentGeneralSettingsView: View { } Section { - TextEditor(text: $tournamentInformation) - .keyboardType(.alphabet) - .focused($focusedField, equals: ._information) + ZStack { + Text(tournamentInformation).opacity(0) + Text(ContactType.defaultCustomMessage).opacity(0) + TextEditor(text: $tournamentInformation) + .keyboardType(.alphabet) + .focused($focusedField, equals: ._information) + } + .frame(maxHeight: 200) + .overlay { + if tournamentInformation.isEmpty { + Text("Texte visible dans l'onglet informations sur Padel Club.").italic() + } + } } header: { Text("Description du tournoi") + } footer: { + FooterButtonView("Ajouter le prix de l'inscription") { + tournamentInformation.append("\n" + tournament.entryFeeMessage) + } } Section { @@ -63,12 +77,6 @@ struct TournamentGeneralSettingsView: View { } label: { Text("Inscription") } - - if tournament.isPrivate == false { - Toggle(isOn: $tournament.displayEntryFeeInformation) { - Text("Afficher sur la page d'infos") - } - } } footer: { Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.") } @@ -141,7 +149,7 @@ struct TournamentGeneralSettingsView: View { if focusedField == ._entryFee { if tournament.isFree() { ForEach(priceTags, id: \.self) { priceTag in - Button(priceTag.formatted(.currency(code: Locale.defaultCurrency()))) { + Button(priceTag.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0)))) { entryFee = priceTag tournament.entryFee = priceTag focusedField = nil @@ -161,14 +169,14 @@ struct TournamentGeneralSettingsView: View { Spacer() Button("Valider") { if focusedField == ._name { - let tournamentName = tournamentName.prefixTrimmed(200) + let tournamentName = tournamentName.prefixMultilineTrimmed(200) if tournamentName.isEmpty { tournament.name = nil } else { tournament.name = tournamentName } } else if focusedField == ._information { - let tournamentInformation = tournamentInformation.prefixTrimmed(4000) + let tournamentInformation = tournamentInformation.prefixMultilineTrimmed(4000) if tournamentInformation.isEmpty { tournament.information = nil } else { @@ -193,9 +201,6 @@ struct TournamentGeneralSettingsView: View { .onChange(of: [tournament.name, tournament.information]) { _save() } - .onChange(of: tournament.displayEntryFeeInformation) { - _save() - } .onChange(of: tournament.dayDuration) { _save() } diff --git a/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift b/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift index 15ec869..36d1078 100644 --- a/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift +++ b/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift @@ -31,7 +31,7 @@ enum TournamentSettings: Identifiable, Selectable, Equatable { case .club: return "Terrains" case .onlineRegistration: - return "Inscriptions en ligne" + return "Inscriptions" } } diff --git a/PadelClubTests/ServerDataTests.swift b/PadelClubTests/ServerDataTests.swift index 7dc721c..6cca7a4 100644 --- a/PadelClubTests/ServerDataTests.swift +++ b/PadelClubTests/ServerDataTests.swift @@ -100,7 +100,7 @@ final class ServerDataTests: XCTestCase { return } - let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true, shouldVerifyBracket: true, shouldVerifyGroupStage: true, hideTeamsWeight: true, publishTournament: true, hidePointsEarned: true, publishRankings: true, loserBracketMode: .manual, initialSeedRound: 8, initialSeedCount: 4, accountIsRequired: false, licenseIsRequired: false, minimumPlayerPerTeam: 3, maximumPlayerPerTeam: 5, information: "Super", displayEntryFeeInformation: true) + let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true, shouldVerifyBracket: true, shouldVerifyGroupStage: true, hideTeamsWeight: true, publishTournament: true, hidePointsEarned: true, publishRankings: true, loserBracketMode: .manual, initialSeedRound: 8, initialSeedCount: 4, accountIsRequired: false, licenseIsRequired: false, minimumPlayerPerTeam: 3, maximumPlayerPerTeam: 5, information: "Super") let t = try await StoreCenter.main.service().post(tournament) assert(t.event == tournament.event) @@ -148,7 +148,6 @@ final class ServerDataTests: XCTestCase { assert(t.minimumPlayerPerTeam == tournament.minimumPlayerPerTeam) assert(t.maximumPlayerPerTeam == tournament.maximumPlayerPerTeam) assert(t.information == tournament.information) - assert(t.displayEntryFeeInformation == tournament.displayEntryFeeInformation) } func testGroupStage() async throws {