From e7d8a8c1f93595fff7edfddb3da1d307376e149e Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 17 Jun 2024 18:26:43 +0200 Subject: [PATCH 1/4] add custom importing --- PadelClub/Data/Tournament.swift | 2 +- PadelClub/Utils/FileImportManager.swift | 72 +++++-------------- .../Team/Components/TeamHeaderView.swift | 2 +- .../Views/Tournament/FileImportView.swift | 18 ++++- .../Screen/TournamentCashierView.swift | 2 +- 5 files changed, 38 insertions(+), 58 deletions(-) diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 2aafb28..fe373b6 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -837,7 +837,7 @@ class Tournament : ModelObject, Storable { } else if index - bracketCut() < groupStageCut() { return "Poule" } else { - return "Liste d'attente" + return "Attente" } } diff --git a/PadelClub/Utils/FileImportManager.swift b/PadelClub/Utils/FileImportManager.swift index f04cb66..c7f3e33 100644 --- a/PadelClub/Utils/FileImportManager.swift +++ b/PadelClub/Utils/FileImportManager.swift @@ -377,67 +377,31 @@ class FileImportManager { } private func _getPadelBusinessLeagueTeams(from fileContent: String, tournament: Tournament) async -> [TeamHolder] { - let lines = fileContent.components(separatedBy: "\n") + let lines = fileContent.replacingOccurrences(of: "\"", with: "").components(separatedBy: "\n") guard let firstLine = lines.first else { return [] } var separator = "," if firstLine.contains(";") { separator = ";" } - let headerCount = firstLine.components(separatedBy: separator).count - var results: [TeamHolder] = [] - if headerCount == 23 { - //todo - let fetchRequest = ImportedPlayer.fetchRequest() - let federalContext = PersistenceController.shared.localContainer.viewContext - - lines.dropFirst().forEach { line in - let data = line.components(separatedBy: separator) - if data.count == 23 { - -// let team = Team(context: context) -// let brand = Brand(context: context) -// brand.title = data[2].trimmed -// brand.qualifier = data[0].trimmed -// brand.country = data[1].trimmed -// brand.lineOfBusiness = data[3].trimmed -// if brand.lineOfBusiness == "Bâtiment / Immo" { //quick fix -// brand.lineOfBusiness = "Bâtiment / Immo / Transport" -// } -// brand.name = data[4].trimmed -// team.brand = brand -// -// for i in 0...5 { -// let sex = data[i*3+5] -// let lastName = data[i*3+6].trimmed -// let firstName = data[i*3+7].trimmed -// if lastName.isEmpty == false { -// let playerOne = Player(context: context) -// let predicate = NSPredicate(format: "(canonicalLastName matches[cd] %@ OR canonicalLastName matches[cd] %@) AND (canonicalFirstName matches[cd] %@ OR canonicalFirstName matches[cd] %@)", lastName, lastName.removePunctuationAndHyphens, firstName, firstName.removePunctuationAndHyphens) -// fetchRequest.predicate = predicate -// if let playerFound = try? federalContext.fetch(fetchRequest).first { -// playerOne.updateWithImportedPlayer(playerFound) -// } else { -// playerOne.lastName = lastName -// playerOne.firstName = firstName -// playerOne.sex = sex == "H" ? 1 : sex == "F" ? 0 : -1 -// playerOne.currentRank = tournament?.lastRankMan ?? 0 -// } -// team.addToPlayers(playerOne) -// } -// } -// team.category = TournamentCategory.men.importingRawValue -// -// if let players = team.players, players.count > 0 { -// results.append(team) -// } else { -// context.delete(team) -// } + let results: [TeamHolder] = lines.chunked(into: 2).map { team in + var teamName: String? = nil + let players = team.map { player in + let data = player.components(separatedBy: separator) + let firstName : String = data[safe: 2]?.trimmed ?? "" + let lastName : String = data[safe: 3]?.trimmed ?? "" + let sex: PlayerRegistration.PlayerSexType = data[safe: 0] == "f" ? PlayerRegistration.PlayerSexType.female : PlayerRegistration.PlayerSexType.male + if data[safe: 1]?.trimmed != nil { + teamName = data[safe: 1]?.trimmed } + let phoneNumber : String? = data[safe: 4]?.trimmed + let email : String? = data[safe: 5]?.trimmed + //let level : String? = data[safe: 6]?.trimmed + let player = PlayerRegistration(firstName: firstName, lastName: lastName, sex: sex, phoneNumber: phoneNumber, email: email) + return player } - - - return results + + return TeamHolder(players: players, tournamentCategory: .men, previousTeam: nil, name: teamName, tournament: tournament) } - return [] + return results } } diff --git a/PadelClub/Views/Team/Components/TeamHeaderView.swift b/PadelClub/Views/Team/Components/TeamHeaderView.swift index b5b7679..b417e16 100644 --- a/PadelClub/Views/Team/Components/TeamHeaderView.swift +++ b/PadelClub/Views/Team/Components/TeamHeaderView.swift @@ -22,7 +22,7 @@ struct TeamHeaderView: View { } if team.unsortedPlayers().isEmpty == false { - if tournament?.hideWeight() == false { + if tournament?.hideWeight() == false, team.weight > 0 { VStack(alignment: .leading, spacing: 0) { Text("Poids").font(.caption) Text(team.weight.formatted()) diff --git a/PadelClub/Views/Tournament/FileImportView.swift b/PadelClub/Views/Tournament/FileImportView.swift index 99b856c..54df424 100644 --- a/PadelClub/Views/Tournament/FileImportView.swift +++ b/PadelClub/Views/Tournament/FileImportView.swift @@ -34,6 +34,16 @@ struct FileImportView: View { return teams.filter { $0.tournamentCategory == tournament.tournamentCategory }.sorted(by: \.weight) } + private func _deleteTeams() async { + await MainActor.run { + do { + try dataStore.teamRegistrations.delete(contentOfs: tournament.unsortedTeams()) + } catch { + Logger.error(error) + } + } + } + var body: some View { List { if teams.isEmpty { @@ -44,6 +54,12 @@ struct FileImportView: View { } } + if tournament.unsortedTeams().count > 0 { + RowButtonView("Effacer les équipes déjà inscrites", role: .destructive) { + await _deleteTeams() + } + } + Section { Picker(selection: $fileProvider) { ForEach(FileImportManager.FileProvider.allCases) { @@ -222,7 +238,7 @@ struct FileImportView: View { teams.removeAll() Task { do { - if selectedFile.lastPathComponent.hasSuffix("xls") { + if selectedFile.lastPathComponent.hasSuffix("xls") || selectedFile.lastPathComponent.hasSuffix("xlsx") { convertingFile = true fileContent = try await CloudConvert.manager.uploadFile(selectedFile) convertingFile = false diff --git a/PadelClub/Views/Tournament/Screen/TournamentCashierView.swift b/PadelClub/Views/Tournament/Screen/TournamentCashierView.swift index 524cece..5e0aef3 100644 --- a/PadelClub/Views/Tournament/Screen/TournamentCashierView.swift +++ b/PadelClub/Views/Tournament/Screen/TournamentCashierView.swift @@ -58,7 +58,7 @@ enum CashierDestination: Identifiable, Selectable, Equatable { case .bracket(let round): let playerRegistrations: [PlayerRegistration] = round.seeds().flatMap { $0.unsortedPlayers() } return playerRegistrations.filter({ $0.hasPaid() == false }).count - case .all(let tournament): + case .all(_): return nil } } From 4f7278e4a0f8df554cd06644a397a48794fde6b1 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 17 Jun 2024 18:27:15 +0200 Subject: [PATCH 2/4] b54 --- PadelClub.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index e97860c..c960292 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -1859,7 +1859,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 54; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; @@ -1897,7 +1897,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 54; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; From 495b6791610946776dcd6e113f82e0523bbfd32b Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Tue, 18 Jun 2024 09:36:07 +0200 Subject: [PATCH 3/4] add crashlytics --- PadelClub.xcodeproj/project.pbxproj | 50 +++++++++++++++++++++++++++++ PadelClub/GoogleService-Info.plist | 30 +++++++++++++++++ PadelClub/PadelClubApp.swift | 11 ++++++- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 PadelClub/GoogleService-Info.plist diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index c960292..7146870 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -235,6 +235,8 @@ FFDB1C6D2BB2A02000F1E467 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDB1C6C2BB2A02000F1E467 /* AppSettings.swift */; }; FFDB1C732BB2CFE900F1E467 /* MySortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDB1C722BB2CFE900F1E467 /* MySortDescriptor.swift */; }; FFDDD40C2B93B2BB00C91A49 /* DeferredViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDDD40B2B93B2BB00C91A49 /* DeferredViewModifier.swift */; }; + FFE2D2D52C216B5000D0C7BE /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = FFE2D2D42C216B5000D0C7BE /* FirebaseCrashlytics */; }; + FFE2D2D82C216D4800D0C7BE /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = FFE2D2D72C216D4800D0C7BE /* GoogleService-Info.plist */; }; FFEF7F4E2BDE69130033D0F0 /* MenuWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */; }; FFF0241E2BF48B15001F14B4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = FFF0241D2BF48B15001F14B4 /* Localizable.strings */; }; FFF03C942BD91D0C00B516FC /* ButtonValidateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF03C932BD91D0C00B516FC /* ButtonValidateView.swift */; }; @@ -559,6 +561,7 @@ FFDB1C6C2BB2A02000F1E467 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; FFDB1C722BB2CFE900F1E467 /* MySortDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySortDescriptor.swift; sourceTree = ""; }; FFDDD40B2B93B2BB00C91A49 /* DeferredViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeferredViewModifier.swift; sourceTree = ""; }; + FFE2D2D72C216D4800D0C7BE /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuWarningView.swift; sourceTree = ""; }; FFF0241C2BF48B15001F14B4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; FFF0241F2BF48B1A001F14B4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -584,6 +587,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + FFE2D2D52C216B5000D0C7BE /* FirebaseCrashlytics in Frameworks */, FFCFBFFE2BBBE86600B82851 /* Algorithms in Frameworks */, C49EF0392BDFF4600077B5AA /* LeStorage.framework in Frameworks */, ); @@ -630,6 +634,7 @@ C425D3FF2B6D249D002A7B48 /* PadelClub */ = { isa = PBXGroup; children = ( + FFE2D2D72C216D4800D0C7BE /* GoogleService-Info.plist */, FF0CA5742BDA4AE10080E843 /* PrivacyInfo.xcprivacy */, FFA6D78A2BB0BEB3003A31F3 /* Info.plist */, C4EC6F562BE92CAC000CEAB4 /* local.plist */, @@ -1322,6 +1327,7 @@ C425D3FA2B6D249D002A7B48 /* Frameworks */, C425D3FB2B6D249D002A7B48 /* Resources */, FF2BE4892B85E27400592328 /* Embed Frameworks */, + FFE2D2D62C216C1700D0C7BE /* ShellScript */, ); buildRules = ( ); @@ -1330,6 +1336,7 @@ name = PadelClub; packageProductDependencies = ( FFCFBFFD2BBBE86600B82851 /* Algorithms */, + FFE2D2D42C216B5000D0C7BE /* FirebaseCrashlytics */, ); productName = PadelClub; productReference = C425D3FD2B6D249D002A7B48 /* PadelClub.app */; @@ -1406,6 +1413,7 @@ mainGroup = C425D3F42B6D249D002A7B48; packageReferences = ( FF4C7F052BBBE6B90031B6A3 /* XCRemoteSwiftPackageReference "swift-algorithms" */, + FFE2D2D32C216B5000D0C7BE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); productRefGroup = C425D3FE2B6D249D002A7B48 /* Products */; projectDirPath = ""; @@ -1434,6 +1442,7 @@ FF1F4B892BFA02A4000B4573 /* groupstagecol-template.html in Resources */, FF1F4B8A2BFA02A4000B4573 /* groupstage-template.html in Resources */, FF1F4B8B2BFA02A4000B4573 /* groupstageentrant-template.html in Resources */, + FFE2D2D82C216D4800D0C7BE /* GoogleService-Info.plist in Resources */, FF1F4B8C2BFA02A4000B4573 /* match-template.html in Resources */, FFF0241E2BF48B15001F14B4 /* Localizable.strings in Resources */, C45BAE3B2BC6DF10002EEC8A /* SyncedProducts.storekit in Resources */, @@ -1459,6 +1468,31 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + FFE2D2D62C216C1700D0C7BE /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}", + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}", + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist", + "$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist", + "$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)", + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\"\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ C425D3F92B6D249D002A7B48 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -1860,6 +1894,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 54; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; @@ -1882,6 +1917,7 @@ ); MARKETING_VERSION = 0.1; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + OTHER_LDFLAGS = "-ObjC"; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1920,6 +1956,7 @@ ); MARKETING_VERSION = 0.1; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + OTHER_LDFLAGS = "-ObjC"; 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_NAME = "$(TARGET_NAME)"; @@ -2055,6 +2092,14 @@ minimumVersion = 1.2.0; }; }; + FFE2D2D32C216B5000D0C7BE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 10.28.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -2063,6 +2108,11 @@ package = FF4C7F052BBBE6B90031B6A3 /* XCRemoteSwiftPackageReference "swift-algorithms" */; productName = Algorithms; }; + FFE2D2D42C216B5000D0C7BE /* FirebaseCrashlytics */ = { + isa = XCSwiftPackageProductDependency; + package = FFE2D2D32C216B5000D0C7BE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseCrashlytics; + }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/PadelClub/GoogleService-Info.plist b/PadelClub/GoogleService-Info.plist new file mode 100644 index 0000000..eae9408 --- /dev/null +++ b/PadelClub/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyAjZC_NmXtQzK5dotExlQjU66fTNylNMII + GCM_SENDER_ID + 404879692726 + PLIST_VERSION + 1 + BUNDLE_ID + app.padelclub + PROJECT_ID + padel-club-8e872 + STORAGE_BUCKET + padel-club-8e872.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:404879692726:ios:90e65a062285ac3dd46717 + + \ No newline at end of file diff --git a/PadelClub/PadelClubApp.swift b/PadelClub/PadelClubApp.swift index 1b760f9..c79c829 100644 --- a/PadelClub/PadelClubApp.swift +++ b/PadelClub/PadelClubApp.swift @@ -8,13 +8,15 @@ import SwiftUI import LeStorage import TipKit +import FirebaseCore @main struct PadelClubApp: App { let persistenceController = PersistenceController.shared @State private var navigationViewModel = NavigationViewModel() @StateObject var networkMonitor: NetworkMonitor = NetworkMonitor() - + @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate + static var appVersion: String { let dictionary = Bundle.main.infoDictionary! let version = dictionary["CFBundleShortVersionString"] as! String @@ -52,3 +54,10 @@ struct PadelClubApp: App { } } + +class AppDelegate: NSObject, UIApplicationDelegate { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { + FirebaseApp.configure() + return true + } +} From 5db253e9f523b0cb62d78f09d5f3c65a7d6c8740 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Tue, 18 Jun 2024 10:51:27 +0200 Subject: [PATCH 4/4] b55 --- PadelClub.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index 7146870..7e3ed59 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -1893,7 +1893,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; @@ -1933,7 +1933,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6;