fix url rawvalue (oups)

multistore
Razmig Sarkissian 2 years ago
parent 9dc16f9c81
commit 2987c509c5
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 10
      PadelClub/Data/Club.swift
  3. 10
      PadelClub/Data/Tournament.swift
  4. 4
      PadelClub/Utils/Tips.swift
  5. 18
      PadelClub/Views/Club/ClubDetailView.swift
  6. 2
      PadelClub/Views/Event/EventCreationView.swift
  7. 2
      PadelClub/Views/Navigation/Toolbox/ToolboxView.swift
  8. 2
      PadelClub/Views/Tournament/Screen/Components/TournamentClubSettingsView.swift
  9. 2
      PadelClub/Views/Tournament/TournamentBuildView.swift
  10. 35
      PadelClub/Views/Tournament/TournamentInitView.swift
  11. 70
      PadelClub/Views/Tournament/TournamentInscriptionView.swift
  12. 2
      PadelClub/Views/Tournament/TournamentRunningView.swift
  13. 51
      PadelClub/Views/Tournament/TournamentView.swift

@ -127,6 +127,7 @@
FF1DC55B2BAB80C400FD8220 /* DisplayContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1DC55A2BAB80C400FD8220 /* DisplayContext.swift */; }; FF1DC55B2BAB80C400FD8220 /* DisplayContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1DC55A2BAB80C400FD8220 /* DisplayContext.swift */; };
FF1DF49B2BD8D23900822FA0 /* BarButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1DF49A2BD8D23900822FA0 /* BarButtonView.swift */; }; FF1DF49B2BD8D23900822FA0 /* BarButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1DF49A2BD8D23900822FA0 /* BarButtonView.swift */; };
FF1F4B6D2BF9E60B000B4573 /* TournamentBuildView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */; }; FF1F4B6D2BF9E60B000B4573 /* TournamentBuildView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */; };
FF1F4B712BF9EFE9000B4573 /* TournamentInscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F4B702BF9EFE9000B4573 /* TournamentInscriptionView.swift */; };
FF2EFBF02BDE295E0049CE3B /* SendToAllView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */; }; FF2EFBF02BDE295E0049CE3B /* SendToAllView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */; };
FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FF3795602B9396D0004EA093 /* PadelClubApp.xcdatamodeld */; }; FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FF3795602B9396D0004EA093 /* PadelClubApp.xcdatamodeld */; };
FF3795662B9399AA004EA093 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3795652B9399AA004EA093 /* Persistence.swift */; }; FF3795662B9399AA004EA093 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3795652B9399AA004EA093 /* Persistence.swift */; };
@ -430,6 +431,7 @@
FF1DC55A2BAB80C400FD8220 /* DisplayContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayContext.swift; sourceTree = "<group>"; }; FF1DC55A2BAB80C400FD8220 /* DisplayContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayContext.swift; sourceTree = "<group>"; };
FF1DF49A2BD8D23900822FA0 /* BarButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarButtonView.swift; sourceTree = "<group>"; }; FF1DF49A2BD8D23900822FA0 /* BarButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarButtonView.swift; sourceTree = "<group>"; };
FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentBuildView.swift; sourceTree = "<group>"; }; FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentBuildView.swift; sourceTree = "<group>"; };
FF1F4B702BF9EFE9000B4573 /* TournamentInscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentInscriptionView.swift; sourceTree = "<group>"; };
FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToAllView.swift; sourceTree = "<group>"; }; FF2EFBEF2BDE295E0049CE3B /* SendToAllView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToAllView.swift; sourceTree = "<group>"; };
FF3795612B9396D0004EA093 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; }; FF3795612B9396D0004EA093 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
FF3795652B9399AA004EA093 /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; }; FF3795652B9399AA004EA093 /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
@ -920,6 +922,7 @@
children = ( children = (
FF70916B2B91005400AB08DA /* TournamentView.swift */, FF70916B2B91005400AB08DA /* TournamentView.swift */,
FF8F26402BADFC8700650388 /* TournamentInitView.swift */, FF8F26402BADFC8700650388 /* TournamentInitView.swift */,
FF1F4B702BF9EFE9000B4573 /* TournamentInscriptionView.swift */,
FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */, FF1F4B6C2BF9E60B000B4573 /* TournamentBuildView.swift */,
FF967CF52BAED51600A9A3BD /* TournamentRunningView.swift */, FF967CF52BAED51600A9A3BD /* TournamentRunningView.swift */,
FF089EBE2BB0B14600F0AEC7 /* FileImportView.swift */, FF089EBE2BB0B14600F0AEC7 /* FileImportView.swift */,
@ -1663,6 +1666,7 @@
FFC91B012BD85C2F00B29808 /* Court.swift in Sources */, FFC91B012BD85C2F00B29808 /* Court.swift in Sources */,
FF967CF82BAEDF0000A9A3BD /* Labels.swift in Sources */, FF967CF82BAEDF0000A9A3BD /* Labels.swift in Sources */,
FF089EB42BB0020000F0AEC7 /* PlayerSexPickerView.swift in Sources */, FF089EB42BB0020000F0AEC7 /* PlayerSexPickerView.swift in Sources */,
FF1F4B712BF9EFE9000B4573 /* TournamentInscriptionView.swift in Sources */,
FF9267FF2BCE94830080F940 /* CallSettingsView.swift in Sources */, FF9267FF2BCE94830080F940 /* CallSettingsView.swift in Sources */,
FF025ADD2BD0C94300A86CF8 /* FooterButtonView.swift in Sources */, FF025ADD2BD0C94300A86CF8 /* FooterButtonView.swift in Sources */,
FF5D0D852BB48997005CB568 /* RankCalculatorView.swift in Sources */, FF5D0D852BB48997005CB568 /* RankCalculatorView.swift in Sources */,

