Laurent 2 months ago
commit dc02001505
  1. 8
      PadelClub.xcodeproj/project.pbxproj
  2. 3
      PadelClub/AppDelegate.swift
  3. 5
      PadelClub/Data/Federal/FederalPlayer.swift
  4. 30
      PadelClub/Extensions/Tournament+Extensions.swift
  5. 15
      PadelClub/Views/Club/Shared/ClubCourtSetupView.swift
  6. 4
      PadelClub/Views/Match/Components/PlayerBlockView.swift
  7. 27
      PadelClub/Views/Match/MatchDetailView.swift
  8. 24
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  9. 12
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  10. 5
      PadelClub/Views/Team/EditingTeamView.swift
  11. 4
      PadelClub/Views/Tournament/ConsolationTournamentImportView.swift
  12. 7
      PadelClub/Views/Tournament/Subscription/SubscriptionView.swift

@ -3145,7 +3145,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.48; MARKETING_VERSION = 1.2.50;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3191,7 +3191,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.48; MARKETING_VERSION = 1.2.50;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3376,7 +3376,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 = 1; CURRENT_PROJECT_VERSION = 2;
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\"";
@ -3419,7 +3419,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 = 1; CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -55,9 +55,10 @@ class AppDelegate : NSObject, UIApplicationDelegate, UNUserNotificationCenterDel
StoreCenter.main.forceNoSynchronization = !synchronized StoreCenter.main.forceNoSynchronization = !synchronized
} }
func applicationWillEnterForeground(_ application: UIApplication) { func applicationWillEnterForeground(_ application: UIApplication) {
Task { Task {
try await Guard.main.refreshPurchasedAppleProducts() await Guard.main.refreshPurchases()
} }
} }

