wip online reg

paca_championship
Raz 11 months ago
parent 9a8f9f8949
commit 5f0eaa156b
  1. 8
      PadelClub.xcodeproj/project.pbxproj
  2. 39
      PadelClub/Data/Tournament.swift
  3. 4
      PadelClub/Extensions/String+Extensions.swift
  4. 4
      PadelClub/Views/Club/ClubDetailView.swift
  5. 29
      PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift
  6. 2
      PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift
  7. 3
      PadelClubTests/ServerDataTests.swift

@ -3527,7 +3527,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3549,7 +3549,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.24; MARKETING_VERSION = 1.0.34;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3569,7 +3569,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -3590,7 +3590,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.24; MARKETING_VERSION = 1.0.34;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

@ -70,7 +70,6 @@ final class Tournament : ModelObject, Storable {
var minimumPlayerPerTeam: Int = 2 var minimumPlayerPerTeam: Int = 2
var maximumPlayerPerTeam: Int = 2 var maximumPlayerPerTeam: Int = 2
var information: String? = nil var information: String? = nil
var displayEntryFeeInformation: Bool = false
@ObservationIgnored @ObservationIgnored
var navigationPath: [Screen] = [] var navigationPath: [Screen] = []
@ -122,16 +121,20 @@ final class Tournament : ModelObject, Storable {
case _loserBracketMode = "loserBracketMode" case _loserBracketMode = "loserBracketMode"
case _initialSeedRound = "initialSeedRound" case _initialSeedRound = "initialSeedRound"
case _initialSeedCount = "initialSeedCount" case _initialSeedCount = "initialSeedCount"
case _accountIsRequired = "account_is_required" case _enableOnlineRegistration = "enableOnlineRegistration"
case _licenseIsRequired = "license_is_required" case _registrationDateLimit = "registrationDateLimit"
case _minimumPlayerPerTeam = "minimum_player_per_team" case _openingRegistrationDate = "openingRegistrationDate"
case _maximumPlayerPerTeam = "maximum_player_per_team" case _targetTeamCount = "targetTeamCount"
case _waitingListLimit = "waitingListLimit"
case _accountIsRequired = "accountIsRequired"
case _licenseIsRequired = "licenseIsRequired"
case _minimumPlayerPerTeam = "minimumPlayerPerTeam"
case _maximumPlayerPerTeam = "maximumPlayerPerTeam"
case _information = "information" 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.event = event
self.name = name self.name = name
self.startDate = startDate self.startDate = startDate
@ -185,14 +188,17 @@ final class Tournament : ModelObject, Storable {
self.loserBracketMode = loserBracketMode self.loserBracketMode = loserBracketMode
self.initialSeedRound = initialSeedRound self.initialSeedRound = initialSeedRound
self.initialSeedCount = initialSeedCount self.initialSeedCount = initialSeedCount
self.enableOnlineRegistration = enableOnlineRegistration
self.registrationDateLimit = registrationDateLimit
self.openingRegistrationDate = openingRegistrationDate
self.targetTeamCount = targetTeamCount
self.waitingListLimit = waitingListLimit
self.accountIsRequired = accountIsRequired self.accountIsRequired = accountIsRequired
self.licenseIsRequired = licenseIsRequired self.licenseIsRequired = licenseIsRequired
self.minimumPlayerPerTeam = minimumPlayerPerTeam self.minimumPlayerPerTeam = minimumPlayerPerTeam
self.maximumPlayerPerTeam = maximumPlayerPerTeam self.maximumPlayerPerTeam = maximumPlayerPerTeam
self.information = information self.information = information
self.displayEntryFeeInformation = displayEntryFeeInformation
} }
required init(from decoder: Decoder) throws { required init(from decoder: Decoder) throws {
@ -240,15 +246,17 @@ final class Tournament : ModelObject, Storable {
loserBracketMode = try container.decodeIfPresent(LoserBracketMode.self, forKey: ._loserBracketMode) ?? .automatic loserBracketMode = try container.decodeIfPresent(LoserBracketMode.self, forKey: ._loserBracketMode) ?? .automatic
initialSeedRound = try container.decodeIfPresent(Int.self, forKey: ._initialSeedRound) ?? 0 initialSeedRound = try container.decodeIfPresent(Int.self, forKey: ._initialSeedRound) ?? 0
initialSeedCount = try container.decodeIfPresent(Int.self, forKey: ._initialSeedCount) ?? 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 accountIsRequired = try container.decodeIfPresent(Bool.self, forKey: ._accountIsRequired) ?? true
licenseIsRequired = try container.decodeIfPresent(Bool.self, forKey: ._licenseIsRequired) ?? true licenseIsRequired = try container.decodeIfPresent(Bool.self, forKey: ._licenseIsRequired) ?? true
minimumPlayerPerTeam = try container.decodeIfPresent(Int.self, forKey: ._minimumPlayerPerTeam) ?? 2 minimumPlayerPerTeam = try container.decodeIfPresent(Int.self, forKey: ._minimumPlayerPerTeam) ?? 2
maximumPlayerPerTeam = try container.decodeIfPresent(Int.self, forKey: ._maximumPlayerPerTeam) ?? 2 maximumPlayerPerTeam = try container.decodeIfPresent(Int.self, forKey: ._maximumPlayerPerTeam) ?? 2
information = try container.decodeIfPresent(String.self, forKey: ._information) information = try container.decodeIfPresent(String.self, forKey: ._information)
displayEntryFeeInformation = try container.decodeIfPresent(Bool.self, forKey: ._displayEntryFeeInformation) ?? false
} }
fileprivate static let _numberFormatter: NumberFormatter = NumberFormatter() fileprivate static let _numberFormatter: NumberFormatter = NumberFormatter()
@ -337,12 +345,17 @@ final class Tournament : ModelObject, Storable {
try container.encode(loserBracketMode, forKey: ._loserBracketMode) try container.encode(loserBracketMode, forKey: ._loserBracketMode)
try container.encode(initialSeedRound, forKey: ._initialSeedRound) try container.encode(initialSeedRound, forKey: ._initialSeedRound)
try container.encode(initialSeedCount, forKey: ._initialSeedCount) 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(accountIsRequired, forKey: ._accountIsRequired)
try container.encode(licenseIsRequired, forKey: ._licenseIsRequired) try container.encode(licenseIsRequired, forKey: ._licenseIsRequired)
try container.encode(minimumPlayerPerTeam, forKey: ._minimumPlayerPerTeam) try container.encode(minimumPlayerPerTeam, forKey: ._minimumPlayerPerTeam)
try container.encode(maximumPlayerPerTeam, forKey: ._maximumPlayerPerTeam) try container.encode(maximumPlayerPerTeam, forKey: ._maximumPlayerPerTeam)
try container.encode(information, forKey: ._information) try container.encode(information, forKey: ._information)
try container.encode(displayEntryFeeInformation, forKey: ._displayEntryFeeInformation)
} }
fileprivate func _encodePayment(container: inout KeyedEncodingContainer<CodingKeys>) throws { fileprivate func _encodePayment(container: inout KeyedEncodingContainer<CodingKeys>) throws {

@ -18,6 +18,10 @@ extension String {
String(trimmed.prefix(length)) String(trimmed.prefix(length))
} }
func prefixMultilineTrimmed(_ length: Int) -> String {
String(trimmedMultiline.prefix(length))
}
var trimmed: String { var trimmed: String {
replaceCharactersFromSet(characterSet: .newlines, replacementString: " ").trimmingCharacters(in: .whitespacesAndNewlines) replaceCharactersFromSet(characterSet: .newlines, replacementString: " ").trimmingCharacters(in: .whitespacesAndNewlines)
} }

@ -135,9 +135,9 @@ struct ClubDetailView: View {
.onChange(of: acronymMode) { .onChange(of: acronymMode) {
focusedField = ._acronym focusedField = ._acronym
if acronymMode == .custom { if acronymMode == .custom {
club.acronym = "" //club.acronym = ""
} else { } else {
club.acronym = club.automaticShortName().uppercased() //club.acronym = club.automaticShortName().uppercased()
} }
} }
} footer: { } footer: {

@ -44,11 +44,25 @@ struct TournamentGeneralSettingsView: View {
} }
Section { Section {
ZStack {
Text(tournamentInformation).opacity(0)
Text(ContactType.defaultCustomMessage).opacity(0)
TextEditor(text: $tournamentInformation) TextEditor(text: $tournamentInformation)
.keyboardType(.alphabet) .keyboardType(.alphabet)
.focused($focusedField, equals: ._information) .focused($focusedField, equals: ._information)
}
.frame(maxHeight: 200)
.overlay {
if tournamentInformation.isEmpty {
Text("Texte visible dans l'onglet informations sur Padel Club.").italic()
}
}
} header: { } header: {
Text("Description du tournoi") Text("Description du tournoi")
} footer: {
FooterButtonView("Ajouter le prix de l'inscription") {
tournamentInformation.append("\n" + tournament.entryFeeMessage)
}
} }
Section { Section {
@ -63,12 +77,6 @@ struct TournamentGeneralSettingsView: View {
} label: { } label: {
Text("Inscription") Text("Inscription")
} }
if tournament.isPrivate == false {
Toggle(isOn: $tournament.displayEntryFeeInformation) {
Text("Afficher sur la page d'infos")
}
}
} footer: { } 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.") 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 focusedField == ._entryFee {
if tournament.isFree() { if tournament.isFree() {
ForEach(priceTags, id: \.self) { priceTag in 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 entryFee = priceTag
tournament.entryFee = priceTag tournament.entryFee = priceTag
focusedField = nil focusedField = nil
@ -161,14 +169,14 @@ struct TournamentGeneralSettingsView: View {
Spacer() Spacer()
Button("Valider") { Button("Valider") {
if focusedField == ._name { if focusedField == ._name {
let tournamentName = tournamentName.prefixTrimmed(200) let tournamentName = tournamentName.prefixMultilineTrimmed(200)
if tournamentName.isEmpty { if tournamentName.isEmpty {
tournament.name = nil tournament.name = nil
} else { } else {
tournament.name = tournamentName tournament.name = tournamentName
} }
} else if focusedField == ._information { } else if focusedField == ._information {
let tournamentInformation = tournamentInformation.prefixTrimmed(4000) let tournamentInformation = tournamentInformation.prefixMultilineTrimmed(4000)
if tournamentInformation.isEmpty { if tournamentInformation.isEmpty {
tournament.information = nil tournament.information = nil
} else { } else {
@ -193,9 +201,6 @@ struct TournamentGeneralSettingsView: View {
.onChange(of: [tournament.name, tournament.information]) { .onChange(of: [tournament.name, tournament.information]) {
_save() _save()
} }
.onChange(of: tournament.displayEntryFeeInformation) {
_save()
}
.onChange(of: tournament.dayDuration) { .onChange(of: tournament.dayDuration) {
_save() _save()
} }

@ -31,7 +31,7 @@ enum TournamentSettings: Identifiable, Selectable, Equatable {
case .club: case .club:
return "Terrains" return "Terrains"
case .onlineRegistration: case .onlineRegistration:
return "Inscriptions en ligne" return "Inscriptions"
} }
} }

@ -100,7 +100,7 @@ final class ServerDataTests: XCTestCase {
return 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) let t = try await StoreCenter.main.service().post(tournament)
assert(t.event == tournament.event) assert(t.event == tournament.event)
@ -148,7 +148,6 @@ final class ServerDataTests: XCTestCase {
assert(t.minimumPlayerPerTeam == tournament.minimumPlayerPerTeam) assert(t.minimumPlayerPerTeam == tournament.minimumPlayerPerTeam)
assert(t.maximumPlayerPerTeam == tournament.maximumPlayerPerTeam) assert(t.maximumPlayerPerTeam == tournament.maximumPlayerPerTeam)
assert(t.information == tournament.information) assert(t.information == tournament.information)
assert(t.displayEntryFeeInformation == tournament.displayEntryFeeInformation)
} }
func testGroupStage() async throws { func testGroupStage() async throws {

Loading…
Cancel
Save