@ -35,9 +35,9 @@ class Club : ModelObject, Storable, Hashable {
var zipCode: String? var zipCode: String?
var latitude: Double? var latitude: Double?
var longitude: Double? var longitude: Double?
//var courtCount: Int? var courtCount: Int = 2
internal init(creator: String? = nil, 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) { internal init(creator: String? = nil, 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, courtCount: Int = 2) {
self.creator = creator self.creator = creator
self.name = name self.name = name
self.acronym = acronym ?? name.acronym() self.acronym = acronym ?? name.acronym()
@ -48,6 +48,7 @@ class Club : ModelObject, Storable, Hashable {
self.zipCode = zipCode self.zipCode = zipCode
self.latitude = latitude self.latitude = latitude
self.longitude = longitude self.longitude = longitude
self.courtCount = courtCount
} }
func clubTitle(_ displayStyle: DisplayStyle = .wide) -> String { func clubTitle(_ displayStyle: DisplayStyle = .wide) -> String {
@ -63,12 +64,12 @@ class Club : ModelObject, Storable, Hashable {
return URLs.main.url.appending(path: "?club=\(id)") return URLs.main.url.appending(path: "?club=\(id)")
} }
var courts: [Court] { var customizedCourts: [Court] {
Store.main.filter { $0.club == self.id }.sorted(by: \.index) Store.main.filter { $0.club == self.id }.sorted(by: \.index)
} }
override func deleteDependencies() throws { override func deleteDependencies() throws {
try Store.main.deleteDependencies(items: self.courts) try Store.main.deleteDependencies(items: self.customizedCourts)
} }
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
@ -83,6 +84,7 @@ class Club : ModelObject, Storable, Hashable {
case _zipCode = "zipCode" case _zipCode = "zipCode"
case _latitude = "latitude" case _latitude = "latitude"
case _longitude = "longitude" case _longitude = "longitude"
case _courtCount = "courtCount"
} }
} }

