From fd661687c33e64ed13849d69516af0d5e8512920 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Wed, 27 Mar 2024 20:49:58 +0100 Subject: [PATCH] clean up --- PadelClub.xcodeproj/project.pbxproj | 12 +++ PadelClub/Data/Club.swift | 4 +- PadelClub/Data/Tournament.swift | 10 ++- .../NumberFormatter+Extensions.swift | 16 ++++ PadelClub/Extensions/String+Extensions.swift | 29 ++++++ PadelClub/Views/Club/ClubRowView.swift | 25 ++++++ PadelClub/Views/Club/ClubsView.swift | 35 +++++--- PadelClub/Views/Event/EventCreationView.swift | 90 ++++++++++--------- .../Navigation/Agenda/EventListView.swift | 55 +++++++----- .../Toolbox/RankCalculatorView.swift | 60 +++++++++++++ .../Navigation/Toolbox/ToolboxView.swift | 6 ++ .../Screen/InscriptionManagerView.swift | 33 ++++++- .../Screen/TournamentSettingsView.swift | 51 +++++++++-- .../Views/Tournament/Shared/DateBoxView.swift | 7 +- .../Shared/TournamentCellView.swift | 10 ++- 15 files changed, 350 insertions(+), 93 deletions(-) create mode 100644 PadelClub/Extensions/NumberFormatter+Extensions.swift create mode 100644 PadelClub/Views/Club/ClubRowView.swift create mode 100644 PadelClub/Views/Navigation/Toolbox/RankCalculatorView.swift diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index 5c5b051..2ec8f79 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -104,6 +104,9 @@ FF5D0D742BB41DF8005CB568 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D732BB41DF8005CB568 /* Color+Extensions.swift */; }; FF5D0D762BB428B2005CB568 /* ListRowViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D752BB428B2005CB568 /* ListRowViewModifier.swift */; }; FF5D0D782BB42C5B005CB568 /* InscriptionInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D772BB42C5B005CB568 /* InscriptionInfoView.swift */; }; + FF5D0D852BB48997005CB568 /* RankCalculatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D822BB48997005CB568 /* RankCalculatorView.swift */; }; + FF5D0D872BB48AFD005CB568 /* NumberFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */; }; + FF5D0D892BB4935C005CB568 /* ClubRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D882BB4935C005CB568 /* ClubRowView.swift */; }; FF6EC8F72B94773200EA7F5A /* RowButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6EC8F62B94773100EA7F5A /* RowButtonView.swift */; }; FF6EC8FB2B94788600EA7F5A /* TournamentButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6EC8FA2B94788600EA7F5A /* TournamentButtonView.swift */; }; FF6EC8FE2B94792300EA7F5A /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6EC8FD2B94792300EA7F5A /* Screen.swift */; }; @@ -317,6 +320,9 @@ FF5D0D732BB41DF8005CB568 /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = ""; }; FF5D0D752BB428B2005CB568 /* ListRowViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRowViewModifier.swift; sourceTree = ""; }; FF5D0D772BB42C5B005CB568 /* InscriptionInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InscriptionInfoView.swift; sourceTree = ""; }; + FF5D0D822BB48997005CB568 /* RankCalculatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RankCalculatorView.swift; sourceTree = ""; }; + FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NumberFormatter+Extensions.swift"; sourceTree = ""; }; + FF5D0D882BB4935C005CB568 /* ClubRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClubRowView.swift; sourceTree = ""; }; FF6EC8F62B94773100EA7F5A /* RowButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RowButtonView.swift; sourceTree = ""; }; FF6EC8FA2B94788600EA7F5A /* TournamentButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentButtonView.swift; sourceTree = ""; }; FF6EC8FD2B94792300EA7F5A /* Screen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screen.swift; sourceTree = ""; }; @@ -657,6 +663,7 @@ FF1DC5562BAB3AED00FD8220 /* ClubsView.swift */, FF1DC5542BAB36DD00FD8220 /* CreateClubView.swift */, FFC1E10B2BAC7FB0008D6F59 /* ClubImportView.swift */, + FF5D0D882BB4935C005CB568 /* ClubRowView.swift */, ); path = Club; sourceTree = ""; @@ -723,6 +730,7 @@ isa = PBXGroup; children = ( FF59FFB82B90EFD70061EFF9 /* ToolboxView.swift */, + FF5D0D822BB48997005CB568 /* RankCalculatorView.swift */, ); path = Toolbox; sourceTree = ""; @@ -880,6 +888,7 @@ isa = PBXGroup; children = ( FFF8ACD52B923960008466FA /* URL+Extensions.swift */, + FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */, FFF8ACD82B923F3C008466FA /* String+Extensions.swift */, FFF8ACDA2B923F48008466FA /* Date+Extensions.swift */, FF6EC9032B9479F500EA7F5A /* Sequence+Extensions.swift */, @@ -1144,6 +1153,7 @@ FF967CEE2BAECBD700A9A3BD /* Round.swift in Sources */, FF3F74FF2B91A2D4004CFE0E /* AgendaDestination.swift in Sources */, FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */, + FF5D0D892BB4935C005CB568 /* ClubRowView.swift in Sources */, FF1DC5512BAB351300FD8220 /* ClubDetailView.swift in Sources */, C4A47D632B6D3D6500ADC637 /* Club.swift in Sources */, FF6EC90B2B947AC000EA7F5A /* Array+Extensions.swift in Sources */, @@ -1193,9 +1203,11 @@ FF5D0D782BB42C5B005CB568 /* InscriptionInfoView.swift in Sources */, FF4AB6BD2B9256E10002987F /* SelectablePlayerListView.swift in Sources */, FF8F26512BAE0BAD00650388 /* MatchFormatPickerView.swift in Sources */, + FF5D0D872BB48AFD005CB568 /* NumberFormatter+Extensions.swift in Sources */, C4A47DA62B83948E00ADC637 /* LoginView.swift in Sources */, FF967CF82BAEDF0000A9A3BD /* Labels.swift in Sources */, FF089EB42BB0020000F0AEC7 /* PlayerSexPickerView.swift in Sources */, + FF5D0D852BB48997005CB568 /* RankCalculatorView.swift in Sources */, FF70916A2B90F95E00AB08DA /* DateBoxView.swift in Sources */, FF5D0D722BB3EFA5005CB568 /* LearnMoreSheetView.swift in Sources */, FFF8ACD42B92392C008466FA /* SourceFileManager.swift in Sources */, diff --git a/PadelClub/Data/Club.swift b/PadelClub/Data/Club.swift index e188cdb..7596ec8 100644 --- a/PadelClub/Data/Club.swift +++ b/PadelClub/Data/Club.swift @@ -35,7 +35,7 @@ class Club : ModelObject, Storable, Hashable { internal init(name: String, acronym: String? = nil, phone: String? = nil, code: String? = nil, address: String? = nil, city: String? = nil, zipCode: String? = nil, latitude: Double? = nil, longitude: Double? = nil) { self.name = name - self.acronym = acronym ?? name.canonicalVersion.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines) + self.acronym = acronym ?? name.acronym() self.phone = phone self.code = code self.address = address @@ -73,7 +73,7 @@ extension Club { } func automaticShortName() -> String { - String(name.canonicalVersion.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines).prefix(10)) + name.acronym() } enum AcronymMode: String, CaseIterable { diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 555d88b..ff4394c 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -106,7 +106,15 @@ class Tournament : ModelObject, Storable { func club() -> Club? { eventObject?.clubObject } - + + func locationLabel(_ displayStyle: DisplayStyle = .wide) -> String { + if let club = club() { + return "@" + club.acronym + } else { + return "" + } + } + func hasEnded() -> Bool { endDate != nil } diff --git a/PadelClub/Extensions/NumberFormatter+Extensions.swift b/PadelClub/Extensions/NumberFormatter+Extensions.swift new file mode 100644 index 0000000..e7f2262 --- /dev/null +++ b/PadelClub/Extensions/NumberFormatter+Extensions.swift @@ -0,0 +1,16 @@ +// +// NumberFormatter+Extensions.swift +// PadelClub +// +// Created by Razmig Sarkissian on 27/03/2024. +// + +import Foundation + +extension NumberFormatter { + static var ordinal: NumberFormatter { + let formatter = NumberFormatter() + formatter.numberStyle = .ordinal + return formatter + } +} diff --git a/PadelClub/Extensions/String+Extensions.swift b/PadelClub/Extensions/String+Extensions.swift index 9efc40d..28e325e 100644 --- a/PadelClub/Extensions/String+Extensions.swift +++ b/PadelClub/Extensions/String+Extensions.swift @@ -25,6 +25,35 @@ extension String { } } +extension String { + func acronym() -> String { + let acronym = canonicalVersion.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines) + if acronym.count > 10 { + return concatenateFirstLetters() + } else { + return acronym + } + } + + func concatenateFirstLetters() -> String { + // Split the input into sentences + let sentences = self.components(separatedBy: .whitespacesAndNewlines) + + // Extract the first character of each sentence + let firstLetters = sentences.compactMap { sentence -> Character? in + let trimmedSentence = sentence.trimmingCharacters(in: .whitespacesAndNewlines) + if let firstCharacter = trimmedSentence.first { + return firstCharacter + } + return nil + } + + // Join the first letters together into a string + let result = String(firstLetters) + return result + } +} + extension String { var computedLicense: String { if let licenseKey { diff --git a/PadelClub/Views/Club/ClubRowView.swift b/PadelClub/Views/Club/ClubRowView.swift new file mode 100644 index 0000000..a87c51b --- /dev/null +++ b/PadelClub/Views/Club/ClubRowView.swift @@ -0,0 +1,25 @@ +// +// ClubRowView.swift +// PadelClub +// +// Created by Razmig Sarkissian on 27/03/2024. +// + +import SwiftUI + +struct ClubRowView: View { + let club: Club + + var body: some View { + LabeledContent { + + } label: { + Text(club.name) + Text(club.acronym) + } + } +} + +#Preview { + ClubRowView(club: Club.mock()) +} diff --git a/PadelClub/Views/Club/ClubsView.swift b/PadelClub/Views/Club/ClubsView.swift index 5725474..8b8f23b 100644 --- a/PadelClub/Views/Club/ClubsView.swift +++ b/PadelClub/Views/Club/ClubsView.swift @@ -10,23 +10,37 @@ import TipKit struct ClubsView: View { @EnvironmentObject var dataStore: DataStore + @Environment(\.dismiss) private var dismiss @State private var presentClubCreationView: Bool = false @State private var presentClubSearchView: Bool = false let tip = SlideToDeleteTip() + var selection: ((Club) -> ())? = nil var body: some View { List { ForEach(dataStore.clubs) { club in - NavigationLink { - ClubDetailView(club: club) - } label: { - Text(club.name) - } - .swipeActions(edge: .trailing, allowsFullSwipe: true) { - Button(role: .destructive) { - try? dataStore.clubs.delete(instance: club) + if let selection { + Button { + selection(club) + dismiss() + } label: { + ClubRowView(club: club) + .frame(maxWidth: .infinity) + } + .contentShape(Rectangle()) + .buttonStyle(.plain) + } else { + NavigationLink { + ClubDetailView(club: club) } label: { - LabelDelete() + ClubRowView(club: club) + } + .swipeActions(edge: .trailing, allowsFullSwipe: true) { + Button(role: .destructive) { + try? dataStore.clubs.delete(instance: club) + } label: { + LabelDelete() + } } } } @@ -37,7 +51,6 @@ struct ClubsView: View { .tipStyle(tint: nil) } } - } .overlay { if dataStore.clubs.isEmpty { @@ -55,7 +68,7 @@ struct ClubsView: View { } } } - .navigationTitle("Mes clubs") + .navigationTitle(selection == nil ? "Mes clubs" : "Choisir un club") .sheet(isPresented: $presentClubCreationView) { CreateClubView() } diff --git a/PadelClub/Views/Event/EventCreationView.swift b/PadelClub/Views/Event/EventCreationView.swift index d6c2e2b..6715484 100644 --- a/PadelClub/Views/Event/EventCreationView.swift +++ b/PadelClub/Views/Event/EventCreationView.swift @@ -17,6 +17,8 @@ struct EventCreationView: View { @State private var duration: Int = 3 @State private var eventName: String = "" @State var tournaments: [Tournament] = [] + @State private var selectedClub: Club? + let multiTournamentsEventTip = MultiTournamentsEventTip() var body: some View { @@ -32,18 +34,6 @@ struct EventCreationView: View { // } // } - Section { - TextField("Nom de l'événement", text: $eventName) - } - - Section { - TipView(multiTournamentsEventTip) { action in - let tournament = Tournament.newEmptyInstance() - self.tournaments.append(tournament) - } - .tipStyle(tint: .orange) - } - Section { DatePicker(selection: $startingDate) { Text(startingDate.formatted(.dateTime.weekday(.wide)).capitalized) @@ -58,8 +48,31 @@ struct EventCreationView: View { } } } + + NavigationLink { + ClubsView() { club in + print("club", club.acronym) + selectedClub = club + } + } label: { + if let selectedClub { + ClubRowView(club: selectedClub) + } else { + Text("Choisir un club") + } + } + + TextField("Nom de l'événement", text: $eventName) } header: { - Text("Démarrage") + Text("Informations générales") + } + + Section { + TipView(multiTournamentsEventTip) { action in + let tournament = Tournament.newEmptyInstance() + self.tournaments.append(tournament) + } + .tipStyle(tint: .orange) } @@ -73,30 +86,12 @@ struct EventCreationView: View { case .animation: animationEditorView } - } - .navigationBarTitleDisplayMode(.large) - .toolbar { - ToolbarItem(placement: .cancellationAction) { - Button("Annuler", role: .cancel) { - dismiss() - } - } - ToolbarItem(placement: .topBarTrailing) { - Button { - let tournament = Tournament.newEmptyInstance() - self.tournaments.append(tournament) - } label: { - Label("épreuve", systemImage: "plus.circle.fill").labelStyle(.titleAndIcon) - } - .clipShape(Capsule()) - .buttonStyle(.bordered) - } - - ToolbarItem(placement: .bottomBar) { - Button { - if tournaments.count > 1 || eventName.trimmed.isEmpty == false { + Section { + RowButtonView(title:"Valider") { + if tournaments.count > 1 || eventName.trimmed.isEmpty == false || selectedClub != nil { let event = Event(name: eventName) + event.club = selectedClub?.id tournaments.forEach { tournament in tournament.event = event.id } @@ -107,20 +102,22 @@ struct EventCreationView: View { tournament.startDate = startingDate tournament.dayDuration = duration } - + try? dataStore.tournaments.addOrUpdate(contentOfs: tournaments) dismiss() - } label: { - Text("Valider") - .frame(maxWidth: .infinity) } - .font(.headline) - .buttonStyle(.borderedProminent) - .tint(.launchScreenBackground) } - + } + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button("Annuler", role: .cancel) { + dismiss() + } + } } .navigationTitle("Nouvel événement") + .navigationBarTitleDisplayMode(.large) + .toolbarBackground(.visible, for: .navigationBar) } } @@ -144,6 +141,13 @@ struct EventCreationView: View { } } } + + Section { + RowButtonView(title: "Ajouter une \((tournaments.count + 1).ordinalFormatted()) épreuve") { + let tournament = Tournament.newEmptyInstance() + self.tournaments.append(tournament) + } + } } @ViewBuilder diff --git a/PadelClub/Views/Navigation/Agenda/EventListView.swift b/PadelClub/Views/Navigation/Agenda/EventListView.swift index 013e716..115ffb6 100644 --- a/PadelClub/Views/Navigation/Agenda/EventListView.swift +++ b/PadelClub/Views/Navigation/Agenda/EventListView.swift @@ -12,32 +12,45 @@ struct EventListView: View { let tournaments: [Tournament] var body: some View { - Section { - ForEach(tournaments) { tournament in - - NavigationLink(value: tournament) { + let groupedTournamentsByDate = Dictionary(grouping: tournaments) { $0.startDate.monthYearFormatted } + + ForEach(groupedTournamentsByDate.keys.sorted(by: >), id: \.self) { section in + if let _tournaments = groupedTournamentsByDate[section]?.sorted(by: \.startDate) { + Section { + ForEach(_tournaments) { tournament in + NavigationLink(value: tournament) { + HStack { + TournamentCellView(tournament: tournament) + Spacer() + Text(tournament.sortedTeams().count.formatted()) + .font(.largeTitle) + } + } + .swipeActions(edge: .trailing, allowsFullSwipe: true) { + Button(role: .destructive) { + try? DataStore.shared.tournaments.delete(instance: tournament) + } label: { + LabelDelete() + } + } + .contextMenu { + Button { + + } label: { + Label("Voir dans le gestionnaire", systemImage: "line.diagonal.arrow") + } + } + } + } header: { HStack { - TournamentCellView(tournament: tournament) + Text(section) Spacer() - Text(tournament.sortedTeams().count.formatted()) - } - } - .contextMenu { - Button { - - } label: { - Label("Voir dans le gestionnaire", systemImage: "line.diagonal.arrow") + Text(_tournaments.count.formatted()) } } + .headerProminence(.increased) } - .onDelete(perform: { indexSet in - for index in indexSet { - try? DataStore.shared.tournaments.delete(instance: tournaments[index]) - } - }) - } header: { - Text(Date().formatted(.dateTime.month().year())) - }.headerProminence(.increased) + } } } diff --git a/PadelClub/Views/Navigation/Toolbox/RankCalculatorView.swift b/PadelClub/Views/Navigation/Toolbox/RankCalculatorView.swift new file mode 100644 index 0000000..0ebd1bf --- /dev/null +++ b/PadelClub/Views/Navigation/Toolbox/RankCalculatorView.swift @@ -0,0 +1,60 @@ +// +// RankCalculatorView.swift +// Padel Tournament +// +// Created by Razmig Sarkissian on 03/05/2023. +// + +import SwiftUI + +struct RankCalculatorView: View { + @State private var rank: Int = 1 + @AppStorage("lastRankCalculatorLevel") private var tournamentLevel: TournamentLevel = .p25 + @AppStorage("lastRankCalculatorCount") private var count: PlayersCountRange = .N8 + + var body: some View { + Form { + Section { + HStack { + let ordinal = NumberFormatter.ordinal.string(from: NSNumber(value:rank))! + Text("\(ordinal) d'un \(tournamentLevel.localizedLabel()) de \(count.localizedLabel()) équipes:") + Spacer() + Text(tournamentLevel.points(for: rank-1, count: count.rawValue).formatted(.number.sign(strategy: .always()))) + } + } + Section { + Picker(selection: $tournamentLevel) { + ForEach(TournamentLevel.allCases) { level in + Text(level.localizedLabel()).tag(level) + } + } label: { + Label("Niveau", systemImage: "gauge.medium") + } + Picker(selection: $count) { + ForEach(tournamentLevel.ranges, id: \.self) { + Text($0.localizedLabel()).tag($0) + } + } label: { + Label("Nombre d'équipes", systemImage: "person.2") + } + Picker(selection: $rank) { + ForEach((1...count.rawValue), id: \.self) { + Text("#\($0)").tag($0) + } + } label: { + Label("Votre position", systemImage: "number") + } + } + Section { + ForEach(tournamentLevel.allPoints(for: count.rawValue).indices, id: \.self) { i in + HStack { + Text("#"+(i+1).formatted()) + Spacer() + Text(tournamentLevel.allPoints(for: count.rawValue)[i].formatted(.number.sign(strategy: .always()))) + } + } + } + } + .navigationTitle("Calculateur de points") + } +} diff --git a/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift b/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift index e903dcc..e5bae96 100644 --- a/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift +++ b/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift @@ -16,6 +16,12 @@ struct ToolboxView: View { } label: { Label("Rechercher un joueur", systemImage: "person.fill.viewfinder") } + NavigationLink { + RankCalculatorView() + } label: { + Label("Calculateur de points", systemImage: "scalemass") + } + } .navigationTitle(TabDestination.toolbox.title) } diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index 2741af4..d8acad0 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -30,7 +30,7 @@ struct InscriptionManagerView: View { @State private var currentRankSourceDate: Date? @State private var confirmUpdateRank = false @State private var selectionSearchField: String? - + let slideToDeleteTip = SlideToDeleteTip() let inscriptionManagerWomanRankTip = InscriptionManagerWomanRankTip() let fileTip = InscriptionManagerFileInputTip() @@ -668,14 +668,41 @@ struct InscriptionManagerView: View { } .labelsHidden() + + Divider() + NavigationLink { + ClubsView() { club in + if let event = tournament.eventObject { + event.club = club.id + try? dataStore.events.addOrUpdate(instance: event) + } else { + let event = Event(club: club.id) + tournament.event = event.id + try? dataStore.events.addOrUpdate(instance: event) + } + _save() + } + } label: { + Text("Changer de club") + } } label: { Text("Membres prioritaires") Text(federalClub.acronym) } Divider() - } else if let event = tournament.eventObject { + } else { NavigationLink { - ClubSearchView() + ClubsView() { club in + if let event = tournament.eventObject { + event.club = club.id + try? dataStore.events.addOrUpdate(instance: event) + } else { + let event = Event(club: club.id) + tournament.event = event.id + try? dataStore.events.addOrUpdate(instance: event) + } + _save() + } } label: { Text("Identifier le club") } diff --git a/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift b/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift index fa35daf..5d04840 100644 --- a/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift +++ b/PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift @@ -46,18 +46,55 @@ struct TournamentSettingsView: View { TournamentDurationManagerView() TournamentFieldsManagerView() TournamentDatePickerView() + + + let event = tournament.eventObject + let selectedClub = event?.clubObject + Section { + if let selectedClub { + NavigationLink { + ClubDetailView(club: selectedClub, displayContext: .edition) + } label: { + ClubRowView(club: selectedClub) + } + } else { + NavigationLink { + ClubsView() { club in + if let event { + event.club = club.id + try? dataStore.events.addOrUpdate(instance: event) + } else { + let event = Event(club: club.id) + tournament.event = event.id + try? dataStore.events.addOrUpdate(instance: event) + } + } + } label: { + Text("Choisir un club") + } + } + } header: { + Text("Lieu du tournoi") + } footer: { + if let event, selectedClub != nil { + HStack { + Spacer() + Button("modifier", role: .destructive) { + event.club = nil + try? dataStore.events.addOrUpdate(instance: event) + } + .font(.caption) + } + } + } + TournamentFormatSelectionView() + } .navigationTitle("Réglages") .toolbarBackground(.visible, for: .navigationBar) - .onAppear { - tournamentName = tournament.name ?? "" - tournament.undoManager = tournament.hashValue - } .onDisappear { - if tournament.undoManager != tournament.hashValue { - try? dataStore.tournaments.addOrUpdate(instance: tournament) - } + try? dataStore.tournaments.addOrUpdate(instance: tournament) } } } diff --git a/PadelClub/Views/Tournament/Shared/DateBoxView.swift b/PadelClub/Views/Tournament/Shared/DateBoxView.swift index a9430a4..049a9f7 100644 --- a/PadelClub/Views/Tournament/Shared/DateBoxView.swift +++ b/PadelClub/Views/Tournament/Shared/DateBoxView.swift @@ -14,8 +14,11 @@ struct DateBoxView: View { VStack(alignment: .center, spacing: -2) { Text(date.formatted(.dateTime.weekday(.abbreviated))) .font(.caption2) - Text(date.formatted(.dateTime.day())) - .font(.title) + HStack(alignment: .bottom) { + Text(date.formatted(.dateTime.day(.twoDigits))) + .font(.title) + .monospacedDigit() + } Text(date.formatted(.dateTime.month(.abbreviated))) .font(.caption2) Text(date.formatted(.dateTime.year())) diff --git a/PadelClub/Views/Tournament/Shared/TournamentCellView.swift b/PadelClub/Views/Tournament/Shared/TournamentCellView.swift index 0ba0c87..42fd781 100644 --- a/PadelClub/Views/Tournament/Shared/TournamentCellView.swift +++ b/PadelClub/Views/Tournament/Shared/TournamentCellView.swift @@ -19,10 +19,14 @@ struct TournamentCellView: View { .fill(color) .frame(width: 2) VStack(alignment: .leading, spacing: -2) { - Text(tournament.subtitle()) + Text(tournament.locationLabel()) .font(.caption2) - Text(tournament.tournamentLevel.localizedLabel()) - .font(.title) + HStack(alignment: .bottom) { + Text(tournament.tournamentLevel.localizedLabel()) + .font(.title) + Text(tournament.subtitle()) + .font(.headline) + } Text(tournament.tournamentCategory.localizedLabel()) .font(.caption2) Text(tournament.federalTournamentAge.localizedLabel())