diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index b10499b..10ac1be 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -79,7 +79,7 @@ FF1162832BCFBE4E000C4809 /* EditablePlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162822BCFBE4E000C4809 /* EditablePlayerView.swift */; }; FF1162852BD00279000C4809 /* PlayerDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162842BD00279000C4809 /* PlayerDetailView.swift */; }; FF1162872BD004AD000C4809 /* EditingTeamView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162862BD004AD000C4809 /* EditingTeamView.swift */; }; - FF11628A2BD05247000C4809 /* DateUpdateManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162892BD05247000C4809 /* DateUpdateManagerView.swift */; }; + FF11628A2BD05247000C4809 /* DatePickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162892BD05247000C4809 /* DatePickingView.swift */; }; FF11628C2BD05267000C4809 /* LoserRoundStepScheduleEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF11628B2BD05267000C4809 /* LoserRoundStepScheduleEditorView.swift */; }; FF17CA492CB915A1003C7323 /* MultiCourtPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF17CA482CB915A1003C7323 /* MultiCourtPickerView.swift */; }; FF17CA4A2CB915A1003C7323 /* MultiCourtPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF17CA482CB915A1003C7323 /* MultiCourtPickerView.swift */; }; @@ -294,8 +294,8 @@ FF4CBFE02C996C0600151637 /* TournamentFieldsManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26462BAE0ACB00650388 /* TournamentFieldsManagerView.swift */; }; FF4CBFE12C996C0600151637 /* PrintSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B812BFA0124000B4573 /* PrintSettingsView.swift */; }; FF4CBFE22C996C0600151637 /* TournamentMatchFormatsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF025AE22BD0EBA900A86CF8 /* TournamentMatchFormatsSettingsView.swift */; }; - FF4CBFE32C996C0600151637 /* DateUpdateManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162892BD05247000C4809 /* DateUpdateManagerView.swift */; }; - FF4CBFE42C996C0600151637 /* MatchTypeSmallSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */; }; + FF4CBFE32C996C0600151637 /* DatePickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162892BD05247000C4809 /* DatePickingView.swift */; }; + FF4CBFE42C996C0600151637 /* MatchFormatRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchFormatRowView.swift */; }; FF4CBFE52C996C0600151637 /* MonthData.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF025AE82BD1307E00A86CF8 /* MonthData.swift */; }; FF4CBFE62C996C0600151637 /* MenuWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */; }; FF4CBFE72C996C0600151637 /* TournamentBuildView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */; }; @@ -351,7 +351,7 @@ FF4CC0192C996C0600151637 /* EventSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */; }; FF4CC01A2C996C0600151637 /* InscriptionInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D772BB42C5B005CB568 /* InscriptionInfoView.swift */; }; FF4CC01B2C996C0600151637 /* SelectablePlayerListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF4AB6BC2B9256E10002987F /* SelectablePlayerListView.swift */; }; - FF4CC01C2C996C0600151637 /* MatchFormatPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26502BAE0BAD00650388 /* MatchFormatPickerView.swift */; }; + FF4CC01C2C996C0600151637 /* MatchFormatSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26502BAE0BAD00650388 /* MatchFormatSelectionView.swift */; }; FF4CC01D2C996C0600151637 /* TournamentRankView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5BAF712BE19274008B4B7E /* TournamentRankView.swift */; }; FF4CC01E2C996C0600151637 /* NumberFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */; }; FF4CC01F2C996C0600151637 /* SetLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0172BBC5A6800B82851 /* SetLabelView.swift */; }; @@ -606,8 +606,8 @@ FF70FB5F2C90584900129CC2 /* TournamentFieldsManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26462BAE0ACB00650388 /* TournamentFieldsManagerView.swift */; }; FF70FB602C90584900129CC2 /* PrintSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B812BFA0124000B4573 /* PrintSettingsView.swift */; }; FF70FB612C90584900129CC2 /* TournamentMatchFormatsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF025AE22BD0EBA900A86CF8 /* TournamentMatchFormatsSettingsView.swift */; }; - FF70FB622C90584900129CC2 /* DateUpdateManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162892BD05247000C4809 /* DateUpdateManagerView.swift */; }; - FF70FB632C90584900129CC2 /* MatchTypeSmallSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */; }; + FF70FB622C90584900129CC2 /* DatePickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1162892BD05247000C4809 /* DatePickingView.swift */; }; + FF70FB632C90584900129CC2 /* MatchFormatRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchFormatRowView.swift */; }; FF70FB642C90584900129CC2 /* MonthData.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF025AE82BD1307E00A86CF8 /* MonthData.swift */; }; FF70FB652C90584900129CC2 /* MenuWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */; }; FF70FB662C90584900129CC2 /* TournamentBuildView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */; }; @@ -663,7 +663,7 @@ FF70FB982C90584900129CC2 /* EventSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */; }; FF70FB992C90584900129CC2 /* InscriptionInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D772BB42C5B005CB568 /* InscriptionInfoView.swift */; }; FF70FB9A2C90584900129CC2 /* SelectablePlayerListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF4AB6BC2B9256E10002987F /* SelectablePlayerListView.swift */; }; - FF70FB9B2C90584900129CC2 /* MatchFormatPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26502BAE0BAD00650388 /* MatchFormatPickerView.swift */; }; + FF70FB9B2C90584900129CC2 /* MatchFormatSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26502BAE0BAD00650388 /* MatchFormatSelectionView.swift */; }; FF70FB9C2C90584900129CC2 /* TournamentRankView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5BAF712BE19274008B4B7E /* TournamentRankView.swift */; }; FF70FB9D2C90584900129CC2 /* NumberFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */; }; FF70FB9E2C90584900129CC2 /* SetLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0172BBC5A6800B82851 /* SetLabelView.swift */; }; @@ -709,6 +709,15 @@ FF70FBC82C90584900129CC2 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = FF0CA5742BDA4AE10080E843 /* PrivacyInfo.xcprivacy */; }; FF70FBC92C90584900129CC2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C425D4042B6D249E002A7B48 /* Assets.xcassets */; }; FF70FBCB2C90584900129CC2 /* LeStorage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C49EF0372BDFF3000077B5AA /* LeStorage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + FF77CE522CCCD1B200CBCBB4 /* MatchFormatPickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE512CCCD1AF00CBCBB4 /* MatchFormatPickingView.swift */; }; + FF77CE532CCCD1B200CBCBB4 /* MatchFormatPickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE512CCCD1AF00CBCBB4 /* MatchFormatPickingView.swift */; }; + FF77CE542CCCD1B200CBCBB4 /* MatchFormatPickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE512CCCD1AF00CBCBB4 /* MatchFormatPickingView.swift */; }; + FF77CE562CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE552CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift */; }; + FF77CE572CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE552CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift */; }; + FF77CE582CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE552CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift */; }; + FF77CE5A2CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE592CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift */; }; + FF77CE5B2CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE592CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift */; }; + FF77CE5C2CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF77CE592CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift */; }; FF7DCD392CC330270041110C /* TeamRestingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF7DCD382CC330260041110C /* TeamRestingView.swift */; }; FF7DCD3A2CC330270041110C /* TeamRestingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF7DCD382CC330260041110C /* TeamRestingView.swift */; }; FF7DCD3B2CC330270041110C /* TeamRestingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF7DCD382CC330260041110C /* TeamRestingView.swift */; }; @@ -728,7 +737,7 @@ FF8F264C2BAE0B4100650388 /* TournamentFormatSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26482BAE0B4100650388 /* TournamentFormatSelectionView.swift */; }; FF8F264D2BAE0B4100650388 /* TournamentDatePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F264A2BAE0B4100650388 /* TournamentDatePickerView.swift */; }; FF8F264F2BAE0B9600650388 /* MatchTypeSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F264E2BAE0B9600650388 /* MatchTypeSelectionView.swift */; }; - FF8F26512BAE0BAD00650388 /* MatchFormatPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26502BAE0BAD00650388 /* MatchFormatPickerView.swift */; }; + FF8F26512BAE0BAD00650388 /* MatchFormatSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26502BAE0BAD00650388 /* MatchFormatSelectionView.swift */; }; FF8F26542BAE1E4400650388 /* TableStructureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF8F26532BAE1E4400650388 /* TableStructureView.swift */; }; FF90FC1D2C44FB3E009339B2 /* AddTeamView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF90FC1C2C44FB3E009339B2 /* AddTeamView.swift */; }; FF92660D2C241CE0002361A4 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = FF92660C2C241CE0002361A4 /* Zip */; }; @@ -797,7 +806,7 @@ FFCFC0142BBC59FC00B82851 /* MatchDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0132BBC59FC00B82851 /* MatchDescriptor.swift */; }; FFCFC0162BBC5A4C00B82851 /* SetInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0152BBC5A4C00B82851 /* SetInputView.swift */; }; FFCFC0182BBC5A6800B82851 /* SetLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0172BBC5A6800B82851 /* SetLabelView.swift */; }; - FFCFC01A2BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */; }; + FFCFC01A2BBC5A8500B82851 /* MatchFormatRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC0192BBC5A8500B82851 /* MatchFormatRowView.swift */; }; FFCFC01C2BBC5AAA00B82851 /* SetDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFCFC01B2BBC5AAA00B82851 /* SetDescriptor.swift */; }; FFD655D82C8DE27400E5B35E /* TournamentLookUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD655D72C8DE27400E5B35E /* TournamentLookUpView.swift */; }; FFD783FF2B91BA42000F62A6 /* PadelClubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD783FE2B91BA42000F62A6 /* PadelClubView.swift */; }; @@ -999,7 +1008,7 @@ FF1162822BCFBE4E000C4809 /* EditablePlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditablePlayerView.swift; sourceTree = ""; }; FF1162842BD00279000C4809 /* PlayerDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerDetailView.swift; sourceTree = ""; }; FF1162862BD004AD000C4809 /* EditingTeamView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditingTeamView.swift; sourceTree = ""; }; - FF1162892BD05247000C4809 /* DateUpdateManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateUpdateManagerView.swift; sourceTree = ""; }; + FF1162892BD05247000C4809 /* DatePickingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickingView.swift; sourceTree = ""; }; FF11628B2BD05267000C4809 /* LoserRoundStepScheduleEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoserRoundStepScheduleEditorView.swift; sourceTree = ""; }; FF17CA482CB915A1003C7323 /* MultiCourtPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiCourtPickerView.swift; sourceTree = ""; }; FF17CA4C2CB9243E003C7323 /* FollowUpMatchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowUpMatchView.swift; sourceTree = ""; }; @@ -1093,6 +1102,9 @@ FF70916B2B91005400AB08DA /* TournamentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentView.swift; sourceTree = ""; }; FF70916D2B9108C600AB08DA /* InscriptionManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InscriptionManagerView.swift; sourceTree = ""; }; FF70FBCF2C90584900129CC2 /* PadelClub TestFlight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "PadelClub TestFlight.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + FF77CE512CCCD1AF00CBCBB4 /* MatchFormatPickingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchFormatPickingView.swift; sourceTree = ""; }; + FF77CE552CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickingViewWithFormat.swift; sourceTree = ""; }; + FF77CE592CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupStageDatePickingView.swift; sourceTree = ""; }; FF7DCD382CC330260041110C /* TeamRestingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamRestingView.swift; sourceTree = ""; }; FF8044AB2C8F676D00A49A52 /* TournamentSubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentSubscriptionView.swift; sourceTree = ""; }; FF82CFC42B911F5B00B0CAF2 /* OrganizedTournamentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrganizedTournamentView.swift; sourceTree = ""; }; @@ -1110,7 +1122,7 @@ FF8F26492BAE0B4100650388 /* TournamentLevelPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentLevelPickerView.swift; sourceTree = ""; }; FF8F264A2BAE0B4100650388 /* TournamentDatePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentDatePickerView.swift; sourceTree = ""; }; FF8F264E2BAE0B9600650388 /* MatchTypeSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchTypeSelectionView.swift; sourceTree = ""; }; - FF8F26502BAE0BAD00650388 /* MatchFormatPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchFormatPickerView.swift; sourceTree = ""; }; + FF8F26502BAE0BAD00650388 /* MatchFormatSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchFormatSelectionView.swift; sourceTree = ""; }; FF8F26532BAE1E4400650388 /* TableStructureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableStructureView.swift; sourceTree = ""; }; FF90FC1C2C44FB3E009339B2 /* AddTeamView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTeamView.swift; sourceTree = ""; }; FF92660F2C255E4A002361A4 /* PadelClub.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PadelClub.entitlements; sourceTree = ""; }; @@ -1178,7 +1190,7 @@ FFCFC0132BBC59FC00B82851 /* MatchDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchDescriptor.swift; sourceTree = ""; }; FFCFC0152BBC5A4C00B82851 /* SetInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetInputView.swift; sourceTree = ""; }; FFCFC0172BBC5A6800B82851 /* SetLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetLabelView.swift; sourceTree = ""; }; - FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchTypeSmallSelectionView.swift; sourceTree = ""; }; + FFCFC0192BBC5A8500B82851 /* MatchFormatRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchFormatRowView.swift; sourceTree = ""; }; FFCFC01B2BBC5AAA00B82851 /* SetDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetDescriptor.swift; sourceTree = ""; }; FFD655D72C8DE27400E5B35E /* TournamentLookUpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentLookUpView.swift; sourceTree = ""; }; FFD783FE2B91BA42000F62A6 /* PadelClubView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PadelClubView.swift; sourceTree = ""; }; @@ -1546,7 +1558,10 @@ FF1162882BD0523B000C4809 /* Components */ = { isa = PBXGroup; children = ( - FF1162892BD05247000C4809 /* DateUpdateManagerView.swift */, + FF1162892BD05247000C4809 /* DatePickingView.swift */, + FF77CE592CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift */, + FF77CE552CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift */, + FF77CE512CCCD1AF00CBCBB4 /* MatchFormatPickingView.swift */, FF17CA482CB915A1003C7323 /* MultiCourtPickerView.swift */, ); path = Components; @@ -1724,11 +1739,11 @@ isa = PBXGroup; children = ( FF8F264E2BAE0B9600650388 /* MatchTypeSelectionView.swift */, - FF8F26502BAE0BAD00650388 /* MatchFormatPickerView.swift */, + FF8F26502BAE0BAD00650388 /* MatchFormatSelectionView.swift */, FF4AB6BC2B9256E10002987F /* SelectablePlayerListView.swift */, FF4AB6BE2B92577A0002987F /* ImportedPlayerView.swift */, FF5D0D6F2BB3EFA5005CB568 /* LearnMoreSheetView.swift */, - FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */, + FFCFC0192BBC5A8500B82851 /* MatchFormatRowView.swift */, FF663FBD2BE019EC0031AE83 /* TournamentFilterView.swift */, FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */, FFE103112C366E5900684FC9 /* ImagePickerView.swift */, @@ -2264,6 +2279,7 @@ FF7091662B90F0B000AB08DA /* TabDestination.swift in Sources */, FF9267F82BCE78C70080F940 /* CashierView.swift in Sources */, FF8F263F2BAD7D5C00650388 /* Event.swift in Sources */, + FF77CE562CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift in Sources */, FF5D30532BD94E2E00F2B93D /* PlayerHolder.swift in Sources */, FF11628C2BD05267000C4809 /* LoserRoundStepScheduleEditorView.swift in Sources */, FF53FBB82BFB302B0051D4C3 /* ClubCourtSetupView.swift in Sources */, @@ -2416,6 +2432,7 @@ FFC1E1042BAC28C6008D6F59 /* ClubSearchView.swift in Sources */, FF089EBB2BB0120700F0AEC7 /* PlayerPopoverView.swift in Sources */, FF70916E2B9108C600AB08DA /* InscriptionManagerView.swift in Sources */, + FF77CE542CCCD1B200CBCBB4 /* MatchFormatPickingView.swift in Sources */, FF82CFC92B9132AF00B0CAF2 /* ActivityView.swift in Sources */, FFDB1C732BB2CFE900F1E467 /* MySortDescriptor.swift in Sources */, FF5D0D8B2BB4D1E3005CB568 /* CalendarView.swift in Sources */, @@ -2423,8 +2440,8 @@ FF8F26472BAE0ACB00650388 /* TournamentFieldsManagerView.swift in Sources */, FF1F4B822BFA0124000B4573 /* PrintSettingsView.swift in Sources */, FF025AE32BD0EBA900A86CF8 /* TournamentMatchFormatsSettingsView.swift in Sources */, - FF11628A2BD05247000C4809 /* DateUpdateManagerView.swift in Sources */, - FFCFC01A2BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift in Sources */, + FF11628A2BD05247000C4809 /* DatePickingView.swift in Sources */, + FFCFC01A2BBC5A8500B82851 /* MatchFormatRowView.swift in Sources */, FF025AE92BD1307F00A86CF8 /* MonthData.swift in Sources */, FFEF7F4E2BDE69130033D0F0 /* MenuWarningView.swift in Sources */, FF1F4B6D2BF9E60B000B4573 /* TournamentBuildView.swift in Sources */, @@ -2485,8 +2502,9 @@ FFBF41862BF75FDA001B24CB /* EventSettingsView.swift in Sources */, FF5D0D782BB42C5B005CB568 /* InscriptionInfoView.swift in Sources */, FF4AB6BD2B9256E10002987F /* SelectablePlayerListView.swift in Sources */, - FF8F26512BAE0BAD00650388 /* MatchFormatPickerView.swift in Sources */, + FF8F26512BAE0BAD00650388 /* MatchFormatSelectionView.swift in Sources */, FF5BAF722BE19274008B4B7E /* TournamentRankView.swift in Sources */, + FF77CE5B2CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift in Sources */, FF5D0D872BB48AFD005CB568 /* NumberFormatter+Extensions.swift in Sources */, FFCFC0182BBC5A6800B82851 /* SetLabelView.swift in Sources */, C4489BE22C05BF5000043F3D /* DebugSettingsView.swift in Sources */, @@ -2541,6 +2559,7 @@ FF4CBF452C996C0600151637 /* TabDestination.swift in Sources */, FF4CBF462C996C0600151637 /* CashierView.swift in Sources */, FF4CBF472C996C0600151637 /* Event.swift in Sources */, + FF77CE582CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift in Sources */, FF4CBF482C996C0600151637 /* PlayerHolder.swift in Sources */, FF4CBF492C996C0600151637 /* LoserRoundStepScheduleEditorView.swift in Sources */, FF4CBF4A2C996C0600151637 /* ClubCourtSetupView.swift in Sources */, @@ -2693,6 +2712,7 @@ FF4CBFD92C996C0600151637 /* ClubSearchView.swift in Sources */, FF4CBFDA2C996C0600151637 /* PlayerPopoverView.swift in Sources */, FF4CBFDB2C996C0600151637 /* InscriptionManagerView.swift in Sources */, + FF77CE522CCCD1B200CBCBB4 /* MatchFormatPickingView.swift in Sources */, FF4CBFDC2C996C0600151637 /* ActivityView.swift in Sources */, FF4CBFDD2C996C0600151637 /* MySortDescriptor.swift in Sources */, FF4CBFDE2C996C0600151637 /* CalendarView.swift in Sources */, @@ -2700,8 +2720,8 @@ FF4CBFE02C996C0600151637 /* TournamentFieldsManagerView.swift in Sources */, FF4CBFE12C996C0600151637 /* PrintSettingsView.swift in Sources */, FF4CBFE22C996C0600151637 /* TournamentMatchFormatsSettingsView.swift in Sources */, - FF4CBFE32C996C0600151637 /* DateUpdateManagerView.swift in Sources */, - FF4CBFE42C996C0600151637 /* MatchTypeSmallSelectionView.swift in Sources */, + FF4CBFE32C996C0600151637 /* DatePickingView.swift in Sources */, + FF4CBFE42C996C0600151637 /* MatchFormatRowView.swift in Sources */, FF4CBFE52C996C0600151637 /* MonthData.swift in Sources */, FF4CBFE62C996C0600151637 /* MenuWarningView.swift in Sources */, FF4CBFE72C996C0600151637 /* TournamentBuildView.swift in Sources */, @@ -2762,8 +2782,9 @@ FF4CC0192C996C0600151637 /* EventSettingsView.swift in Sources */, FF4CC01A2C996C0600151637 /* InscriptionInfoView.swift in Sources */, FF4CC01B2C996C0600151637 /* SelectablePlayerListView.swift in Sources */, - FF4CC01C2C996C0600151637 /* MatchFormatPickerView.swift in Sources */, + FF4CC01C2C996C0600151637 /* MatchFormatSelectionView.swift in Sources */, FF4CC01D2C996C0600151637 /* TournamentRankView.swift in Sources */, + FF77CE5C2CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift in Sources */, FF4CC01E2C996C0600151637 /* NumberFormatter+Extensions.swift in Sources */, FF4CC01F2C996C0600151637 /* SetLabelView.swift in Sources */, FF4CC0202C996C0600151637 /* DebugSettingsView.swift in Sources */, @@ -2797,6 +2818,7 @@ FF70FAC42C90584900129CC2 /* TabDestination.swift in Sources */, FF70FAC52C90584900129CC2 /* CashierView.swift in Sources */, FF70FAC62C90584900129CC2 /* Event.swift in Sources */, + FF77CE572CCCD1EB00CBCBB4 /* DatePickingViewWithFormat.swift in Sources */, FF70FAC72C90584900129CC2 /* PlayerHolder.swift in Sources */, FF70FAC82C90584900129CC2 /* LoserRoundStepScheduleEditorView.swift in Sources */, FF70FAC92C90584900129CC2 /* ClubCourtSetupView.swift in Sources */, @@ -2949,6 +2971,7 @@ FF70FB582C90584900129CC2 /* ClubSearchView.swift in Sources */, FF70FB592C90584900129CC2 /* PlayerPopoverView.swift in Sources */, FF70FB5A2C90584900129CC2 /* InscriptionManagerView.swift in Sources */, + FF77CE532CCCD1B200CBCBB4 /* MatchFormatPickingView.swift in Sources */, FF70FB5B2C90584900129CC2 /* ActivityView.swift in Sources */, FF70FB5C2C90584900129CC2 /* MySortDescriptor.swift in Sources */, FF70FB5D2C90584900129CC2 /* CalendarView.swift in Sources */, @@ -2956,8 +2979,8 @@ FF70FB5F2C90584900129CC2 /* TournamentFieldsManagerView.swift in Sources */, FF70FB602C90584900129CC2 /* PrintSettingsView.swift in Sources */, FF70FB612C90584900129CC2 /* TournamentMatchFormatsSettingsView.swift in Sources */, - FF70FB622C90584900129CC2 /* DateUpdateManagerView.swift in Sources */, - FF70FB632C90584900129CC2 /* MatchTypeSmallSelectionView.swift in Sources */, + FF70FB622C90584900129CC2 /* DatePickingView.swift in Sources */, + FF70FB632C90584900129CC2 /* MatchFormatRowView.swift in Sources */, FF70FB642C90584900129CC2 /* MonthData.swift in Sources */, FF70FB652C90584900129CC2 /* MenuWarningView.swift in Sources */, FF70FB662C90584900129CC2 /* TournamentBuildView.swift in Sources */, @@ -3018,8 +3041,9 @@ FF70FB982C90584900129CC2 /* EventSettingsView.swift in Sources */, FF70FB992C90584900129CC2 /* InscriptionInfoView.swift in Sources */, FF70FB9A2C90584900129CC2 /* SelectablePlayerListView.swift in Sources */, - FF70FB9B2C90584900129CC2 /* MatchFormatPickerView.swift in Sources */, + FF70FB9B2C90584900129CC2 /* MatchFormatSelectionView.swift in Sources */, FF70FB9C2C90584900129CC2 /* TournamentRankView.swift in Sources */, + FF77CE5A2CCCD1FF00CBCBB4 /* GroupStageDatePickingView.swift in Sources */, FF70FB9D2C90584900129CC2 /* NumberFormatter+Extensions.swift in Sources */, FF70FB9E2C90584900129CC2 /* SetLabelView.swift in Sources */, FF70FB9F2C90584900129CC2 /* DebugSettingsView.swift in Sources */, diff --git a/PadelClub/Utils/PadelRule.swift b/PadelClub/Utils/PadelRule.swift index d3b1d45..404899b 100644 --- a/PadelClub/Utils/PadelRule.swift +++ b/PadelClub/Utils/PadelRule.swift @@ -1135,19 +1135,24 @@ enum MatchType: String { case loserBracket = "loserBracket" } -enum MatchFormat: Int, Hashable, Codable, CaseIterable { +enum MatchFormat: Int, Hashable, Codable, CaseIterable, Identifiable { + var id: Int { self.rawValue } case twoSets case twoSetsSuperTie case twoSetsOfFourGames case nineGames case superTie case megaTie - + case twoSetsDecisivePoint case twoSetsDecisivePointSuperTie case twoSetsOfFourGamesDecisivePoint case nineGamesDecisivePoint + case twoSetsOfSuperTie + case singleSet + case singleSetDecisivePoint + init?(rawValue: Int?) { guard let value = rawValue else { return nil } self.init(rawValue: value) @@ -1156,7 +1161,7 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { func defaultWalkOutScore(_ asWalkOutTeam: Bool) -> [Int] { Array(repeating: asWalkOutTeam ? 0 : setFormat.scoreToWin, count: setsToWin) } - + var weight: Int { switch self { case .twoSets, .twoSetsDecisivePoint: @@ -1171,6 +1176,10 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return 4 case .megaTie: return 5 + case .twoSetsOfSuperTie: + return 6 + case .singleSet, .singleSetDecisivePoint: + return 7 } } @@ -1196,6 +1205,10 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return 4 case .megaTie: return 5 + case .twoSetsOfSuperTie: + return 6 + case .singleSet, .singleSetDecisivePoint: + return 7 } } @@ -1211,7 +1224,7 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { } static var allCases: [MatchFormat] { - [.twoSets, .twoSetsDecisivePoint, .twoSetsSuperTie, .twoSetsDecisivePointSuperTie, .twoSetsOfFourGames, .twoSetsOfFourGamesDecisivePoint, .nineGames, .nineGamesDecisivePoint, .superTie, .megaTie] + [.twoSets, .twoSetsDecisivePoint, .twoSetsSuperTie, .twoSetsDecisivePointSuperTie, .twoSetsOfFourGames, .twoSetsOfFourGamesDecisivePoint, .nineGames, .nineGamesDecisivePoint, .superTie, .megaTie, .twoSetsOfSuperTie, .singleSet, .singleSetDecisivePoint] } func winner(scoreTeamOne: Int, scoreTeamTwo: Int) -> TeamPosition { @@ -1242,7 +1255,7 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { func formattedEstimatedDuration(_ additionalDuration: Int = 0) -> String { Duration.seconds((estimatedDuration + additionalDuration) * 60).formatted(.units(allowed: [.minutes])) } - + func formattedEstimatedBreakDuration() -> String { var label = Duration.seconds(breakTime.breakTime * 60).formatted(.units(allowed: [.minutes])) if breakTime.matchCount > 1 { @@ -1251,7 +1264,7 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { } return label } - + var defaultEstimatedDuration: Int { switch self { case .twoSets: @@ -1274,9 +1287,15 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return 20 case .superTie: return 15 + case .twoSetsOfSuperTie: + return 25 + case .singleSet: + return 30 + case .singleSetDecisivePoint: + return 25 } } - + var estimatedTimeWithBreak: Int { estimatedDuration + breakTime.breakTime @@ -1294,6 +1313,8 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return (15, 3) case .megaTie: return (5, 1) + case .twoSetsOfSuperTie, .singleSet, .singleSetDecisivePoint: + return (10, 1) } } @@ -1305,7 +1326,7 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return matchCount < 6 ? 3 : 0 case .twoSetsOfFourGames, .twoSetsOfFourGamesDecisivePoint, .nineGames, .nineGamesDecisivePoint: return matchCount < 7 ? 6 : 2 - case .superTie: + case .superTie, .twoSetsOfSuperTie, .singleSet, .singleSetDecisivePoint: return 7 case .megaTie: return 7 @@ -1314,7 +1335,7 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { var hasDecisivePoint: Bool { switch self { - case .nineGamesDecisivePoint, .twoSetsDecisivePoint, .twoSetsOfFourGamesDecisivePoint, .twoSetsDecisivePointSuperTie: + case .nineGamesDecisivePoint, .twoSetsDecisivePoint, .twoSetsOfFourGamesDecisivePoint, .twoSetsDecisivePointSuperTie, .singleSetDecisivePoint: return true default: return false @@ -1328,9 +1349,13 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return setFormat } + func formatTitle() -> String { + ["Format ", shortFormat, suffix].joined() + } + var suffix: String { switch self { - case .twoSetsDecisivePoint, .twoSetsDecisivePointSuperTie, .twoSetsOfFourGamesDecisivePoint, .nineGamesDecisivePoint: + case .twoSetsDecisivePoint, .twoSetsDecisivePointSuperTie, .twoSetsOfFourGamesDecisivePoint, .nineGamesDecisivePoint, .singleSetDecisivePoint: return " [Point Décisif]" default: return "" @@ -1344,8 +1369,20 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { var shortPrefix: String { return "\(format) : " } + + var isFederal: Bool { + switch self { + case .megaTie, .twoSetsOfSuperTie, .singleSet, .singleSetDecisivePoint: + return false + default: + return true + } + } var format: String { + shortFormat + (isFederal ? "" : " (non officiel)") + } + var shortFormat: String { switch self { case .twoSets: return "A1" @@ -1357,8 +1394,14 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return "D1" case .superTie: return "E" + case .twoSetsOfSuperTie: + return "G" case .megaTie: - return "F (non officiel)" + return "F" + case .singleSet: + return "H1" + case .singleSetDecisivePoint: + return "H2" case .twoSetsDecisivePoint: return "A2" case .twoSetsDecisivePointSuperTie: @@ -1372,6 +1415,8 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { var longLabel: String { switch self { + case .singleSet, .singleSetDecisivePoint: + return "1 set de 6" case .twoSets, .twoSetsDecisivePoint: return "2 sets de 6" case .twoSetsSuperTie, .twoSetsDecisivePointSuperTie: @@ -1380,6 +1425,8 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { return "2 sets de 4, tiebreak à 4/4, supertie au 3ème" case .nineGames, .nineGamesDecisivePoint: return "9 jeux, tiebreak à 8/8" + case .twoSetsOfSuperTie: + return "2 sets de supertie de 10 points" case .superTie: return "supertie de 10 points" case .megaTie: @@ -1401,22 +1448,22 @@ enum MatchFormat: Int, Hashable, Codable, CaseIterable { var setsToWin: Int { switch self { - case .twoSets, .twoSetsSuperTie, .twoSetsOfFourGames, .twoSetsDecisivePoint, .twoSetsOfFourGamesDecisivePoint, .twoSetsDecisivePointSuperTie: + case .twoSets, .twoSetsSuperTie, .twoSetsOfFourGames, .twoSetsDecisivePoint, .twoSetsOfFourGamesDecisivePoint, .twoSetsDecisivePointSuperTie, .twoSetsOfSuperTie: return 2 - case .nineGames, .nineGamesDecisivePoint, .superTie, .megaTie: + case .nineGames, .nineGamesDecisivePoint, .superTie, .megaTie, .singleSet, .singleSetDecisivePoint: return 1 } } var setFormat: SetFormat { switch self { - case .twoSets, .twoSetsSuperTie, .twoSetsDecisivePoint, .twoSetsDecisivePointSuperTie: + case .twoSets, .twoSetsSuperTie, .twoSetsDecisivePoint, .twoSetsDecisivePointSuperTie, .singleSet, .singleSetDecisivePoint: return .six case .twoSetsOfFourGames, .twoSetsOfFourGamesDecisivePoint: return .four case .nineGames, .nineGamesDecisivePoint: return .nine - case .superTie: + case .superTie, .twoSetsOfSuperTie: return .superTieBreak case .megaTie: return .megaTieBreak diff --git a/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift b/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift index d39811d..ed0e831 100644 --- a/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift +++ b/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift @@ -11,49 +11,115 @@ import LeStorage struct GlobalSettingsView: View { @EnvironmentObject var dataStore : DataStore + var groupStageMatchFormat: Binding { + Binding { + dataStore.user.groupStageMatchFormatPreference ?? .nineGames + } set: { value in + dataStore.user.groupStageMatchFormatPreference = value + } + } + + var groupStageMatchFormatPreference: Binding { + Binding { + dataStore.user.groupStageMatchFormatPreference == nil + } set: { value in + if value { + dataStore.user.groupStageMatchFormatPreference = nil + } else { + dataStore.user.groupStageMatchFormatPreference = .nineGames + } + } + + } + + var bracketMatchFormat: Binding { + Binding { + dataStore.user.bracketMatchFormatPreference ?? .nineGames + } set: { value in + dataStore.user.bracketMatchFormatPreference = value + } + } + + var bracketMatchFormatPreference: Binding { + Binding { + dataStore.user.bracketMatchFormatPreference == nil + } set: { value in + if value { + dataStore.user.bracketMatchFormatPreference = nil + } else { + dataStore.user.bracketMatchFormatPreference = .nineGames + } + } + + } + + var loserBracketMatchFormat: Binding { + Binding { + dataStore.user.loserBracketMatchFormatPreference ?? .nineGames + } set: { value in + dataStore.user.loserBracketMatchFormatPreference = value + } + } + + var loserBracketMatchFormatPreference: Binding { + Binding { + dataStore.user.loserBracketMatchFormatPreference == nil + } set: { value in + if value { + dataStore.user.loserBracketMatchFormatPreference = nil + } else { + dataStore.user.loserBracketMatchFormatPreference = .nineGames + } + } + + } + var body: some View { @Bindable var user = dataStore.user List { Section { - Picker(selection: $user.groupStageMatchFormatPreference) { - Text("Automatique").tag(nil as MatchFormat?) - ForEach(MatchFormat.allCases, id: \.self) { format in - Text(format.format).tag(format as MatchFormat?) - } - } label: { - HStack { - Text("Poule") - Spacer() - } + Toggle(isOn: groupStageMatchFormatPreference) { + Text("Automatique") } - Picker(selection: $user.bracketMatchFormatPreference) { - Text("Automatique").tag(nil as MatchFormat?) - ForEach(MatchFormat.allCases, id: \.self) { format in - Text(format.format).tag(format as MatchFormat?) - } - } label: { - HStack { - Text("Tableau") - Spacer() - } + + if groupStageMatchFormatPreference.wrappedValue == false { + MatchTypeSelectionView(selectedFormat: groupStageMatchFormat) + } + } header: { + Text("Poule") + } footer: { + Text("À minima, les règles fédérales seront toujours prises en compte par défaut.") + } + + Section { + Toggle(isOn: bracketMatchFormatPreference) { + Text("Automatique") + } + + if bracketMatchFormatPreference.wrappedValue == false { + MatchTypeSelectionView(selectedFormat: bracketMatchFormat) + } + } header: { + Text("Tableau") + } footer: { + Text("À minima, les règles fédérales seront toujours prises en compte par défaut.") + } + + Section { + Toggle(isOn: loserBracketMatchFormatPreference) { + Text("Automatique") } - Picker(selection: $user.loserBracketMatchFormatPreference) { - Text("Automatique").tag(nil as MatchFormat?) - ForEach(MatchFormat.allCases, id: \.self) { format in - Text(format.format).tag(format as MatchFormat?) - } - } label: { - HStack { - Text("Match de classement") - Spacer() - } + + if loserBracketMatchFormatPreference.wrappedValue == false { + MatchTypeSelectionView(selectedFormat: loserBracketMatchFormat) } } header: { - Text("Vos formats préférés") + Text("Match de classement") } footer: { Text("À minima, les règles fédérales seront toujours prises en compte par défaut.") } } + .headerProminence(.increased) .onChange(of: [ user.bracketMatchFormatPreference, user.groupStageMatchFormatPreference, diff --git a/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift b/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift index b389892..7d90518 100644 --- a/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift +++ b/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift @@ -24,9 +24,7 @@ struct MatchFormatStorageView: View { LabeledContent { StepperView(title: "minutes", count: $estimatedDuration, step: 5) } label: { - Text("Durée \(matchFormat.format)" + matchFormat.suffix) - Text(matchFormat.longLabel) - Text(matchFormat.formattedEstimatedBreakDuration() + " de pause").foregroundStyle(.secondary).font(.subheadline) + MatchFormatRowView(matchFormat: matchFormat, hideDuration: true) } } footer: { if estimatedDuration != matchFormat.defaultEstimatedDuration { diff --git a/PadelClub/Views/Planning/Components/DatePickingView.swift b/PadelClub/Views/Planning/Components/DatePickingView.swift new file mode 100644 index 0000000..9c865e3 --- /dev/null +++ b/PadelClub/Views/Planning/Components/DatePickingView.swift @@ -0,0 +1,93 @@ +// +// DatePickingView.swift +// PadelClub +// +// Created by Razmig Sarkissian on 17/04/2024. +// + +import SwiftUI + +struct DatePickingView: View { + let title: String + @Binding var startDate: Date + @Binding var currentDate: Date? + var duration: Int? + var validateAction: (() async -> ()) + + @State private var confirmFollowingScheduleUpdate: Bool = false + @State private var updatingInProgress: Bool = false + + var body: some View { + Section { + DatePicker(selection: $startDate) { + Text(startDate.formatted(.dateTime.weekday(.wide))).font(.headline) + } + if confirmFollowingScheduleUpdate { + RowButtonView("Modifier la suite du programme") { + updatingInProgress = true + await validateAction() + updatingInProgress = false + confirmFollowingScheduleUpdate = false + } + } + } header: { + Text(title) + } footer: { + if confirmFollowingScheduleUpdate && updatingInProgress == false { + FooterButtonView("non, ne pas modifier la suite") { + currentDate = startDate + confirmFollowingScheduleUpdate = false + } + } else { + HStack { + Menu { + Button("de 30 minutes") { + startDate = startDate.addingTimeInterval(1800) + } + + Button("d'une heure") { + startDate = startDate.addingTimeInterval(3600) + } + + Button("à 9h") { + startDate = startDate.atNine() + } + + Button("à demain 9h") { + startDate = startDate.tomorrowAtNine + } + + if let duration { + Button("à la prochaine rotation") { + startDate = startDate.addingTimeInterval(Double(duration) * 60) + } + Button("à la précédente rotation") { + startDate = startDate.addingTimeInterval(Double(duration) * -60) + } + } + } label: { + Text("décaler") + .underline() + } + .buttonStyle(.borderless) + Spacer() + + if currentDate != nil { + FooterButtonView("retirer l'horaire bloqué") { + currentDate = nil + } + } else { + FooterButtonView("bloquer l'horaire") { + currentDate = startDate + } + } + } + .buttonStyle(.borderless) + } + } + .onChange(of: startDate) { + confirmFollowingScheduleUpdate = true + } + .headerProminence(.increased) + } +} diff --git a/PadelClub/Views/Planning/Components/DatePickingViewWithFormat.swift b/PadelClub/Views/Planning/Components/DatePickingViewWithFormat.swift new file mode 100644 index 0000000..6eca161 --- /dev/null +++ b/PadelClub/Views/Planning/Components/DatePickingViewWithFormat.swift @@ -0,0 +1,108 @@ +// +// DatePickingViewWithFormat.swift +// PadelClub +// +// Created by razmig on 26/10/2024. +// + +import SwiftUI + +struct DatePickingViewWithFormat: View { + @Environment(Tournament.self) var tournament + @Binding var matchFormat: MatchFormat + let title: String + @Binding var startDate: Date + @Binding var currentDate: Date? + var duration: Int? + var validateAction: ((Bool) async -> ()) + + @State private var confirmScheduleUpdate: Bool = false + @State private var updatingInProgress : Bool = false + + var body: some View { + Section { + MatchTypeSelectionView(selectedFormat: $matchFormat, additionalEstimationDuration: tournament.additionalEstimationDuration) + DatePicker(selection: $startDate) { + Text(startDate.formatted(.dateTime.weekday(.wide))).font(.headline) + } + if confirmScheduleUpdate { + RowButtonView("Sauver et modifier la suite") { + updatingInProgress = true + await validateAction(true) + updatingInProgress = false + confirmScheduleUpdate = false + } + } + } header: { + Text(title) + } footer: { + if confirmScheduleUpdate && updatingInProgress == false { + HStack { + FooterButtonView("sauver sans modifier la suite") { + Task { + await validateAction(false) + confirmScheduleUpdate = false + } + } + Text("ou") + FooterButtonView("annuler") { + confirmScheduleUpdate = false + } + } + } else { + HStack { + Menu { + Button("de 30 minutes") { + startDate = startDate.addingTimeInterval(1800) + } + + Button("d'une heure") { + startDate = startDate.addingTimeInterval(3600) + } + + Button("à 9h") { + startDate = startDate.atNine() + } + + Button("à demain 9h") { + startDate = startDate.tomorrowAtNine + } + + if let duration { + Button("à la prochaine rotation") { + startDate = startDate.addingTimeInterval(Double(duration) * 60) + } + Button("à la précédente rotation") { + startDate = startDate.addingTimeInterval(Double(duration) * -60) + } + } + } label: { + Text("décaler") + .underline() + } + .buttonStyle(.borderless) + Spacer() + + if currentDate != nil { + FooterButtonView("retirer l'horaire bloqué") { + currentDate = nil + } + } else { + FooterButtonView("bloquer l'horaire") { + currentDate = startDate + } + } + } + .buttonStyle(.borderless) + } + + } + .headerProminence(.increased) + .onChange(of: matchFormat) { + confirmScheduleUpdate = true + } + .onChange(of: startDate) { + confirmScheduleUpdate = true + } + } +} diff --git a/PadelClub/Views/Planning/Components/DateUpdateManagerView.swift b/PadelClub/Views/Planning/Components/DateUpdateManagerView.swift index 3cdb16d..9c865e3 100644 --- a/PadelClub/Views/Planning/Components/DateUpdateManagerView.swift +++ b/PadelClub/Views/Planning/Components/DateUpdateManagerView.swift @@ -1,5 +1,5 @@ // -// DateUpdateManagerView.swift +// DatePickingView.swift // PadelClub // // Created by Razmig Sarkissian on 17/04/2024. @@ -91,225 +91,3 @@ struct DatePickingView: View { .headerProminence(.increased) } } - -struct MatchFormatPickingView: View { - var title: String? = nil - @Binding var matchFormat: MatchFormat - var validateAction: (() async -> ()) - - @State private var confirmScheduleUpdate: Bool = false - @State private var updatingInProgress : Bool = false - - var body: some View { - Section { - MatchFormatPickerView(headerLabel: "Format", matchFormat: $matchFormat) - if confirmScheduleUpdate { - RowButtonView("Recalculer les horaires") { - updatingInProgress = true - await validateAction() - updatingInProgress = false - confirmScheduleUpdate = false - } - } - } header: { - if let title { - Text(title) - } - } footer: { - if confirmScheduleUpdate && updatingInProgress == false { - FooterButtonView("non, ne pas modifier les horaires") { - confirmScheduleUpdate = false - } - } - } - .headerProminence(.increased) - .onChange(of: matchFormat) { - confirmScheduleUpdate = true - } - } -} - - -struct DatePickingViewWithFormat: View { - @Binding var matchFormat: MatchFormat - let title: String - @Binding var startDate: Date - @Binding var currentDate: Date? - var duration: Int? - var validateAction: ((Bool) async -> ()) - - @State private var confirmScheduleUpdate: Bool = false - @State private var updatingInProgress : Bool = false - - var body: some View { - Section { - MatchFormatPickerView(headerLabel: "Format", matchFormat: $matchFormat) - DatePicker(selection: $startDate) { - Text(startDate.formatted(.dateTime.weekday(.wide))).font(.headline) - } - if confirmScheduleUpdate { - RowButtonView("Sauver et modifier la suite") { - updatingInProgress = true - await validateAction(true) - updatingInProgress = false - confirmScheduleUpdate = false - } - } - } header: { - Text(title) - } footer: { - if confirmScheduleUpdate && updatingInProgress == false { - HStack { - FooterButtonView("sauver sans modifier la suite") { - Task { - await validateAction(false) - confirmScheduleUpdate = false - } - } - Text("ou") - FooterButtonView("annuler") { - confirmScheduleUpdate = false - } - } - } else { - HStack { - Menu { - Button("de 30 minutes") { - startDate = startDate.addingTimeInterval(1800) - } - - Button("d'une heure") { - startDate = startDate.addingTimeInterval(3600) - } - - Button("à 9h") { - startDate = startDate.atNine() - } - - Button("à demain 9h") { - startDate = startDate.tomorrowAtNine - } - - if let duration { - Button("à la prochaine rotation") { - startDate = startDate.addingTimeInterval(Double(duration) * 60) - } - Button("à la précédente rotation") { - startDate = startDate.addingTimeInterval(Double(duration) * -60) - } - } - } label: { - Text("décaler") - .underline() - } - .buttonStyle(.borderless) - Spacer() - - if currentDate != nil { - FooterButtonView("retirer l'horaire bloqué") { - currentDate = nil - } - } else { - FooterButtonView("bloquer l'horaire") { - currentDate = startDate - } - } - } - .buttonStyle(.borderless) - } - - } - .headerProminence(.increased) - .onChange(of: matchFormat) { - confirmScheduleUpdate = true - } - .onChange(of: startDate) { - confirmScheduleUpdate = true - } - } -} - -struct GroupStageDatePickingView: View { - let title: String - @Binding var startDate: Date - @Binding var currentDate: Date? - var duration: Int? - var validateAction: (() async -> ()) - - @State private var confirmFollowingScheduleUpdate: Bool = false - @State private var updatingInProgress: Bool = false - - var body: some View { - Section { - DatePicker(selection: $startDate) { - Text(startDate.formatted(.dateTime.weekday(.wide))).font(.headline) - } - if confirmFollowingScheduleUpdate { - RowButtonView("Confirmer et modifier les matchs") { - updatingInProgress = true - await validateAction() - updatingInProgress = false - confirmFollowingScheduleUpdate = false - } - } - } header: { - Text(title) - } footer: { - if confirmFollowingScheduleUpdate && updatingInProgress == false { - FooterButtonView("Modifier juste l'horaire de la poule") { - currentDate = startDate - confirmFollowingScheduleUpdate = false - } - } else { - HStack { - Menu { - Button("de 30 minutes") { - startDate = startDate.addingTimeInterval(1800) - } - - Button("d'une heure") { - startDate = startDate.addingTimeInterval(3600) - } - - Button("à 9h") { - startDate = startDate.atNine() - } - - Button("à demain 9h") { - startDate = startDate.tomorrowAtNine - } - - if let duration { - Button("à la prochaine rotation") { - startDate = startDate.addingTimeInterval(Double(duration) * 60) - } - Button("à la précédente rotation") { - startDate = startDate.addingTimeInterval(Double(duration) * -60) - } - } - } label: { - Text("décaler") - .underline() - } - .buttonStyle(.borderless) - Spacer() - - if currentDate != nil { - FooterButtonView("retirer l'horaire bloqué") { - currentDate = nil - } - } else { - FooterButtonView("bloquer l'horaire") { - currentDate = startDate - } - } - } - .buttonStyle(.borderless) - } - } - .onChange(of: startDate) { - confirmFollowingScheduleUpdate = true - } - .headerProminence(.increased) - } -} diff --git a/PadelClub/Views/Planning/Components/GroupStageDatePickingView.swift b/PadelClub/Views/Planning/Components/GroupStageDatePickingView.swift new file mode 100644 index 0000000..29c380f --- /dev/null +++ b/PadelClub/Views/Planning/Components/GroupStageDatePickingView.swift @@ -0,0 +1,93 @@ +// +// GroupStageDatePickingView.swift +// PadelClub +// +// Created by razmig on 26/10/2024. +// + +import SwiftUI + +struct GroupStageDatePickingView: View { + let title: String + @Binding var startDate: Date + @Binding var currentDate: Date? + var duration: Int? + var validateAction: (() async -> ()) + + @State private var confirmFollowingScheduleUpdate: Bool = false + @State private var updatingInProgress: Bool = false + + var body: some View { + Section { + DatePicker(selection: $startDate) { + Text(startDate.formatted(.dateTime.weekday(.wide))).font(.headline) + } + if confirmFollowingScheduleUpdate { + RowButtonView("Confirmer et modifier les matchs") { + updatingInProgress = true + await validateAction() + updatingInProgress = false + confirmFollowingScheduleUpdate = false + } + } + } header: { + Text(title) + } footer: { + if confirmFollowingScheduleUpdate && updatingInProgress == false { + FooterButtonView("Modifier juste l'horaire de la poule") { + currentDate = startDate + confirmFollowingScheduleUpdate = false + } + } else { + HStack { + Menu { + Button("de 30 minutes") { + startDate = startDate.addingTimeInterval(1800) + } + + Button("d'une heure") { + startDate = startDate.addingTimeInterval(3600) + } + + Button("à 9h") { + startDate = startDate.atNine() + } + + Button("à demain 9h") { + startDate = startDate.tomorrowAtNine + } + + if let duration { + Button("à la prochaine rotation") { + startDate = startDate.addingTimeInterval(Double(duration) * 60) + } + Button("à la précédente rotation") { + startDate = startDate.addingTimeInterval(Double(duration) * -60) + } + } + } label: { + Text("décaler") + .underline() + } + .buttonStyle(.borderless) + Spacer() + + if currentDate != nil { + FooterButtonView("retirer l'horaire bloqué") { + currentDate = nil + } + } else { + FooterButtonView("bloquer l'horaire") { + currentDate = startDate + } + } + } + .buttonStyle(.borderless) + } + } + .onChange(of: startDate) { + confirmFollowingScheduleUpdate = true + } + .headerProminence(.increased) + } +} diff --git a/PadelClub/Views/Planning/Components/MatchFormatPickingView.swift b/PadelClub/Views/Planning/Components/MatchFormatPickingView.swift new file mode 100644 index 0000000..8b36c13 --- /dev/null +++ b/PadelClub/Views/Planning/Components/MatchFormatPickingView.swift @@ -0,0 +1,47 @@ +// +// MatchFormatPickingView.swift +// PadelClub +// +// Created by razmig on 26/10/2024. +// + +import SwiftUI + +struct MatchFormatPickingView: View { + @Environment(Tournament.self) var tournament + var title: String? = nil + @Binding var matchFormat: MatchFormat + var validateAction: (() async -> ()) + + @State private var confirmScheduleUpdate: Bool = false + @State private var updatingInProgress : Bool = false + + var body: some View { + Section { + MatchTypeSelectionView(selectedFormat: $matchFormat, additionalEstimationDuration: tournament.additionalEstimationDuration) + if confirmScheduleUpdate { + RowButtonView("Recalculer les horaires") { + updatingInProgress = true + await validateAction() + updatingInProgress = false + confirmScheduleUpdate = false + } + } + } header: { + if let title { + Text(title) + } + } footer: { + if confirmScheduleUpdate && updatingInProgress == false { + FooterButtonView("non, ne pas modifier les horaires") { + confirmScheduleUpdate = false + } + } + } + .headerProminence(.increased) + .onChange(of: matchFormat) { + confirmScheduleUpdate = true + } + } +} + diff --git a/PadelClub/Views/Score/EditScoreView.swift b/PadelClub/Views/Score/EditScoreView.swift index 639d2bf..600b771 100644 --- a/PadelClub/Views/Score/EditScoreView.swift +++ b/PadelClub/Views/Score/EditScoreView.swift @@ -13,6 +13,7 @@ struct EditScoreView: View { @EnvironmentObject var dataStore: DataStore @StateObject var matchDescriptor: MatchDescriptor + @State private var presentMatchFormatSelection: Bool = false @Binding var confirmScoreEdition: Bool @Environment(\.dismiss) private var dismiss @@ -89,11 +90,9 @@ struct EditScoreView: View { } Spacer() - MatchTypeSmallSelectionView(selectedFormat: $matchDescriptor.matchFormat, format: "Format") - .onChange(of: matchDescriptor.matchFormat) { - matchDescriptor.setDescriptors.removeAll() - matchDescriptor.addNewSet() - } + FooterButtonView("Format : \(matchDescriptor.matchFormat.shortFormat)") { + presentMatchFormatSelection = true + } } } ForEach($matchDescriptor.setDescriptors) { $setDescriptor in @@ -143,6 +142,15 @@ struct EditScoreView: View { } } } + .sheet(isPresented: $presentMatchFormatSelection) { + MatchFormatSelectionView(matchFormat: $matchDescriptor.matchFormat, additionalEstimationDuration: matchDescriptor.match?.currentTournament()?.additionalEstimationDuration) + .tint(.master) + } + .onChange(of: matchDescriptor.matchFormat) { + presentMatchFormatSelection = false + matchDescriptor.setDescriptors.removeAll() + matchDescriptor.addNewSet() + } } func save() { diff --git a/PadelClub/Views/Shared/MatchFormatPickerView.swift b/PadelClub/Views/Shared/MatchFormatPickerView.swift deleted file mode 100644 index c50c3a7..0000000 --- a/PadelClub/Views/Shared/MatchFormatPickerView.swift +++ /dev/null @@ -1,63 +0,0 @@ -// -// MatchFormatPickerView.swift -// PadelClub -// -// Created by Razmig Sarkissian on 22/03/2024. -// - -import SwiftUI - -struct MatchFormatPickerView: View { - @Environment(Tournament.self) var tournament: Tournament - let headerLabel: String - @Binding var matchFormat: MatchFormat - @State private var isExpanded: Bool = false - - var body: some View { - DisclosureGroup(isExpanded: $isExpanded) { - Picker(selection: $matchFormat) { - ForEach(MatchFormat.allCases, id: \.rawValue) { format in - LabeledContent { - Text("~" + format.formattedEstimatedDuration(tournament.additionalEstimationDuration)) - } label: { - Text(format.format + " " + format.suffix) - Text(format.longLabel) - } - .tag(format) - } - } label: { - } - .pickerStyle(.inline) - .onChange(of: matchFormat) { - isExpanded = false - } - } label: { - descriptionView - } - } - - var descriptionView: some View { - VStack(alignment: .leading) { - HStack { - Text(headerLabel).font(.footnote) - Spacer() - Text("Durée").font(.footnote) - } - HStack { - Text(matchFormat.format).font(.title).fontWeight(.semibold) - Spacer() - VStack(alignment: .trailing) { - Text("~" + matchFormat.formattedEstimatedDuration(tournament.additionalEstimationDuration)) - Text(matchFormat.formattedEstimatedBreakDuration() + " de pause").foregroundStyle(.secondary).font(.subheadline) - } - } - } - } -} - - -//#Preview { -// List { -// MatchFormatPickerView(headerLabel: "Test", matchFormat: .constant(MatchFormat.superTie)) -// } -//} diff --git a/PadelClub/Views/Shared/MatchFormatRowView.swift b/PadelClub/Views/Shared/MatchFormatRowView.swift new file mode 100644 index 0000000..8698ea4 --- /dev/null +++ b/PadelClub/Views/Shared/MatchFormatRowView.swift @@ -0,0 +1,46 @@ +// +// MatchFormatRowView.swift +// PadelClub +// +// Created by Razmig Sarkissian on 02/04/2024. +// + +import SwiftUI + +struct MatchFormatRowView: View { + let matchFormat: MatchFormat + var headerLabel: String? = nil + var hideExplanation: Bool = false + var hideDuration: Bool = false + var additionalEstimationDuration: Int? + + var body: some View { + VStack(alignment: .leading) { + if let headerLabel { + HStack { + Text(headerLabel).font(.footnote) + if hideDuration == false { + Spacer() + Text("Durée").font(.footnote) + } + } + } + HStack { + Text(matchFormat.formatTitle()) + if hideDuration == false { + Spacer() + Text("~" + matchFormat.formattedEstimatedDuration(additionalEstimationDuration ?? 0)) + } + } + .font(.headline) + + if hideExplanation == false { + Text(matchFormat.longLabel) + Text(matchFormat.formattedEstimatedBreakDuration() + " de pause").font(.footnote) + if matchFormat.isFederal == false { + Text("Non officiel").foregroundStyle(.logoRed).font(.footnote) + } + } + } + } +} diff --git a/PadelClub/Views/Shared/MatchFormatSelectionView.swift b/PadelClub/Views/Shared/MatchFormatSelectionView.swift new file mode 100644 index 0000000..3249090 --- /dev/null +++ b/PadelClub/Views/Shared/MatchFormatSelectionView.swift @@ -0,0 +1,33 @@ +// +// MatchFormatSelectionView.swift +// PadelClub +// +// Created by Razmig Sarkissian on 22/03/2024. +// + +import SwiftUI + +struct MatchFormatSelectionView: View { + @Environment(\.dismiss) private var dismiss + @Binding var matchFormat: MatchFormat + var additionalEstimationDuration: Int? + + var body: some View { + List { + Section { + Picker(selection: $matchFormat) { + ForEach(MatchFormat.allCases) { format in + MatchFormatRowView(matchFormat: format, additionalEstimationDuration: additionalEstimationDuration).tag(format) + } + } label: { + + } + .labelsHidden() + .pickerStyle(.inline) + } + } + .onChange(of: matchFormat) { + dismiss() + } + } +} diff --git a/PadelClub/Views/Shared/MatchTypeSelectionView.swift b/PadelClub/Views/Shared/MatchTypeSelectionView.swift index 2d3ba3c..54bc81c 100644 --- a/PadelClub/Views/Shared/MatchTypeSelectionView.swift +++ b/PadelClub/Views/Shared/MatchTypeSelectionView.swift @@ -9,9 +9,16 @@ import SwiftUI struct MatchTypeSelectionView: View { @Binding var selectedFormat: MatchFormat - let format: String + var format: String? + var additionalEstimationDuration: Int? var body: some View { - MatchFormatPickerView(headerLabel: format, matchFormat: $selectedFormat) + NavigationLink { + MatchFormatSelectionView(matchFormat: $selectedFormat) + .navigationTitle("Choix du format") + .toolbarBackground(.visible, for: .navigationBar) + } label: { + MatchFormatRowView(matchFormat: selectedFormat, headerLabel: format, hideExplanation: true, additionalEstimationDuration: additionalEstimationDuration) + } } } diff --git a/PadelClub/Views/Shared/MatchTypeSmallSelectionView.swift b/PadelClub/Views/Shared/MatchTypeSmallSelectionView.swift deleted file mode 100644 index cc30267..0000000 --- a/PadelClub/Views/Shared/MatchTypeSmallSelectionView.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// MatchTypeSmallSelectionView.swift -// PadelClub -// -// Created by Razmig Sarkissian on 02/04/2024. -// - -import SwiftUI - -struct MatchTypeSmallSelectionView: View { - @Binding var selectedFormat: MatchFormat - let format: String - - var body: some View { - Picker(selection: $selectedFormat) { - ForEach(MatchFormat.allCases, id: \.rawValue) { matchFormat in - Text(format + " " + matchFormat.format) - .tag(matchFormat) - } - } label: { - } - } -} diff --git a/PadelClub/Views/Tournament/Screen/Components/TournamentFormatSelectionView.swift b/PadelClub/Views/Tournament/Screen/Components/TournamentFormatSelectionView.swift index 74ef46c..5f6f301 100644 --- a/PadelClub/Views/Tournament/Screen/Components/TournamentFormatSelectionView.swift +++ b/PadelClub/Views/Tournament/Screen/Components/TournamentFormatSelectionView.swift @@ -15,9 +15,9 @@ struct TournamentFormatSelectionView: View { @Bindable var tournament = tournament Section { - MatchTypeSelectionView(selectedFormat: $tournament.groupStageMatchFormat, format: "Poule") - MatchTypeSelectionView(selectedFormat: $tournament.matchFormat, format: "Tableau") - MatchTypeSelectionView(selectedFormat: $tournament.loserBracketMatchFormat, format: "Match de classement") + MatchTypeSelectionView(selectedFormat: $tournament.groupStageMatchFormat, format: "Poule", additionalEstimationDuration: tournament.additionalEstimationDuration) + MatchTypeSelectionView(selectedFormat: $tournament.matchFormat, format: "Tableau", additionalEstimationDuration: tournament.additionalEstimationDuration) + MatchTypeSelectionView(selectedFormat: $tournament.loserBracketMatchFormat, format: "Match de classement", additionalEstimationDuration: tournament.additionalEstimationDuration) } footer: { Text("À minima, les règles fédérales seront toujours prises en compte par défaut.") }