@ -402,10 +402,12 @@ class Tournament : ModelObject, Storable {
return .canceled return .canceled
} }
if startDate >= Date() { return .running } let isBuild = (groupStageCount > 0 && groupStages().isEmpty == false)
|| rounds().isEmpty == false
if (groupStageCount > 0 && groupStages().isEmpty == false) if isBuild && startDate <= Date() { return .running }
|| rounds().isEmpty == false {
if isBuild {
return .build return .build
} }
return .initial return .initial
@ -1415,7 +1417,7 @@ class Tournament : ModelObject, Storable {
} }
func courtNameIfAvailable(atIndex courtIndex: Int) -> String? { func courtNameIfAvailable(atIndex courtIndex: Int) -> String? {
club()?.courts.first(where: { $0.index == courtIndex })?.name club()?.customizedCourts.first(where: { $0.index == courtIndex })?.name
} }
func courtName(atIndex courtIndex: Int) -> String { func courtName(atIndex courtIndex: Int) -> String {

@ -404,11 +404,11 @@ struct TournamentRunningTip: Tip {
} }
var message: Text? { var message: Text? {
return Text("Le tournoi a commencé, les options utiles à sa préparation son accessible ici pour laisser la place aux matchs.") return Text("Le tournoi a commencé, les options utiles surtout à sa préparation sont maintenant accessibles dans le menu en haut à droite.")
} }
var image: Image? { var image: Image? {
Image(systemName: "ellipsis.circle.fill") Image(systemName: "ellipsis.circle")
} }
} }

