You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
PadelClub/PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift

378 lines
14 KiB

//
// RegistrationSetupView.swift
// PadelClub
//
// Created by razmig on 20/11/2024.
//
import SwiftUI
import LeStorage
struct RegistrationSetupView: View {
@EnvironmentObject var dataStore: DataStore
@Bindable var tournament: Tournament
@State private var enableOnlineRegistration: Bool
@State private var registrationDateLimit: Date
@State private var openingRegistrationDate: Date
@State private var targetTeamCount: Int
@State private var waitingListLimit: Int
@State private var registrationDateLimitEnabled: Bool
@State private var targetTeamCountEnabled: Bool
@State private var waitingListLimitEnabled: Bool
@State private var openingRegistrationDateEnabled: Bool
@State private var userAccountIsRequired: Bool
@State private var licenseIsRequired: Bool
@State private var minPlayerPerTeam: Int
@State private var maxPlayerPerTeam: Int
@State private var showMoreInfos: Bool = false
@State private var hasChanges: Bool = false
@Environment(\.dismiss) private var dismiss
init(tournament: Tournament) {
self.tournament = tournament
_enableOnlineRegistration = .init(wrappedValue: tournament.enableOnlineRegistration)
// Registration Date Limit
if let registrationDateLimit = tournament.registrationDateLimit {
_registrationDateLimit = .init(wrappedValue: registrationDateLimit)
_registrationDateLimitEnabled = .init(wrappedValue: true)
} else {
_registrationDateLimit = .init(wrappedValue: tournament.startDate.truncateMinutesAndSeconds())
_registrationDateLimitEnabled = .init(wrappedValue: false)
}
// Opening Registration Date
if let openingRegistrationDate = tournament.openingRegistrationDate {
_openingRegistrationDate = .init(wrappedValue: openingRegistrationDate)
_openingRegistrationDateEnabled = .init(wrappedValue: true)
} else {
_openingRegistrationDate = .init(wrappedValue: tournament.creationDate.truncateMinutesAndSeconds())
_openingRegistrationDateEnabled = .init(wrappedValue: false)
}
// Target Team Count
_targetTeamCount = .init(wrappedValue: tournament.teamCount) // Default value
_targetTeamCountEnabled = .init(wrappedValue: false)
// Waiting List Limit
if let waitingListLimit = tournament.waitingListLimit {
_waitingListLimit = .init(wrappedValue: waitingListLimit)
_waitingListLimitEnabled = .init(wrappedValue: true)
} else {
_waitingListLimit = .init(wrappedValue: 0) // Default value
_waitingListLimitEnabled = .init(wrappedValue: false)
}
_userAccountIsRequired = .init(wrappedValue: tournament.accountIsRequired)
_licenseIsRequired = .init(wrappedValue: tournament.licenseIsRequired)
_maxPlayerPerTeam = .init(wrappedValue: tournament.maximumPlayerPerTeam)
_minPlayerPerTeam = .init(wrappedValue: tournament.minimumPlayerPerTeam)
}
var body: some View {
List {
Section {
Toggle(isOn: $enableOnlineRegistration) {
Text("Activer")
}
} footer: {
VStack(alignment: .leading) {
Text("Les inscriptions en ligne permettent à des joueurs de s'inscrire à votre tournoi en passant par le site Padel Club. Vous verrez alors votre liste d'inscription s'agrandir dans la vue Gestion des Inscriptions de l'application.")
FooterButtonView("En savoir plus") {
self.showMoreInfos = true
}
}
}
if enableOnlineRegistration {
if let shareURL = tournament.shareURL(.info) {
Section {
Link(destination: shareURL) {
Text(shareURL.absoluteString)
}
} header: {
Text("Page d'inscription")
} footer: {
HStack {
CopyPasteButtonView(pasteValue: shareURL.absoluteString)
Spacer()
ShareLink(item: shareURL) {
Label("Partager", systemImage: "square.and.arrow.up")
}
}
}
}
Section {
Toggle(isOn: $openingRegistrationDateEnabled) {
Text("Définir une date")
}
if openingRegistrationDateEnabled {
DatePicker(selection: $openingRegistrationDate) {
DateMenuView(date: $openingRegistrationDate)
}
}
} header: {
Text("Date d'ouverture des inscriptions")
} footer: {
Text("Activez et définissez une date d'ouverture pour les inscriptions au tournoi. Les inscriptions en ligne ne seront possible qu'à partir de cette date.")
}
Section {
Toggle(isOn: $registrationDateLimitEnabled) {
Text("Définir une date")
}
if registrationDateLimitEnabled {
DatePicker(selection: $registrationDateLimit) {
DateMenuView(date: $registrationDateLimit)
}
}
} header: {
Text("Date de fermeture des inscriptions")
} footer: {
Text("Si une date de fermeture des inscriptions en ligne est définie, alors plus aucune inscription ne sera possible après cette date. Sinon, la date du début du tournoi ou la date de clôture des inscriptions seront utilisées.")
}
Section {
// Toggle(isOn: $targetTeamCountEnabled) {
// Text("Activer une limite")
// }
//
// if targetTeamCountEnabled {
// StepperView(count: $targetTeamCount, minimum: 4)
// }
StepperView(count: $targetTeamCount, minimum: 4)
} header: {
Text("Paires admises")
} footer: {
Text("Les inscriptions seront indiqués en attente pour les joueurs au-délà de cette limite dans le cas où aucune limite de liste d'attente n'est active ou non atteinte. Dans le cas contraire, plus aucune inscription ne seront possibles.")
}
Section {
Toggle(isOn: $waitingListLimitEnabled) {
Text("Activer une limite")
}
if waitingListLimitEnabled {
StepperView(count: $waitingListLimit, minimum: 0)
}
} header: {
Text("Liste d'attente")
} footer: {
Text("Si une limite à la liste d'attente existe, les inscriptions ne seront plus possibles une fois la liste d'attente pleine. Si aucune limite de liste d'attente n'est active, alors les inscriptions seront toujours possibles. Les joueurs auront une indication comme quoi ils sont en liste d'attente.")
}
if tournament.isAnimation() {
Section {
// Toggle(isOn: $userAccountIsRequired) {
// Text("Compte Padel Club requis pour s'inscrire")
// }
// .disabled(true)
Toggle(isOn: $licenseIsRequired) {
Text("Licence FFT requise pour s'inscrire")
}
LabeledContent {
StepperView(count: $minPlayerPerTeam, minimum: 1, maximum: maxPlayerPerTeam)
} label: {
Text("Nombre minimum de joueurs possible")
}
LabeledContent {
StepperView(count: $maxPlayerPerTeam, minimum: minPlayerPerTeam)
} label: {
Text("Nombre maximum de joueurs possible")
}
}
}
} else {
ContentUnavailableView(
"Activez les inscriptions en ligne",
systemImage: "person.2.crop.square.stack.fill",
description: Text("Permettez aux joueurs de s'inscrire eux-mêmes à ce tournoi. Les équipes inscrites apparaîtront automatiquement dans la liste de l'arbitre. L'inscription en ligne requiert un email de contact et une licence FFT.")
)
}
}
.sheet(isPresented: $showMoreInfos) {
RegistrationInfoSheetView()
}
.toolbar(content: {
if hasChanges {
ToolbarItem(placement: .topBarLeading) {
Button("Annuler", role: .cancel) {
dismiss()
}
}
ToolbarItem(placement: .topBarTrailing) {
ButtonValidateView(role: .destructive) {
_save()
dismiss()
}
}
}
})
.toolbarRole(.editor)
.headerProminence(.increased)
.navigationTitle("Inscription en ligne")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.navigationBarBackButtonHidden(hasChanges)
.onChange(of: enableOnlineRegistration, {
_hasChanged()
})
.onChange(of: openingRegistrationDateEnabled) {
_hasChanged()
}
.onChange(of: openingRegistrationDate) {
_hasChanged()
}
.onChange(of: registrationDateLimitEnabled) {
_hasChanged()
}
.onChange(of: registrationDateLimit) {
_hasChanged()
}
.onChange(of: targetTeamCountEnabled) {
_hasChanged()
}
.onChange(of: targetTeamCount) {
_hasChanged()
}
.onChange(of: waitingListLimitEnabled) {
_hasChanged()
}
.onChange(of: waitingListLimit) {
_hasChanged()
}
.onChange(of: [minPlayerPerTeam, maxPlayerPerTeam]) {
_hasChanged()
}
.onChange(of: [userAccountIsRequired, licenseIsRequired]) {
_hasChanged()
}
}
private func _hasChanged() {
hasChanges = true
}
private func _save() {
hasChanges = false
tournament.enableOnlineRegistration = enableOnlineRegistration
if enableOnlineRegistration {
tournament.accountIsRequired = userAccountIsRequired
tournament.licenseIsRequired = licenseIsRequired
tournament.minimumPlayerPerTeam = minPlayerPerTeam
tournament.maximumPlayerPerTeam = maxPlayerPerTeam
} else {
tournament.accountIsRequired = true
tournament.licenseIsRequired = true
tournament.minimumPlayerPerTeam = 2
tournament.maximumPlayerPerTeam = 2
}
if openingRegistrationDateEnabled == false {
tournament.openingRegistrationDate = nil
} else {
tournament.openingRegistrationDate = openingRegistrationDate
}
if registrationDateLimitEnabled == false {
tournament.registrationDateLimit = nil
} else {
tournament.registrationDateLimit = registrationDateLimit
}
if targetTeamCountEnabled == false {
tournament.teamCount = 24
} else {
tournament.teamCount = targetTeamCount
}
if waitingListLimitEnabled == false {
tournament.waitingListLimit = nil
} else {
tournament.waitingListLimit = waitingListLimit
}
do {
try self.dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
dismiss()
}
}
enum OnlineRegistrationStatus: Int {
case open = 1
case notEnabled = 2
case notStarted = 3
case ended = 4
case waitingListPossible = 5
case waitingListFull = 6
case inProgress = 7
case endedWithResults = 8
var displayName: String {
switch self {
case .open:
return "Open"
case .notEnabled:
return "Not Enabled"
case .notStarted:
return "Not Started"
case .ended:
return "Ended"
case .waitingListPossible:
return "Waiting List Possible"
case .waitingListFull:
return "Waiting List Full"
case .inProgress:
return "In Progress"
case .endedWithResults:
return "Ended with Results"
}
}
func statusLocalized() -> String {
switch self {
case .open:
return "Inscription ouverte"
case .notEnabled:
return "Inscription désactivée"
case .notStarted:
return "Inscription pas encore ouverte"
case .ended:
return "Inscription terminée"
case .waitingListPossible:
return "Liste d'attente disponible"
case .waitingListFull:
return "Liste d'attente complète"
case .inProgress:
return "Tournoi en cours"
case .endedWithResults:
return "Tournoi terminé"
}
}
}