v1.0.2 build 1

clubs
Raz 1 year ago
parent eef48f3388
commit f73eecd310
  1. 20
      PadelClub.xcodeproj/project.pbxproj
  2. 29
      PadelClub/Data/Match.swift
  3. 15
      PadelClub/Data/PlayerRegistration.swift
  4. 4
      PadelClub/Data/Tournament.swift
  5. 2
      PadelClub/Utils/URLs.swift
  6. 40
      PadelClub/Views/Components/ConfirmButtonView.swift
  7. 20
      PadelClub/Views/Match/MatchDetailView.swift
  8. 17
      PadelClub/Views/Match/MatchSetupView.swift
  9. 3
      PadelClub/Views/Team/TeamPickerView.swift
  10. 32
      PadelClub/Views/Tournament/Screen/AddTeamView.swift
  11. 18
      PadelClub/Views/Tournament/Screen/Components/InscriptionInfoView.swift

@ -253,6 +253,7 @@
FFE103102C366DCD00684FC9 /* EditSharingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */; }; FFE103102C366DCD00684FC9 /* EditSharingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */; };
FFE103122C366E5900684FC9 /* ImagePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE103112C366E5900684FC9 /* ImagePickerView.swift */; }; FFE103122C366E5900684FC9 /* ImagePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE103112C366E5900684FC9 /* ImagePickerView.swift */; };
FFE2D2E22C231BEE00D0C7BE /* SupportButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */; }; FFE2D2E22C231BEE00D0C7BE /* SupportButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */; };
FFE8C2C02C7601E80046B243 /* ConfirmButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE8C2BF2C7601E80046B243 /* ConfirmButtonView.swift */; };
FFEF7F4E2BDE69130033D0F0 /* MenuWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */; }; FFEF7F4E2BDE69130033D0F0 /* MenuWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */; };
FFF0241E2BF48B15001F14B4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = FFF0241D2BF48B15001F14B4 /* Localizable.strings */; }; FFF0241E2BF48B15001F14B4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = FFF0241D2BF48B15001F14B4 /* Localizable.strings */; };
FFF03C942BD91D0C00B516FC /* ButtonValidateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF03C932BD91D0C00B516FC /* ButtonValidateView.swift */; }; FFF03C942BD91D0C00B516FC /* ButtonValidateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF03C932BD91D0C00B516FC /* ButtonValidateView.swift */; };
@ -596,6 +597,7 @@
FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSharingView.swift; sourceTree = "<group>"; }; FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSharingView.swift; sourceTree = "<group>"; };
FFE103112C366E5900684FC9 /* ImagePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePickerView.swift; sourceTree = "<group>"; }; FFE103112C366E5900684FC9 /* ImagePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePickerView.swift; sourceTree = "<group>"; };
FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportButtonView.swift; sourceTree = "<group>"; }; FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportButtonView.swift; sourceTree = "<group>"; };
FFE8C2BF2C7601E80046B243 /* ConfirmButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmButtonView.swift; sourceTree = "<group>"; };
FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuWarningView.swift; sourceTree = "<group>"; }; FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuWarningView.swift; sourceTree = "<group>"; };
FFF0241C2BF48B15001F14B4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; }; FFF0241C2BF48B15001F14B4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
FFF0241F2BF48B1A001F14B4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; }; FFF0241F2BF48B1A001F14B4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -684,6 +686,7 @@
FFF8ACD72B923F26008466FA /* Extensions */, FFF8ACD72B923F26008466FA /* Extensions */,
C425D4042B6D249E002A7B48 /* Assets.xcassets */, C425D4042B6D249E002A7B48 /* Assets.xcassets */,
FFF024192BF48AEE001F14B4 /* Localization */, FFF024192BF48AEE001F14B4 /* Localization */,
FFA4DA502C75E815002DAA31 /* Files */,
FF0EC54D2BB195CA0056B6D1 /* CSV */, FF0EC54D2BB195CA0056B6D1 /* CSV */,
FF1F4B802BFA0105000B4573 /* HTML Templates */, FF1F4B802BFA0105000B4573 /* HTML Templates */,
C425D4062B6D249E002A7B48 /* Preview Content */, C425D4062B6D249E002A7B48 /* Preview Content */,
@ -820,6 +823,7 @@
C4A47D9E2B7D0BCE00ADC637 /* StepperView.swift */, C4A47D9E2B7D0BCE00ADC637 /* StepperView.swift */,
FFCB74162C480411008384D0 /* CopyPasteButtonView.swift */, FFCB74162C480411008384D0 /* CopyPasteButtonView.swift */,
FF558C622C6CDD020071F9AE /* UnderlineView.swift */, FF558C622C6CDD020071F9AE /* UnderlineView.swift */,
FFE8C2BF2C7601E80046B243 /* ConfirmButtonView.swift */,
); );
path = Components; path = Components;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1228,6 +1232,13 @@
path = Components; path = Components;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FFA4DA502C75E815002DAA31 /* Files */ = {
isa = PBXGroup;
children = (
);
path = Files;
sourceTree = "<group>";
};
FFBF41802BF73EA2001B24CB /* Event */ = { FFBF41802BF73EA2001B24CB /* Event */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1601,6 +1612,7 @@
FF967CF62BAED51600A9A3BD /* TournamentRunningView.swift in Sources */, FF967CF62BAED51600A9A3BD /* TournamentRunningView.swift in Sources */,
FF8F264D2BAE0B4100650388 /* TournamentDatePickerView.swift in Sources */, FF8F264D2BAE0B4100650388 /* TournamentDatePickerView.swift in Sources */,
FFF116E32BD2AF4800A33B06 /* CourtAvailabilitySettingsView.swift in Sources */, FFF116E32BD2AF4800A33B06 /* CourtAvailabilitySettingsView.swift in Sources */,
FFE8C2C02C7601E80046B243 /* ConfirmButtonView.swift in Sources */,
C4FC2E272C2AABC90021F3BF /* PasswordField.swift in Sources */, C4FC2E272C2AABC90021F3BF /* PasswordField.swift in Sources */,
FF967D042BAEF1C300A9A3BD /* MatchRowView.swift in Sources */, FF967D042BAEF1C300A9A3BD /* MatchRowView.swift in Sources */,
C44B79112BBDA63A00906534 /* Locale+Extensions.swift in Sources */, C44B79112BBDA63A00906534 /* Locale+Extensions.swift in Sources */,
@ -1939,7 +1951,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 = 8; 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\"";
@ -1964,7 +1976,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.1; MARKETING_VERSION = 1.0.2;
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "-Onone"; OTHER_SWIFT_FLAGS = "-Onone";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
@ -1989,7 +2001,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 = 8; 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;
@ -2012,7 +2024,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.1; MARKETING_VERSION = 1.0.2;
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=5 -Xfrontend -warn-long-expression-type-checking=20 -Xfrontend -warn-long-function-bodies=50"; OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=5 -Xfrontend -warn-long-expression-type-checking=20 -Xfrontend -warn-long-function-bodies=50";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;

@ -163,6 +163,7 @@ defer {
} }
func isSeededBy(team: TeamRegistration, inTeamPosition teamPosition: TeamPosition) -> Bool { func isSeededBy(team: TeamRegistration, inTeamPosition teamPosition: TeamPosition) -> Bool {
guard let roundObject, roundObject.isUpperBracket() else { return false }
guard let bracketPosition = team.bracketPosition else { return false } guard let bracketPosition = team.bracketPosition else { return false }
return index * 2 + teamPosition.rawValue == bracketPosition return index * 2 + teamPosition.rawValue == bracketPosition
} }
@ -345,9 +346,37 @@ defer {
// forwardMatch._toggleByeState(state) // forwardMatch._toggleByeState(state)
} }
func isSeededBy(team: TeamRegistration) -> Bool {
isSeededBy(team: team, inTeamPosition: .one) || isSeededBy(team: team, inTeamPosition: .two)
}
func isSeeded() -> Bool {
return isSeededAt(.one) || isSeededAt(.two)
}
func isSeededAt(_ teamPosition: TeamPosition) -> Bool {
if let team = team(teamPosition) {
return isSeededBy(team: team)
}
return false
}
func _toggleMatchDisableState(_ state: Bool, forward: Bool = false) { func _toggleMatchDisableState(_ state: Bool, forward: Bool = false) {
//if disabled == state { return } //if disabled == state { return }
disabled = state disabled = state
if state == true {
let teams = teams()
for team in teams {
if isSeededBy(team: team) {
team.bracketPosition = nil
do {
try self.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
}
}
}
//byeState = false //byeState = false
do { do {
try self.tournamentStore.matches.addOrUpdate(instance: self) try self.tournamentStore.matches.addOrUpdate(instance: self)

@ -304,6 +304,21 @@ final class PlayerRegistration: ModelObject, Storable {
} }
} }
func hasHomonym() -> Bool {
let federalContext = PersistenceController.shared.localContainer.viewContext
let fetchRequest = ImportedPlayer.fetchRequest()
let predicate = NSPredicate(format: "firstName == %@ && lastName == %@", firstName, lastName)
fetchRequest.predicate = predicate
do {
let count = try federalContext.count(for: fetchRequest)
return count > 1
} catch {
}
return false
}
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case _id = "id" case _id = "id"
case _teamRegistration = "teamRegistration" case _teamRegistration = "teamRegistration"

@ -952,6 +952,10 @@ defer {
return duplicates return duplicates
} }
func homonyms(in players: [PlayerRegistration]) -> [PlayerRegistration] {
players.filter({ $0.hasHomonym() })
}
func unsortedPlayers() -> [PlayerRegistration] { func unsortedPlayers() -> [PlayerRegistration] {
return Array(self.tournamentStore.playerRegistrations) return Array(self.tournamentStore.playerRegistrations)
} }

@ -18,7 +18,7 @@ enum URLs: String, Identifiable {
case tenup = "https://tenup.fft.fr" case tenup = "https://tenup.fft.fr"
case padelCompetitionGeneralGuide = "https://fft-site.cdn.prismic.io/fft-site/Zqi2PB5LeNNTxlrS_1-REGLESGENERALESDELACOMPETITION-ANNEESPORTIVE2025.pdf" case padelCompetitionGeneralGuide = "https://fft-site.cdn.prismic.io/fft-site/Zqi2PB5LeNNTxlrS_1-REGLESGENERALESDELACOMPETITION-ANNEESPORTIVE2025.pdf"
case padelCompetitionSpecificGuide = "https://fft-site.cdn.prismic.io/fft-site/Zqi4ax5LeNNTxlsu_3-CAHIERDESCHARGESDESTOURNOIS-ANNEESPORTIVE2025.pdf" case padelCompetitionSpecificGuide = "https://fft-site.cdn.prismic.io/fft-site/Zqi4ax5LeNNTxlsu_3-CAHIERDESCHARGESDESTOURNOIS-ANNEESPORTIVE2025.pdf"
case padelRules = "https://fft-site.cdn.prismic.io/fft-site/ZgLnkMcYqOFdyF7i_L%27arbitragedupadel-édition2023_0.pdf" case padelRules = "https://xlr.alwaysdata.net/static/rules/padel-rules-2024.pdf"
case restingDischarge = "https://club.fft.fr/tennisfirmidecazeville/60120370_d/data_1/pdf/fo/formlairededechargederesponsabilitetournoidepadel.pdf" case restingDischarge = "https://club.fft.fr/tennisfirmidecazeville/60120370_d/data_1/pdf/fo/formlairededechargederesponsabilitetournoidepadel.pdf"
case appReview = "https://apps.apple.com/app/padel-club/id6484163558?mt=8&action=write-review" case appReview = "https://apps.apple.com/app/padel-club/id6484163558?mt=8&action=write-review"
case appDescription = "https://padelclub.app/download/" case appDescription = "https://padelclub.app/download/"

@ -0,0 +1,40 @@
//
// ConfirmButtonView.swift
// PadelClub
//
// Created by razmig on 21/08/2024.
//
import SwiftUI
struct ConfirmButtonView<T:View>: View {
@State private var showingConfirmDialog = false
@State private var actionConfirmed = false
var shouldConfirm: Bool
var message: String
var confirmButtonText: String = "OK"
var cancelButtonText: String = "Annuler"
var onConfirm: () -> Void
var label: () -> T
var body: some View {
Button {
if shouldConfirm {
showingConfirmDialog = true
} else {
onConfirm()
}
} label: {
label()
}
.confirmationDialog("Attention", isPresented: $showingConfirmDialog) {
Button(confirmButtonText, role: .destructive) {
onConfirm()
}
Button(cancelButtonText, role: .cancel) { }
} message: {
Text(message)
}
}
}

@ -250,6 +250,17 @@ struct MatchDetailView: View {
// } // }
// } // }
Toggle(isOn: .init(get: {
return match.confirmed
}, set: { value in
match.confirmed = value
save()
})) {
Text(match.confirmed ? "Confirmé" : "Non confirmé")
}
Divider()
if match.courtIndex != nil { if match.courtIndex != nil {
Button(role: .destructive) { Button(role: .destructive) {
match.removeCourt() match.removeCourt()
@ -275,6 +286,15 @@ struct MatchDetailView: View {
} label: { } label: {
Text("Supprimer les scores") Text("Supprimer les scores")
} }
Divider()
Button(role: .destructive) {
match.resetTeamScores(outsideOf: [])
match.resetMatch()
match.confirmed = false
save()
} label: {
Text("Remise-à-zéro")
}
} label: { } label: {
LabelOptions() LabelOptions()

@ -9,6 +9,7 @@ import SwiftUI
import LeStorage import LeStorage
struct MatchSetupView: View { struct MatchSetupView: View {
static let confirmationMessage = "Au moins une tête de série a été placée dans la branche de ce match dans les tours précédents. En plaçant une équipe sur ici, les équipes déjà placées dans la même branche seront retirées du tableau et devront être replacées."
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@ -33,6 +34,8 @@ struct MatchSetupView: View {
let teamScore = (team != nil) ? scores.first(where: { $0.teamRegistration == team!.id }) : nil let teamScore = (team != nil) ? scores.first(where: { $0.teamRegistration == team!.id }) : nil
let walkOutSpot = teamScore?.walkOut == 1 let walkOutSpot = teamScore?.walkOut == 1
let shouldConfirm = match.previousMatch(teamPosition)?.isSeeded() == true
if let team, teamScore?.walkOut == nil { if let team, teamScore?.walkOut == nil {
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
if let teamScore, teamScore.luckyLoser != nil { if let teamScore, teamScore.luckyLoser != nil {
@ -42,12 +45,12 @@ struct MatchSetupView: View {
_removeTeam(team: team, teamPosition: teamPosition) _removeTeam(team: team, teamPosition: teamPosition)
} label: { } label: {
TeamRowView(team: team, teamPosition: teamPosition) TeamRowView(team: team, teamPosition: teamPosition)
}
.buttonStyle(.plain)
.swipeActions(edge: .trailing, allowsFullSwipe: false) { .swipeActions(edge: .trailing, allowsFullSwipe: false) {
_removeTeam(team: team, teamPosition: teamPosition) _removeTeam(team: team, teamPosition: teamPosition)
} }
} }
.buttonStyle(.plain)
}
} else { } else {
VStack(alignment: .leading) { VStack(alignment: .leading) {
if let team { if let team {
@ -56,7 +59,7 @@ struct MatchSetupView: View {
} }
HStack { HStack {
let luckyLosers = walkOutSpot ? match.luckyLosers() : [] let luckyLosers = walkOutSpot ? match.luckyLosers() : []
TeamPickerView(groupStagePosition: nil, luckyLosers: luckyLosers, teamPicked: { team in TeamPickerView(shouldConfirm: shouldConfirm, groupStagePosition: nil, luckyLosers: luckyLosers, teamPicked: { team in
print(team.pasteData()) print(team.pasteData())
if walkOutSpot || team.bracketPosition != nil { if walkOutSpot || team.bracketPosition != nil {
match.setLuckyLoser(team: team, teamPosition: teamPosition) match.setLuckyLoser(team: team, teamPosition: teamPosition)
@ -100,7 +103,7 @@ struct MatchSetupView: View {
} }
if availableQualifiedTeams.isEmpty == false { if availableQualifiedTeams.isEmpty == false {
Button { ConfirmButtonView(shouldConfirm: shouldConfirm, message: MatchSetupView.confirmationMessage) {
if let randomTeam = availableQualifiedTeams.randomElement() { if let randomTeam = availableQualifiedTeams.randomElement() {
randomTeam.setSeedPosition(inSpot: match, slot: teamPosition, opposingSeeding: false) randomTeam.setSeedPosition(inSpot: match, slot: teamPosition, opposingSeeding: false)
do { do {
@ -120,7 +123,7 @@ struct MatchSetupView: View {
} }
ForEach(availableSeedGroups, id: \.self) { seedGroup in ForEach(availableSeedGroups, id: \.self) { seedGroup in
Button { ConfirmButtonView(shouldConfirm: shouldConfirm, message: MatchSetupView.confirmationMessage) {
if let randomTeam = tournament.randomSeed(fromSeedGroup: seedGroup) { if let randomTeam = tournament.randomSeed(fromSeedGroup: seedGroup) {
randomTeam.setSeedPosition(inSpot: match, slot: teamPosition, opposingSeeding: false) randomTeam.setSeedPosition(inSpot: match, slot: teamPosition, opposingSeeding: false)
do { do {
@ -157,7 +160,7 @@ struct MatchSetupView: View {
.underline() .underline()
} }
} else { } else {
Button { ConfirmButtonView(shouldConfirm: shouldConfirm, message: MatchSetupView.confirmationMessage) {
_ = match.lockAndGetSeedPosition(atTeamPosition: teamPosition) _ = match.lockAndGetSeedPosition(atTeamPosition: teamPosition)
do { do {
try tournamentStore.matches.addOrUpdate(instance: match) try tournamentStore.matches.addOrUpdate(instance: match)
@ -187,7 +190,7 @@ struct MatchSetupView: View {
} catch { } catch {
Logger.error(error) Logger.error(error)
} }
match.updateTeamScores() //match.updateTeamScores()
match.previousMatches().forEach { previousMatch in match.previousMatches().forEach { previousMatch in
if previousMatch.disabled { if previousMatch.disabled {
previousMatch.enableMatch() previousMatch.enableMatch()

@ -14,6 +14,7 @@ struct TeamPickerView: View {
@State private var confirmTeam: TeamRegistration? @State private var confirmTeam: TeamRegistration?
@State private var presentTeamPickerView: Bool = false @State private var presentTeamPickerView: Bool = false
@State private var searchField: String = "" @State private var searchField: String = ""
var shouldConfirm: Bool = false
var groupStagePosition: Int? = nil var groupStagePosition: Int? = nil
var luckyLosers: [TeamRegistration] = [] var luckyLosers: [TeamRegistration] = []
let teamPicked: ((TeamRegistration) -> (Void)) let teamPicked: ((TeamRegistration) -> (Void))
@ -26,7 +27,7 @@ struct TeamPickerView: View {
} }
var body: some View { var body: some View {
Button { ConfirmButtonView(shouldConfirm: shouldConfirm, message: MatchSetupView.confirmationMessage) {
presentTeamPickerView = true presentTeamPickerView = true
} label: { } label: {
Text("Choisir") Text("Choisir")

@ -34,6 +34,8 @@ struct AddTeamView: View {
@State private var autoSelect: Bool = false @State private var autoSelect: Bool = false
@State private var presentationCount: Int = 0 @State private var presentationCount: Int = 0
@State private var confirmDuplicate: Bool = false @State private var confirmDuplicate: Bool = false
@State private var homonyms: [PlayerRegistration] = []
@State private var confirmHomonym: Bool = false
var tournamentStore: TournamentStore { var tournamentStore: TournamentStore {
return self.tournament.tournamentStore return self.tournament.tournamentStore
@ -66,9 +68,22 @@ struct AddTeamView: View {
var body: some View { var body: some View {
_buildingTeamView() _buildingTeamView()
.navigationBarBackButtonHidden(true) .navigationBarBackButtonHidden(true)
.alert("Présence d'homonyme", isPresented: $confirmHomonym) {
Button("Créer l'équipe quand même") {
_createTeam(checkDuplicates: false, checkHomonym: false)
}
Button("Annuler", role: .cancel) {
confirmHomonym = false
}
} message: {
let plural : String = homonyms.count > 1 ? "nt chacun" : ""
Text(homonyms.map({ $0.playerLabel() }).joined(separator: ", ") + " possède" + plural + " au moins un homonyme dans la base fédérale, vérifiez bien leur licence.")
}
.alert("Cette équipe existe déjà", isPresented: $confirmDuplicate) { .alert("Cette équipe existe déjà", isPresented: $confirmDuplicate) {
Button("Créer l'équipe quand même") { Button("Créer l'équipe quand même") {
_createTeam(checkDuplicates: false) _createTeam(checkDuplicates: false, checkHomonym: true)
} }
Button("Annuler", role: .cancel) { Button("Annuler", role: .cancel) {
@ -275,13 +290,22 @@ struct AddTeamView: View {
return false return false
} }
private func _createTeam(checkDuplicates: Bool) { private func _createTeam(checkDuplicates: Bool, checkHomonym: Bool) {
if checkDuplicates && _isDuplicate() { if checkDuplicates && _isDuplicate() {
confirmDuplicate = true confirmDuplicate = true
return return
} }
let players = _currentSelection() let players = _currentSelection()
if checkHomonym {
homonyms = players.filter({ $0.hasHomonym() })
if homonyms.isEmpty == false {
confirmHomonym = true
return
}
}
let team = tournament.addTeam(players) let team = tournament.addTeam(players)
do { do {
try self.tournamentStore.teamRegistrations.addOrUpdate(instance: team) try self.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
@ -368,11 +392,11 @@ struct AddTeamView: View {
if editedTeam == nil { if editedTeam == nil {
if createdPlayerIds.isEmpty { if createdPlayerIds.isEmpty {
RowButtonView("Bloquer une place") { RowButtonView("Bloquer une place") {
_createTeam(checkDuplicates: false) _createTeam(checkDuplicates: false, checkHomonym: false)
} }
} else { } else {
RowButtonView("Ajouter l'équipe") { RowButtonView("Ajouter l'équipe") {
_createTeam(checkDuplicates: true) _createTeam(checkDuplicates: true, checkHomonym: true)
} }
} }
} else { } else {

@ -21,6 +21,7 @@ struct InscriptionInfoView: View {
@State private var playersWithoutValidLicense : [PlayerRegistration] = [] @State private var playersWithoutValidLicense : [PlayerRegistration] = []
@State private var entriesFromBeachPadel : [TeamRegistration] = [] @State private var entriesFromBeachPadel : [TeamRegistration] = []
@State private var playersMissing : [TeamRegistration] = [] @State private var playersMissing : [TeamRegistration] = []
@State private var homonyms : [PlayerRegistration] = []
var body: some View { var body: some View {
List { List {
@ -126,6 +127,22 @@ struct InscriptionInfoView: View {
.listRowView(color: .logoRed) .listRowView(color: .logoRed)
} }
Section {
DisclosureGroup {
ForEach(homonyms) { player in
ImportedPlayerView(player: player)
}
} label: {
LabeledContent {
Text(homonyms.count.formatted())
} label: {
Text("Homonymes")
}
}
.listRowView(color: .logoRed)
}
Section { Section {
DisclosureGroup { DisclosureGroup {
ForEach(problematicPlayers) { player in ForEach(problematicPlayers) { player in
@ -208,6 +225,7 @@ struct InscriptionInfoView: View {
callDateIssue = selectedTeams.filter { $0.callDate != nil && tournament.isStartDateIsDifferentThanCallDate($0) } callDateIssue = selectedTeams.filter { $0.callDate != nil && tournament.isStartDateIsDifferentThanCallDate($0) }
waitingList = tournament.waitingListTeams(in: selectedTeams, includingWalkOuts: true) waitingList = tournament.waitingListTeams(in: selectedTeams, includingWalkOuts: true)
duplicates = tournament.duplicates(in: players) duplicates = tournament.duplicates(in: players)
homonyms = tournament.homonyms(in: players)
problematicPlayers = players.filter({ $0.sex == nil }) problematicPlayers = players.filter({ $0.sex == nil })
inadequatePlayers = tournament.inadequatePlayers(in: players) inadequatePlayers = tournament.inadequatePlayers(in: players)
playersWithoutValidLicense = tournament.playersWithoutValidLicense(in: players) playersWithoutValidLicense = tournament.playersWithoutValidLicense(in: players)

Loading…
Cancel
Save