@ -80,8 +80,13 @@ class FederalPlayer: Decodable {
let ageSportif = try container.decodeIfPresent(Int.self, forKey: .ageSportif) let ageSportif = try container.decodeIfPresent(Int.self, forKey: .ageSportif)
if let ageSportif { if let ageSportif {
let month = Calendar.current.component(.month, from: Date())
if month > 8 {
birthYear = Calendar.current.component(.year, from: Date()) + 1 - ageSportif
} else {
birthYear = Calendar.current.component(.year, from: Date()) - ageSportif birthYear = Calendar.current.component(.year, from: Date()) - ageSportif
} }
}
clubCode = try container.decodeIfPresent(String.self, forKey: .codeClub) ?? "" clubCode = try container.decodeIfPresent(String.self, forKey: .codeClub) ?? ""
club = try container.decodeIfPresent(String.self, forKey: .nomClub) ?? "" club = try container.decodeIfPresent(String.self, forKey: .nomClub) ?? ""
ligue = try container.decodeIfPresent(String.self, forKey: .ligue) ?? "" ligue = try container.decodeIfPresent(String.self, forKey: .ligue) ?? ""

@ -12,36 +12,6 @@ import LeStorage
extension Tournament { extension Tournament {
func setupFederalSettings() {
teamSorting = tournamentLevel.defaultTeamSortingType
groupStageMatchFormat = groupStageSmartMatchFormat()
loserBracketMatchFormat = loserBracketSmartMatchFormat(5)
matchFormat = roundSmartMatchFormat(5)
entryFee = tournamentLevel.entryFee
registrationDateLimit = deadline(for: .inscription)
if enableOnlineRegistration, isAnimation() == false {
accountIsRequired = true
licenseIsRequired = true
}
}
func customizeUsingPreferences() {
guard let lastTournamentWithSameBuild = DataStore.shared.tournaments.filter({ tournament in
tournament.tournamentLevel == self.tournamentLevel
&& tournament.tournamentCategory == self.tournamentCategory
&& tournament.federalTournamentAge == self.federalTournamentAge
&& tournament.hasEnded() == true
&& tournament.isCanceled == false
&& tournament.isDeleted == false
}).sorted(by: \.endDate!, order: .descending).first else {
return
}
self.dayDuration = lastTournamentWithSameBuild.dayDuration
self.teamCount = (lastTournamentWithSameBuild.teamCount / 2) * 2
self.enableOnlineRegistration = lastTournamentWithSameBuild.enableOnlineRegistration
}
func addTeam(_ players: Set<PlayerRegistration>, registrationDate: Date? = nil, name: String? = nil) -> TeamRegistration { func addTeam(_ players: Set<PlayerRegistration>, registrationDate: Date? = nil, name: String? = nil) -> TeamRegistration {
let team = TeamRegistration(tournament: id, registrationDate: registrationDate ?? Date(), name: name) let team = TeamRegistration(tournament: id, registrationDate: registrationDate ?? Date(), name: name)
team.setWeight(from: Array(players), inTournamentCategory: tournamentCategory) team.setWeight(from: Array(players), inTournamentCategory: tournamentCategory)

@ -23,10 +23,17 @@ struct ClubCourtSetupView: View {
.disabled(displayContext == .lockedForEditing) .disabled(displayContext == .lockedForEditing)
.onChange(of: club.courtCount) { .onChange(of: club.courtCount) {
if displayContext != .addition { if displayContext != .addition {
do { dataStore.clubs.addOrUpdate(instance: club)
try dataStore.clubs.addOrUpdate(instance: club) dataStore.events.filter { event in
} catch { event.club?.id == club.id
Logger.error(error) }.forEach { event in
let tournaments = event.tournaments.filter({ tournament in
tournament.startDate > Date()
})
tournaments.forEach { tournament in
tournament.courtCount = club.courtCount
}
dataStore.tournaments.addOrUpdate(contentOfs: tournaments)
} }
} }
} }

@ -77,7 +77,7 @@ struct PlayerBlockView: View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
ZStack(alignment: .leading) { ZStack(alignment: .leading) {
VStack { VStack {
if let teamName = team?.name { if let teamName = team?.name, teamName.isEmpty == false {
Text(teamName).foregroundStyle(.secondary).font(.footnote) Text(teamName).foregroundStyle(.secondary).font(.footnote)
} }
Text("longLabelPlayerOne").lineLimit(1) Text("longLabelPlayerOne").lineLimit(1)
@ -91,7 +91,7 @@ struct PlayerBlockView: View {
Text("Repêchée").italic().font(.caption) Text("Repêchée").italic().font(.caption)
} }
if let teamName = team.name { if let teamName = team.name, teamName.isEmpty == false {
Text(teamName).foregroundStyle(.secondary).font(.footnote) Text(teamName).foregroundStyle(.secondary).font(.footnote)
} else if team.players().isEmpty { } else if team.players().isEmpty {
if team.isWildCard() { if team.isWildCard() {

@ -354,6 +354,33 @@ struct MatchDetailView: View {
Text("Remise-à-zéro") Text("Remise-à-zéro")
} }
Menu {
Button("Effacer le nom") {
match.name = nil
tournamentStore?.matches.addOrUpdate(instance: match)
}
if let tournament = match.currentTournament() {
Menu {
ForEach(tournament.generateSeedGroups(base: 16, teamCount: 8), id: \.self) { seedGroup in
Button {
match.name = seedGroup.localizedInterval()
tournamentStore?.matches.addOrUpdate(instance: match)
} label: {
Text(seedGroup.localizedInterval())
}
}
} label: {
Text("Choisir un nom")
}
}
} label: {
Text("[Site] Nom du match")
if let name = match.name {
Text("(\(name))")
}
}
if match.teamScores.isEmpty == false { if match.teamScores.isEmpty == false {
Divider() Divider()
Menu { Menu {

@ -158,6 +158,29 @@ struct EventListView: View {
} }
Divider() Divider()
} }
Menu {
Picker("Choix du montant", selection: Binding<Double>(get: {
// If all tournaments share the same price, show it; otherwise default to 0
let prices = Set(pcTournaments.compactMap { $0.entryFee })
return prices.count == 1 ? prices.first ?? 0.0 : 0.0
}, set: { (newValue: Double) in
// Apply the chosen price to every tournament
pcTournaments.forEach { tournament in
tournament.entryFee = newValue
}
dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments)
})) {
ForEach([Double](stride(from: 0.0, through: 50.0, by: 5.0)), id: \.self) { (price: Double) in
Text(price.formatted(.currency(code: Locale.current.currency?.identifier ?? "EUR"))).tag(price as Double)
}
}
} label: {
Text("Montant de l'inscription")
}
Divider()
Menu { Menu {
Button { Button {
pcTournaments.forEach { tournament in pcTournaments.forEach { tournament in
@ -534,3 +557,4 @@ struct EventListView: View {
//#Preview { //#Preview {
// EventListView(tournaments: [], viewStyle: .calendar, sortAscending: true) // EventListView(tournaments: [], viewStyle: .calendar, sortAscending: true)
//} //}

@ -317,18 +317,6 @@ struct UmpireView: View {
licenseMessage = nil licenseMessage = nil
} }
.navigationTitle("Juge-Arbitre") .navigationTitle("Juge-Arbitre")
.toolbar {
#if DEBUG
ToolbarItem(placement: .topBarTrailing) {
NetworkStatusView()
// if StoreCenter.main.collectionsCanSynchronize {
// Image(systemName: "checkmark.icloud")
// } else {
// Image(systemName: "icloud.slash")
// }
}
#endif
}
.navigationBarBackButtonHidden(focusedField != nil) .navigationBarBackButtonHidden(focusedField != nil)
.toolbar(content: { .toolbar(content: {
if focusedField != nil { if focusedField != nil {

@ -209,11 +209,6 @@ struct EditingTeamView: View {
Text(registrationDateModified.localizedWeekDay().capitalized) Text(registrationDateModified.localizedWeekDay().capitalized)
} }
} }
#if DEBUG
.disabled(false)
#else
.disabled(team.hasPaidOnline() || team.hasRegisteredOnline())
#endif
Toggle(isOn: $wildCardBracket) { Toggle(isOn: $wildCardBracket) {
Text("Wildcard Tableau") Text("Wildcard Tableau")

@ -218,8 +218,8 @@ struct ConsolationTournamentImportView: View {
case .losers: case .losers:
if selectedGroupStagePosition.isEmpty { if selectedGroupStagePosition.isEmpty {
return $0.qualified == false return $0.qualified == false
} else if let position = $0.groupStagePosition { } else if let position = $0.groupStageObject()?.finalPosition(ofTeam: $0) {
return $0.qualified == false && selectedGroupStagePosition.contains(position) return $0.qualified == false && selectedGroupStagePosition.contains(position + 1)
} else { } else {
return $0.qualified == false return $0.qualified == false
} }

@ -238,14 +238,9 @@ struct SubscriptionView: View {
fileprivate func _restore() { fileprivate func _restore() {
Task { Task {
do {
self.isRestoring = true self.isRestoring = true
try await Guard.main.refreshPurchasedAppleProducts() await Guard.main.refreshPurchases()
self.isRestoring = false
} catch {
self.isRestoring = false self.isRestoring = false
Logger.error(error)
}
} }
} }

Loading…
Cancel
Save