@ -153,6 +153,24 @@ struct ClubDetailView: View {
} }
Section {
TournamentFieldsManagerView(localizedStringKey: "Terrains", count: $club.courtCount)
.disabled(displayContext == .lockedForEditing)
.onChange(of: club.courtCount) {
if displayContext != .addition {
do {
try dataStore.clubs.addOrUpdate(instance: club)
} catch {
Logger.error(error)
}
}
}
} footer: {
if displayContext == .lockedForEditing {
Text("Édition impossible, vous n'êtes pas le créateur de ce club.").foregroundStyle(.logoRed)
}
}
if let federalLink = club.federalLink() { if let federalLink = club.federalLink() {
Section { Section {
LabeledContent("Code Club") { LabeledContent("Code Club") {

@ -111,7 +111,7 @@ struct EventCreationView: View {
} }
tournaments.forEach { tournament in tournaments.forEach { tournament in
tournament.courtCount = selectedClub?.courts.count ?? 2 tournament.courtCount = selectedClub?.courtCount ?? 2
tournament.startDate = startingDate tournament.startDate = startingDate
tournament.dayDuration = duration tournament.dayDuration = duration
tournament.setupFederalSettings() tournament.setupFederalSettings()

@ -46,7 +46,7 @@ struct ToolboxView: View {
} }
Section { Section {
Link("Guide de la compétition", destination: URLs.padelRules) Link("Accéder au guide de la compétition", destination: URLs.padelRules.url)
} }
} }
.navigationTitle(TabDestination.toolbox.title) .navigationTitle(TabDestination.toolbox.title)

@ -81,7 +81,7 @@ struct TournamentClubSettingsView: View {
@ViewBuilder @ViewBuilder
private func _courtView(atIndex index: Int, tournamentClub: Club) -> some View { private func _courtView(atIndex index: Int, tournamentClub: Club) -> some View {
if let court = tournamentClub.courts.first(where: { $0.index == index }) { if let court = tournamentClub.customizedCourts.first(where: { $0.index == index }) {
LabeledContent { LabeledContent {
FooterButtonView("personnaliser") { FooterButtonView("personnaliser") {
selectedCourt = court selectedCourt = court

@ -12,8 +12,6 @@ struct TournamentBuildView: View {
@ViewBuilder @ViewBuilder
var body: some View { var body: some View {
TournamentInitView(tournament: tournament)
Section { Section {
NavigationLink(value: Screen.schedule) { NavigationLink(value: Screen.schedule) {
let tournamentStatus = tournament.scheduleStatus() let tournamentStatus = tournament.scheduleStatus()

@ -12,10 +12,17 @@ struct TournamentInitView: View {
@ViewBuilder @ViewBuilder
var body: some View { var body: some View {
Section {
NavigationLink(value: Screen.broadcast) {
LabeledContent {
// Text(tournament.isPrivate ? "privée" : "publique")
} label: {
Text("Publication")
}
}
if let event = tournament.eventObject() { if let event = tournament.eventObject() {
let tournaments = event.tournaments let tournaments = event.tournaments
Section {
NavigationLink(value: Screen.event) { NavigationLink(value: Screen.event) {
LabeledContent { LabeledContent {
Text(tournaments.count.formatted() + " épreuve" + tournaments.count.pluralSuffix) Text(tournaments.count.formatted() + " épreuve" + tournaments.count.pluralSuffix)
@ -24,9 +31,6 @@ struct TournamentInitView: View {
} }
} }
} }
}
Section {
NavigationLink(value: Screen.settings) { NavigationLink(value: Screen.settings) {
LabeledContent { LabeledContent {
Text(tournament.settingsDescriptionLocalizedLabel()) Text(tournament.settingsDescriptionLocalizedLabel())
@ -38,29 +42,6 @@ struct TournamentInitView: View {
} footer: { } footer: {
Text("La date, la catégorie, le niveau, le nombre de terrain, les formats, etc.") Text("La date, la catégorie, le niveau, le nombre de terrain, les formats, etc.")
} }
Section {
NavigationLink(value: Screen.broadcast) {
LabeledContent {
// Text(tournament.isPrivate ? "privée" : "publique")
} label: {
Text("Publication")
}
}
}
Section {
NavigationLink(value: Screen.structure) {
LabeledContent {
Text(tournament.structureDescriptionLocalizedLabel())
.tint(.master)
} label: {
LabelStructure()
}
}
} footer: {
Text("Nombre d'équipes, de poules, de qualifiés sortant, etc.")
}
} }
} }

@ -0,0 +1,70 @@
//
// TournamentInscriptionView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 19/05/2024.
//
import SwiftUI
import LeStorage
struct TournamentInscriptionView: View {
@EnvironmentObject var dataStore: DataStore
var tournament: Tournament
@ViewBuilder
var body: some View {
Section {
NavigationLink(value: Screen.inscription) {
LabeledContent {
Text(tournament.unsortedTeams().count.formatted() + "/" + tournament.teamCount.formatted())
} label: {
Text("Gestion des inscriptions")
if let closedRegistrationDate = tournament.closedRegistrationDate {
Text("clôturé le " + closedRegistrationDate.formatted(date: .abbreviated, time: .shortened))
}
}
}
if let endOfInscriptionDate = tournament.mandatoryRegistrationCloseDate(), tournament.inscriptionClosed() == false && tournament.hasStarted() == false {
LabeledContent {
Text(endOfInscriptionDate.formatted(date: .abbreviated, time: .shortened))
} label: {
Text("Date limite")
}
}
if tournament.state() != .running {
NavigationLink(value: Screen.structure) {
LabeledContent {
Text(tournament.structureDescriptionLocalizedLabel())
.tint(.master)
} label: {
LabelStructure()
}
}
}
} footer: {
if tournament.inscriptionClosed() == false && tournament.state() == .build && tournament.unsortedTeams().isEmpty == false && tournament.hasStarted() == false {
Button {
tournament.lockRegistration()
_save()
} label: {
Text("clôturer les inscriptions")
.underline()
}
.buttonStyle(.borderless)
} else if tournament.state() != .running {
Text("Nombre d'équipes, de poules, de qualifiés sortant, etc.")
}
}
}
private func _save() {
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
}
}

@ -18,8 +18,6 @@ struct TournamentRunningView: View {
@ViewBuilder @ViewBuilder
var body: some View { var body: some View {
TournamentBuildView(tournament: tournament)
MatchListView(section: "en cours", matches: tournament.runningMatches(allMatches)) MatchListView(section: "en cours", matches: tournament.runningMatches(allMatches))
MatchListView(section: "à lancer", matches: tournament.readyMatches(allMatches), isExpanded: false) MatchListView(section: "à lancer", matches: tournament.readyMatches(allMatches), isExpanded: false)
MatchListView(section: "disponible", matches: tournament.availableToStart(allMatches), isExpanded: false) MatchListView(section: "disponible", matches: tournament.availableToStart(allMatches), isExpanded: false)

@ -39,40 +39,10 @@ struct TournamentView: View {
var body: some View { var body: some View {
VStack(spacing: 0.0) { VStack(spacing: 0.0) {
List { List {
SubscriptionInfoView() TipView(tournamentRunningTip)
.tipStyle(tint: nil)
if tournament.state() != .canceled { SubscriptionInfoView()
Section {
NavigationLink(value: Screen.inscription) {
LabeledContent {
Text(tournament.unsortedTeams().count.formatted() + "/" + tournament.teamCount.formatted())
} label: {
Text("Gestion des inscriptions")
if let closedRegistrationDate = tournament.closedRegistrationDate {
Text("clôturé le " + closedRegistrationDate.formatted(date: .abbreviated, time: .shortened))
}
}
}
if let endOfInscriptionDate = tournament.mandatoryRegistrationCloseDate(), tournament.inscriptionClosed() == false && tournament.hasStarted() == false {
LabeledContent {
Text(endOfInscriptionDate.formatted(date: .abbreviated, time: .shortened))
} label: {
Text("Date limite")
}
}
} footer: {
if tournament.inscriptionClosed() == false && tournament.state() == .build && tournament.unsortedTeams().isEmpty == false && tournament.hasStarted() == false {
Button {
tournament.lockRegistration()
_save()
} label: {
Text("clôturer les inscriptions")
.underline()
}
.buttonStyle(.borderless)
}
}
}
switch tournament.state() { switch tournament.state() {
case .canceled: case .canceled:
@ -85,18 +55,24 @@ struct TournamentView: View {
Text("todo expliquer cet état") Text("todo expliquer cet état")
} }
case .initial: case .initial:
TournamentInscriptionView(tournament: tournament)
TournamentInitView(tournament: tournament) TournamentInitView(tournament: tournament)
case .build: case .build:
TournamentInscriptionView(tournament: tournament)
TournamentInitView(tournament: tournament)
TournamentBuildView(tournament: tournament) TournamentBuildView(tournament: tournament)
case .running: case .running:
TournamentRunningView(tournament: tournament) TournamentInscriptionView(tournament: tournament)
TournamentBuildView(tournament: tournament)
if tournament.hasEnded() { if tournament.hasEnded() {
Section {
NavigationLink(value: Screen.rankings) { NavigationLink(value: Screen.rankings) {
Text("Classement") Text("Classement")
} }
} }
} }
TournamentRunningView(tournament: tournament)
}
} }
} }
.toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar)
@ -189,14 +165,11 @@ struct TournamentView: View {
} label: { } label: {
LabelOptions() LabelOptions()
} }
.popoverTip(tournamentRunningTip)
.onAppear {
TournamentRunningTip.isRunning = tournament.state == .running
}
} }
} }
} }
.onAppear { .onAppear {
TournamentRunningTip.isRunning = tournament.state() == .running
Logger.log("Payment = \(String(describing: self.tournament.payment)), canceled = \(self.tournament.isCanceled)") Logger.log("Payment = \(String(describing: self.tournament.payment)), canceled = \(self.tournament.isCanceled)")
} }
} }

Loading…
Cancel
Save