fix registration online

online_reg
Raz 11 months ago
parent 768902e827
commit 7b06c8cefc
  1. 16
      PadelClub.xcodeproj/project.pbxproj
  2. 32
      PadelClub/Data/Tournament.swift
  3. 2
      PadelClub/PadelClubApp.swift
  4. 23
      PadelClub/Utils/Tips.swift
  5. 1
      PadelClub/ViewModel/Screen.swift
  6. 2
      PadelClub/Views/Cashier/Event/EventCreationView.swift
  7. 2
      PadelClub/Views/Cashier/Event/EventTournamentsView.swift
  8. 2
      PadelClub/Views/Navigation/Agenda/CalendarView.swift
  9. 2
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  10. 10
      PadelClub/Views/Team/EditingTeamView.swift
  11. 67
      PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift
  12. 7
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  13. 8
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift
  14. 42
      PadelClub/Views/Tournament/Screen/TournamentRankView.swift
  15. 3
      PadelClub/Views/Tournament/Shared/TournamentCellView.swift
  16. 54
      PadelClub/Views/Tournament/TournamentView.swift

@ -798,9 +798,9 @@
FFBF41822BF73EB3001B24CB /* EventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41812BF73EB3001B24CB /* EventView.swift */; }; FFBF41822BF73EB3001B24CB /* EventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41812BF73EB3001B24CB /* EventView.swift */; };
FFBF41842BF75ED7001B24CB /* EventTournamentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41832BF75ED7001B24CB /* EventTournamentsView.swift */; }; FFBF41842BF75ED7001B24CB /* EventTournamentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41832BF75ED7001B24CB /* EventTournamentsView.swift */; };
FFBF41862BF75FDA001B24CB /* EventSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */; }; FFBF41862BF75FDA001B24CB /* EventSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */; };
FFBFC3912CEE3A0E000EBD8D /* RegisrationSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3902CEE3A0E000EBD8D /* RegisrationSetupView.swift */; }; FFBFC3912CEE3A0E000EBD8D /* RegistrationSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3902CEE3A0E000EBD8D /* RegistrationSetupView.swift */; };
FFBFC3922CEE3A0E000EBD8D /* RegisrationSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3902CEE3A0E000EBD8D /* RegisrationSetupView.swift */; }; FFBFC3922CEE3A0E000EBD8D /* RegistrationSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3902CEE3A0E000EBD8D /* RegistrationSetupView.swift */; };
FFBFC3932CEE3A0E000EBD8D /* RegisrationSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3902CEE3A0E000EBD8D /* RegisrationSetupView.swift */; }; FFBFC3932CEE3A0E000EBD8D /* RegistrationSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3902CEE3A0E000EBD8D /* RegistrationSetupView.swift */; };
FFBFC3952CF05CBB000EBD8D /* DateMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */; }; FFBFC3952CF05CBB000EBD8D /* DateMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */; };
FFBFC3962CF05CBB000EBD8D /* DateMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */; }; FFBFC3962CF05CBB000EBD8D /* DateMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */; };
FFBFC3972CF05CBB000EBD8D /* DateMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */; }; FFBFC3972CF05CBB000EBD8D /* DateMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */; };
@ -1194,7 +1194,7 @@
FFBF41812BF73EB3001B24CB /* EventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventView.swift; sourceTree = "<group>"; }; FFBF41812BF73EB3001B24CB /* EventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventView.swift; sourceTree = "<group>"; };
FFBF41832BF75ED7001B24CB /* EventTournamentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventTournamentsView.swift; sourceTree = "<group>"; }; FFBF41832BF75ED7001B24CB /* EventTournamentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventTournamentsView.swift; sourceTree = "<group>"; };
FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventSettingsView.swift; sourceTree = "<group>"; }; FFBF41852BF75FDA001B24CB /* EventSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventSettingsView.swift; sourceTree = "<group>"; };
FFBFC3902CEE3A0E000EBD8D /* RegisrationSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisrationSetupView.swift; sourceTree = "<group>"; }; FFBFC3902CEE3A0E000EBD8D /* RegistrationSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationSetupView.swift; sourceTree = "<group>"; };
FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateMenuView.swift; sourceTree = "<group>"; }; FFBFC3942CF05CBB000EBD8D /* DateMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateMenuView.swift; sourceTree = "<group>"; };
FFC1E1032BAC28C6008D6F59 /* ClubSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClubSearchView.swift; sourceTree = "<group>"; }; FFC1E1032BAC28C6008D6F59 /* ClubSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClubSearchView.swift; sourceTree = "<group>"; };
FFC1E1072BAC29FC008D6F59 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; }; FFC1E1072BAC29FC008D6F59 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
@ -1680,7 +1680,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FF70916D2B9108C600AB08DA /* InscriptionManagerView.swift */, FF70916D2B9108C600AB08DA /* InscriptionManagerView.swift */,
FFBFC3902CEE3A0E000EBD8D /* RegisrationSetupView.swift */, FFBFC3902CEE3A0E000EBD8D /* RegistrationSetupView.swift */,
FF90FC1C2C44FB3E009339B2 /* AddTeamView.swift */, FF90FC1C2C44FB3E009339B2 /* AddTeamView.swift */,
FF8F26422BADFE5B00650388 /* TournamentSettingsView.swift */, FF8F26422BADFE5B00650388 /* TournamentSettingsView.swift */,
FF8F26532BAE1E4400650388 /* TableStructureView.swift */, FF8F26532BAE1E4400650388 /* TableStructureView.swift */,
@ -2436,7 +2436,7 @@
C45BAE442BCA753E002EEC8A /* Purchase.swift in Sources */, C45BAE442BCA753E002EEC8A /* Purchase.swift in Sources */,
FF6EC8FE2B94792300EA7F5A /* Screen.swift in Sources */, FF6EC8FE2B94792300EA7F5A /* Screen.swift in Sources */,
FF967CEE2BAECBD700A9A3BD /* Round.swift in Sources */, FF967CEE2BAECBD700A9A3BD /* Round.swift in Sources */,
FFBFC3922CEE3A0E000EBD8D /* RegisrationSetupView.swift in Sources */, FFBFC3922CEE3A0E000EBD8D /* RegistrationSetupView.swift in Sources */,
FF5BAF6E2BE0B3C8008B4B7E /* FederalDataViewModel.swift in Sources */, FF5BAF6E2BE0B3C8008B4B7E /* FederalDataViewModel.swift in Sources */,
FF3F74FF2B91A2D4004CFE0E /* AgendaDestination.swift in Sources */, FF3F74FF2B91A2D4004CFE0E /* AgendaDestination.swift in Sources */,
FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */, FF3795622B9396D0004EA093 /* PadelClubApp.xcdatamodeld in Sources */,
@ -2723,7 +2723,7 @@
FF4CBFB92C996C0600151637 /* Purchase.swift in Sources */, FF4CBFB92C996C0600151637 /* Purchase.swift in Sources */,
FF4CBFBA2C996C0600151637 /* Screen.swift in Sources */, FF4CBFBA2C996C0600151637 /* Screen.swift in Sources */,
FF4CBFBB2C996C0600151637 /* Round.swift in Sources */, FF4CBFBB2C996C0600151637 /* Round.swift in Sources */,
FFBFC3912CEE3A0E000EBD8D /* RegisrationSetupView.swift in Sources */, FFBFC3912CEE3A0E000EBD8D /* RegistrationSetupView.swift in Sources */,
FF4CBFBC2C996C0600151637 /* FederalDataViewModel.swift in Sources */, FF4CBFBC2C996C0600151637 /* FederalDataViewModel.swift in Sources */,
FF4CBFBD2C996C0600151637 /* AgendaDestination.swift in Sources */, FF4CBFBD2C996C0600151637 /* AgendaDestination.swift in Sources */,
FF4CBFBE2C996C0600151637 /* PadelClubApp.xcdatamodeld in Sources */, FF4CBFBE2C996C0600151637 /* PadelClubApp.xcdatamodeld in Sources */,
@ -2989,7 +2989,7 @@
FF70FB382C90584900129CC2 /* Purchase.swift in Sources */, FF70FB382C90584900129CC2 /* Purchase.swift in Sources */,
FF70FB392C90584900129CC2 /* Screen.swift in Sources */, FF70FB392C90584900129CC2 /* Screen.swift in Sources */,
FF70FB3A2C90584900129CC2 /* Round.swift in Sources */, FF70FB3A2C90584900129CC2 /* Round.swift in Sources */,
FFBFC3932CEE3A0E000EBD8D /* RegisrationSetupView.swift in Sources */, FFBFC3932CEE3A0E000EBD8D /* RegistrationSetupView.swift in Sources */,
FF70FB3B2C90584900129CC2 /* FederalDataViewModel.swift in Sources */, FF70FB3B2C90584900129CC2 /* FederalDataViewModel.swift in Sources */,
FF70FB3C2C90584900129CC2 /* AgendaDestination.swift in Sources */, FF70FB3C2C90584900129CC2 /* AgendaDestination.swift in Sources */,
FF70FB3D2C90584900129CC2 /* PadelClubApp.xcdatamodeld in Sources */, FF70FB3D2C90584900129CC2 /* PadelClubApp.xcdatamodeld in Sources */,

@ -2131,12 +2131,16 @@ defer {
} }
} }
func setupFederalSettings() { func setupFederalSettings(fromEvent event: Event?) {
teamSorting = tournamentLevel.defaultTeamSortingType teamSorting = tournamentLevel.defaultTeamSortingType
groupStageMatchFormat = groupStageSmartMatchFormat() groupStageMatchFormat = groupStageSmartMatchFormat()
loserBracketMatchFormat = loserBracketSmartMatchFormat(5) loserBracketMatchFormat = loserBracketSmartMatchFormat(5)
matchFormat = roundSmartMatchFormat(5) matchFormat = roundSmartMatchFormat(5)
entryFee = tournamentLevel.entryFee entryFee = tournamentLevel.entryFee
if event?.tenupId != nil {
enableOnlineRegistration = true
registrationDateLimit = deadline(for: .inscription)
}
} }
func roundSmartMatchFormat(_ roundIndex: Int) -> MatchFormat { func roundSmartMatchFormat(_ roundIndex: Int) -> MatchFormat {
@ -2504,6 +2508,32 @@ defer {
return .open return .open
} }
// MARK: - Status
func shouldTournamentBeOver() -> Bool {
#if _DEBUGING_TIME //DEBUGING TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func shouldTournamentBeOver()", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
if isDeleted == false && hasEnded() == false && hasStarted() {
let allMatches = allMatches()
let remainingMatches = allMatches.filter({ $0.hasEnded() == false && $0.startDate != nil })
let calendar = Calendar.current
let anyTomorrow = remainingMatches.anySatisfy({ calendar.isDateInTomorrow($0.startDate!) })
if anyTomorrow == false, let endDate = allMatches.filter({ $0.hasEnded() }).sorted(by: \.endDate!, order: .ascending).last?.endDate, endDate.timeIntervalSinceNow <= -2 * 3600 {
return true
}
}
return false
}
// MARK: - // MARK: -
func insertOnServer() throws { func insertOnServer() throws {

@ -102,7 +102,7 @@ print("Running in Release mode")
//try? Tips.resetDatastore() //try? Tips.resetDatastore()
try? Tips.configure([ try? Tips.configure([
.displayFrequency(.daily), .displayFrequency(.immediate),
.datastoreLocation(.applicationDefault) .datastoreLocation(.applicationDefault)
]) ])
} }

@ -572,6 +572,29 @@ struct PlayerTournamentSearchTip: Tip {
} }
struct OnlineRegistrationTip: Tip {
var title: Text {
Text("Inscription en ligne")
}
var message: Text? {
Text("Facilitez les inscriptions à votre tournoi en activant l'inscription en ligne. Les joueurs pourront s'inscrire directement depuis l'application ou le site Padel Club.")
}
var image: Image? {
Image(systemName: "person.2.crop.square.stack")
}
var actions: [Action] {
Action(id: ActionKey.enableOnlineRegistration.rawValue, title: "Activer dans les réglages du tournoi")
}
enum ActionKey: String {
case enableOnlineRegistration = "enableOnlineRegistration"
}
}
struct TipStyleModifier: ViewModifier { struct TipStyleModifier: ViewModifier {
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
var tint: Color? var tint: Color?

@ -21,4 +21,5 @@ enum Screen: String, Codable {
case event case event
case print case print
case restingTime case restingTime
case stateSettings
} }

@ -143,7 +143,7 @@ struct EventCreationView: View {
tournament.courtCount = selectedClub?.courtCount ?? 2 tournament.courtCount = selectedClub?.courtCount ?? 2
tournament.startDate = startingDate tournament.startDate = startingDate
tournament.dayDuration = duration tournament.dayDuration = duration
tournament.setupFederalSettings() tournament.setupFederalSettings(fromEvent: event)
} }
do { do {

@ -63,7 +63,7 @@ struct EventTournamentsView: View {
newTournament.courtCount = event.eventCourtCount() newTournament.courtCount = event.eventCourtCount()
newTournament.startDate = event.eventStartDate() newTournament.startDate = event.eventStartDate()
newTournament.dayDuration = event.eventDayDuration() newTournament.dayDuration = event.eventDayDuration()
newTournament.setupFederalSettings() newTournament.setupFederalSettings(fromEvent: event)
do { do {
try dataStore.tournaments.addOrUpdate(instance: newTournament) try dataStore.tournaments.addOrUpdate(instance: newTournament)

@ -173,7 +173,7 @@ struct CalendarView: View {
newTournament.federalTournamentAge = build.age newTournament.federalTournamentAge = build.age
newTournament.dayDuration = federalTournament.dayDuration newTournament.dayDuration = federalTournament.dayDuration
newTournament.startDate = federalTournament.startDate.atBeginningOfDay(hourInt: 9) newTournament.startDate = federalTournament.startDate.atBeginningOfDay(hourInt: 9)
newTournament.setupFederalSettings() newTournament.setupFederalSettings(fromEvent: event)
do { do {
try dataStore.tournaments.addOrUpdate(instance: newTournament) try dataStore.tournaments.addOrUpdate(instance: newTournament)
} catch { } catch {

@ -37,7 +37,6 @@ struct EventListView: View {
Text("\(count.formatted()) tournoi" + count.pluralSuffix) Text("\(count.formatted()) tournoi" + count.pluralSuffix)
} }
} }
.id(sectionIndex)
.headerProminence(.increased) .headerProminence(.increased)
} }
} }
@ -119,6 +118,7 @@ struct EventListView: View {
NavigationLink(value: tournament) { NavigationLink(value: tournament) {
TournamentCellView(tournament: tournament) TournamentCellView(tournament: tournament)
} }
.listRowView(isActive: tournament.shouldTournamentBeOver(), color: .red, hideColorVariation: true, alignment: .leading)
.contextMenu { .contextMenu {
if tournament.hasEnded() == false { if tournament.hasEnded() == false {
Button { Button {

@ -53,6 +53,12 @@ struct EditingTeamView: View {
} }
TeamDetailView(team: team) TeamDetailView(team: team)
} header: {
if team.hasRegisteredOnline() {
Text("Inscription en ligne")
} else {
Text("Inscription par vous-même")
}
} footer: { } footer: {
HStack { HStack {
CopyPasteButtonView(pasteValue: team.playersPasteData()) CopyPasteButtonView(pasteValue: team.playersPasteData())
@ -203,6 +209,10 @@ struct EditingTeamView: View {
} }
dismiss() dismiss()
} }
} footer: {
if team.hasRegisteredOnline() {
Text("Attention, supprimer cette équipe notifiera par email que leur inscription a été annulée.")
}
} }
} }
.navigationBarBackButtonHidden(focusedField != nil) .navigationBarBackButtonHidden(focusedField != nil)

@ -32,39 +32,6 @@ struct TournamentGeneralSettingsView: View {
var body: some View { var body: some View {
@Bindable var tournament = tournament @Bindable var tournament = tournament
Form { Form {
Section {
TextField("Nom du tournoi", text: $tournamentName, axis: .vertical)
.lineLimit(2)
.frame(maxWidth: .infinity)
.keyboardType(.alphabet)
.focused($focusedField, equals: ._name)
} header: {
Text("Nom du tournoi")
}
Section {
ZStack {
Text(tournamentInformation).opacity(0)
Text(ContactType.defaultCustomMessage).opacity(0)
TextEditor(text: $tournamentInformation)
.keyboardType(.alphabet)
.focused($focusedField, equals: ._information)
}
.frame(maxHeight: 200)
.overlay {
if tournamentInformation.isEmpty {
Text("Texte visible dans l'onglet informations sur Padel Club.").italic()
}
}
} header: {
Text("Description du tournoi")
} footer: {
FooterButtonView("Ajouter le prix de l'inscription") {
tournamentInformation.append("\n" + tournament.entryFeeMessage)
}
}
Section { Section {
TournamentDatePickerView() TournamentDatePickerView()
TournamentDurationManagerView() TournamentDurationManagerView()
@ -83,7 +50,7 @@ struct TournamentGeneralSettingsView: View {
Section { Section {
NavigationLink { NavigationLink {
RegisrationSetupView(tournament: tournament) RegistrationSetupView(tournament: tournament)
} label: { } label: {
LabeledContent { LabeledContent {
if tournament.enableOnlineRegistration { if tournament.enableOnlineRegistration {
@ -104,6 +71,38 @@ struct TournamentGeneralSettingsView: View {
Text("Paramétrez les possibilités d'inscription en ligne à votre tournoi via Padel Club") Text("Paramétrez les possibilités d'inscription en ligne à votre tournoi via Padel Club")
} }
Section {
TextField("Nom du tournoi", text: $tournamentName, axis: .vertical)
.lineLimit(2)
.frame(maxWidth: .infinity)
.keyboardType(.alphabet)
.focused($focusedField, equals: ._name)
} header: {
Text("Nom du tournoi")
}
Section {
ZStack {
Text(tournamentInformation).opacity(0)
Text(ContactType.defaultCustomMessage).opacity(0)
TextEditor(text: $tournamentInformation)
.keyboardType(.alphabet)
.focused($focusedField, equals: ._information)
}
.frame(maxHeight: 200)
.overlay {
if tournamentInformation.isEmpty {
Text("Texte visible dans l'onglet informations sur Padel Club.").italic()
}
}
} header: {
Text("Description du tournoi")
} footer: {
FooterButtonView("Ajouter le prix de l'inscription") {
tournamentInformation.append("\n" + tournament.entryFeeMessage)
}
}
Section { Section {
TournamentLevelPickerView() TournamentLevelPickerView()
} }

@ -23,6 +23,7 @@ let teamsExportTip = TeamsExportTip()
struct InscriptionManagerView: View { struct InscriptionManagerView: View {
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@Environment(NavigationViewModel.self) var navigation: NavigationViewModel
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
@ -248,6 +249,10 @@ struct InscriptionManagerView: View {
RowButtonView("Rafraîchir la liste") { RowButtonView("Rafraîchir la liste") {
await _refreshList() await _refreshList()
} }
} else {
RowButtonView("Inscription en ligne") {
navigation.path.append(Screen.settings)
}
} }
} }
} }
@ -608,9 +613,11 @@ struct InscriptionManagerView: View {
} label: { } label: {
TeamRowView(team: team) TeamRowView(team: team)
} }
#if DEBUG
.swipeActions(edge: .trailing, allowsFullSwipe: true) { .swipeActions(edge: .trailing, allowsFullSwipe: true) {
_teamDeleteButtonView(team) _teamDeleteButtonView(team)
} }
#endif
.listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true) .listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true)
} }
} header: { } header: {

@ -1,5 +1,5 @@
// //
// RegisrationSetupView.swift // RegistrationSetupView.swift
// PadelClub // PadelClub
// //
// Created by razmig on 20/11/2024. // Created by razmig on 20/11/2024.
@ -8,7 +8,7 @@
import SwiftUI import SwiftUI
import LeStorage import LeStorage
struct RegisrationSetupView: View { struct RegistrationSetupView: View {
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@Bindable var tournament: Tournament @Bindable var tournament: Tournament
@State private var enableOnlineRegistration: Bool @State private var enableOnlineRegistration: Bool
@ -89,7 +89,9 @@ struct RegisrationSetupView: View {
if enableOnlineRegistration { if enableOnlineRegistration {
if let shareURL = tournament.shareURL(.info) { if let shareURL = tournament.shareURL(.info) {
Section { Section {
ShareLink(item: shareURL) ShareLink(item: shareURL) {
Text(shareURL.absoluteString)
}
} header: { } header: {
Text("Page d'inscription") Text("Page d'inscription")
} footer: { } footer: {

@ -28,6 +28,14 @@ struct TournamentRankView: View {
} }
} }
var hideRankings: Binding<Bool> {
Binding {
tournament.publishRankings == false
} set: { value in
tournament.publishRankings = !value
}
}
var body: some View { var body: some View {
List { List {
@Bindable var tournament = tournament @Bindable var tournament = tournament
@ -53,18 +61,17 @@ struct TournamentRankView: View {
} }
//affiche l'onglet sur le site, car sur le broadcast c'est dispo automatiquement de toute façon //affiche l'onglet sur le site, car sur le broadcast c'est dispo automatiquement de toute façon
Toggle(isOn: $tournament.publishRankings) { Toggle(isOn: $tournament.publishRankings) {
Text("Publier sur Padel Club") if calculating {
if let url = tournament.shareURL(.rankings) { ProgressView("Calcul en cours")
Link(destination: url) { } else {
Text("Accéder à la page") Text("Publier sur Padel Club")
}
} }
} }
.onChange(of: tournament.publishRankings) { .disabled(calculating)
do { } footer: {
try dataStore.tournaments.addOrUpdate(instance: tournament) if let url = tournament.shareURL(.rankings) {
} catch { Link(destination: url) {
Logger.error(error) Text("Voir la page des classements sur Padel Club")
} }
} }
} }
@ -88,6 +95,8 @@ struct TournamentRankView: View {
team.finalRanking = nil team.finalRanking = nil
team.pointsEarned = nil team.pointsEarned = nil
} }
tournament.publishRankings = false
_save() _save()
} }
} }
@ -107,6 +116,13 @@ struct TournamentRankView: View {
} }
} }
.id(calculating) .id(calculating)
.onChange(of: tournament.publishRankings) {
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
}
.alert("Position", isPresented: isEditingTeam) { .alert("Position", isPresented: isEditingTeam) {
if let selectedTeam { if let selectedTeam {
@Bindable var team = selectedTeam @Bindable var team = selectedTeam
@ -131,16 +147,12 @@ struct TournamentRankView: View {
} }
} }
} }
.overlay(content: {
if calculating {
ProgressView()
}
})
.onAppear { .onAppear {
let rankingPublished = tournament.selectedSortedTeams().anySatisfy({ $0.finalRanking != nil }) let rankingPublished = tournament.selectedSortedTeams().anySatisfy({ $0.finalRanking != nil })
if rankingPublished == false { if rankingPublished == false {
Task { Task {
await _calculateRankings() await _calculateRankings()
tournament.publishRankings = true
} }
} }
} }

@ -160,6 +160,7 @@ struct TournamentCellView: View {
} }
} }
.font(.caption) .font(.caption)
.listRowView(isActive: existingTournament != nil, color: .green, hideColorVariation: true, alignment: .leading)
} }
private func _createOrShow(federalTournament: FederalTournament, existingTournament: Tournament?, build: any TournamentBuildHolder) { private func _createOrShow(federalTournament: FederalTournament, existingTournament: Tournament?, build: any TournamentBuildHolder) {
@ -178,7 +179,7 @@ struct TournamentCellView: View {
newTournament.federalTournamentAge = build.age newTournament.federalTournamentAge = build.age
newTournament.dayDuration = federalTournament.dayDuration newTournament.dayDuration = federalTournament.dayDuration
newTournament.startDate = federalTournament.startDate.atBeginningOfDay(hourInt: 9) newTournament.startDate = federalTournament.startDate.atBeginningOfDay(hourInt: 9)
newTournament.setupFederalSettings() newTournament.setupFederalSettings(fromEvent: event)
do { do {
try dataStore.tournaments.addOrUpdate(instance: newTournament) try dataStore.tournaments.addOrUpdate(instance: newTournament)
} catch { } catch {

@ -18,6 +18,7 @@ struct TournamentView: View {
let tournamentSelectionTip: TournamentSelectionTip = TournamentSelectionTip() let tournamentSelectionTip: TournamentSelectionTip = TournamentSelectionTip()
let tournamentRunningTip: TournamentRunningTip = TournamentRunningTip() let tournamentRunningTip: TournamentRunningTip = TournamentRunningTip()
let onlineRegistrationTip: OnlineRegistrationTip = OnlineRegistrationTip()
var selectedTournamentId: Binding<String> { Binding( var selectedTournamentId: Binding<String> { Binding(
get: { tournament.id }, get: { tournament.id },
@ -59,17 +60,63 @@ struct TournamentView: View {
} }
} }
case .initial: case .initial:
if tournament.enableOnlineRegistration == false {
TipView(onlineRegistrationTip) { actions in
navigation.path.append(Screen.settings)
}
.tipStyle(tint: .master, asSection: true)
}
Section { Section {
TournamentInscriptionView(tournament: tournament) TournamentInscriptionView(tournament: tournament)
} }
TournamentInitView(tournament: tournament) TournamentInitView(tournament: tournament)
case .build: case .build:
if tournament.enableOnlineRegistration == false {
TipView(onlineRegistrationTip) { actions in
navigation.path.append(Screen.settings)
}
.tipStyle(tint: .master, asSection: true)
}
Section { Section {
TournamentInscriptionView(tournament: tournament) TournamentInscriptionView(tournament: tournament)
} }
TournamentBuildView(tournament: tournament) TournamentBuildView(tournament: tournament)
TournamentInitView(tournament: tournament) TournamentInitView(tournament: tournament)
case .running: case .running:
if tournament.shouldTournamentBeOver() {
Section {
Menu {
Button("Scores manquants") {
if let activeRound = tournament.getActiveRound() {
navigation.path.append(Screen.round)
} else if let activeGroupStage = tournament.getActiveGroupStage() {
navigation.path.append(Screen.groupStage)
}
}
Button {
navigation.path.append(Screen.stateSettings)
} label: {
Text("Annuler le tournoi")
}
} label: {
Label("Actions rapides", systemImage: "bolt.circle")
.foregroundColor(.white)
.frame(height: 32)
.font(.headline)
.frame(maxWidth: .infinity)
}
.menuStyle(.button)
.buttonStyle(.borderedProminent)
.tint(.logoYellow)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(.zero))
}
}
TournamentBuildView(tournament: tournament) TournamentBuildView(tournament: tournament)
TournamentRunningView(tournament: tournament) TournamentRunningView(tournament: tournament)
case .finished: case .finished:
@ -113,6 +160,9 @@ struct TournamentView: View {
PrintSettingsView(tournament: tournament) PrintSettingsView(tournament: tournament)
case .restingTime: case .restingTime:
TeamRestingView() TeamRestingView()
case .stateSettings:
TournamentStatusView(tournament: tournament)
} }
} }
.environment(tournament) .environment(tournament)
@ -197,9 +247,7 @@ struct TournamentView: View {
Divider() Divider()
NavigationLink { NavigationLink(value: Screen.stateSettings) {
TournamentStatusView(tournament: tournament)
} label: {
Text("Gestion du tournoi") Text("Gestion du tournoi")
Text("Annuler, supprimer ou terminer le tournoi") Text("Annuler, supprimer ou terminer le tournoi")
} }

Loading…
Cancel
Save