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.
355 lines
15 KiB
355 lines
15 KiB
//
|
|
// TournamentGeneralSettingsView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 18/04/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import LeStorage
|
|
|
|
struct TournamentGeneralSettingsView: View {
|
|
@EnvironmentObject var dataStore: DataStore
|
|
|
|
@Bindable var tournament: Tournament
|
|
@State private var tournamentName: String = ""
|
|
@State private var tournamentInformation: String = ""
|
|
@State private var entryFee: Double? = nil
|
|
@State private var umpireCustomMail: String
|
|
@State private var umpireCustomPhone: String
|
|
@State private var umpireCustomContact: String
|
|
@State private var umpireCustomMailIsInvalid: Bool = false
|
|
@State private var umpireCustomPhoneIsInvalid: Bool = false
|
|
|
|
@FocusState private var focusedField: Tournament.CodingKeys?
|
|
let priceTags: [Double] = [15.0, 20.0, 25.0]
|
|
|
|
init(tournament: Tournament) {
|
|
self.tournament = tournament
|
|
_tournamentName = State(wrappedValue: tournament.name ?? "")
|
|
_tournamentInformation = State(wrappedValue: tournament.information ?? "")
|
|
_entryFee = State(wrappedValue: tournament.entryFee)
|
|
_umpireCustomMail = State(wrappedValue: tournament.umpireCustomMail ?? "")
|
|
_umpireCustomPhone = State(wrappedValue: tournament.umpireCustomPhone ?? "")
|
|
_umpireCustomContact = State(wrappedValue: tournament.umpireCustomContact ?? "")
|
|
}
|
|
|
|
var body: some View {
|
|
@Bindable var tournament = tournament
|
|
Form {
|
|
Section {
|
|
TournamentDatePickerView()
|
|
TournamentDurationManagerView()
|
|
LabeledContent {
|
|
TextField(tournament.isFree() ? "Gratuite" : "Inscription", value: $entryFee, format: .currency(code: Locale.defaultCurrency()))
|
|
.keyboardType(.decimalPad)
|
|
.multilineTextAlignment(.trailing)
|
|
.frame(maxWidth: .infinity)
|
|
.focused($focusedField, equals: ._entryFee)
|
|
} label: {
|
|
Text("Inscription")
|
|
}
|
|
} footer: {
|
|
Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.")
|
|
}
|
|
|
|
if tournament.onlineRegistrationCanBeEnabled() {
|
|
Section {
|
|
NavigationLink {
|
|
RegistrationSetupView(tournament: tournament)
|
|
} label: {
|
|
LabeledContent {
|
|
if tournament.enableOnlineRegistration {
|
|
Text("activée").foregroundStyle(.green)
|
|
.font(.headline)
|
|
} else {
|
|
Text("désactivée").foregroundStyle(.logoRed)
|
|
.font(.headline)
|
|
}
|
|
} label: {
|
|
Text("Accéder aux paramètres")
|
|
Text(tournament.getOnlineRegistrationStatus().statusLocalized())
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Inscription en ligne")
|
|
} footer: {
|
|
Text("Paramétrez les possibilités d'inscription en ligne à votre tournoi via Padel Club")
|
|
}
|
|
}
|
|
|
|
_customUmpireView()
|
|
|
|
Section {
|
|
if tournament.hideUmpireMail, tournament.hideUmpirePhone, tournament.enableOnlineRegistration {
|
|
Text("Attention, les emails envoyés automatiquement au regard des inscriptions en ligne ne contiendront aucun moyen de vous contacter.").foregroundStyle(.logoRed)
|
|
}
|
|
|
|
Toggle(isOn: $tournament.hideUmpireMail) {
|
|
Text("Masquer l'email")
|
|
}
|
|
Toggle(isOn: $tournament.hideUmpirePhone) {
|
|
Text("Masquer le téléphone")
|
|
}
|
|
|
|
} footer: {
|
|
Text("Ces informations ne seront pas affichées sur la page d'information du tournoi sur Padel Club et dans les emails envoyés automatiquement au regard des inscriptions en lignes.")
|
|
}
|
|
|
|
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, focusedField != ._information {
|
|
Text("Texte visible dans l'onglet informations sur Padel Club.").italic()
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Description du tournoi")
|
|
} footer: {
|
|
FooterButtonView("Ajouter le prix de l'inscription") {
|
|
tournamentInformation.append("\n" + tournament.entryFeeMessage)
|
|
}
|
|
}
|
|
}
|
|
.navigationBarBackButtonHidden(focusedField != nil)
|
|
.toolbar(content: {
|
|
if focusedField != nil {
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
Button("Annuler", role: .cancel) {
|
|
focusedField = nil
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.toolbarBackground(.visible, for: .navigationBar)
|
|
.toolbar {
|
|
if focusedField != nil {
|
|
ToolbarItem(placement: .keyboard) {
|
|
HStack {
|
|
if focusedField == ._entryFee {
|
|
if tournament.isFree() {
|
|
ForEach(priceTags, id: \.self) { priceTag in
|
|
Button(priceTag.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0)))) {
|
|
entryFee = priceTag
|
|
tournament.entryFee = priceTag
|
|
focusedField = nil
|
|
}
|
|
.buttonStyle(.bordered)
|
|
}
|
|
} else {
|
|
Button("Gratuit") {
|
|
entryFee = nil
|
|
tournament.entryFee = nil
|
|
focusedField = nil
|
|
}
|
|
.buttonStyle(.bordered)
|
|
|
|
}
|
|
} else {
|
|
if focusedField == ._name, tournamentName.isEmpty == false {
|
|
Button("Effacer") {
|
|
tournament.name = nil
|
|
tournamentName = ""
|
|
}
|
|
.buttonStyle(.borderless)
|
|
} else if focusedField == ._information, tournamentInformation.isEmpty == false {
|
|
Button("Effacer") {
|
|
tournament.information = nil
|
|
tournamentInformation = ""
|
|
}
|
|
.buttonStyle(.borderless)
|
|
} else if focusedField == ._umpireCustomMail, umpireCustomMail.isEmpty == false {
|
|
Button("Effacer") {
|
|
_deleteUmpireMail()
|
|
}
|
|
.buttonStyle(.borderless)
|
|
} else if focusedField == ._umpireCustomPhone, umpireCustomPhone.isEmpty == false {
|
|
Button("Effacer") {
|
|
_deleteUmpirePhone()
|
|
}
|
|
.buttonStyle(.borderless)
|
|
} else if focusedField == ._umpireCustomContact, umpireCustomContact.isEmpty == false {
|
|
Button("Effacer") {
|
|
_deleteUmpireContact()
|
|
}
|
|
.buttonStyle(.borderless)
|
|
}
|
|
}
|
|
Spacer()
|
|
Button("Valider") {
|
|
focusedField = nil
|
|
}
|
|
.buttonStyle(.bordered)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.onChange(of: tournament.startDate) {
|
|
_save()
|
|
}
|
|
.onChange(of: tournament.entryFee) {
|
|
_save()
|
|
}
|
|
.onChange(of: [tournament.name, tournament.information, tournament.umpireCustomMail, tournament.umpireCustomPhone, tournament.umpireCustomContact]) {
|
|
_save()
|
|
}
|
|
.onChange(of: [tournament.hideUmpireMail, tournament.hideUmpirePhone]) {
|
|
_save()
|
|
}
|
|
.onChange(of: tournament.dayDuration) {
|
|
_save()
|
|
}
|
|
.onChange(of: focusedField) { old, new in
|
|
if old == ._name {
|
|
let tournamentName = tournamentName.prefixMultilineTrimmed(200)
|
|
if tournamentName.isEmpty {
|
|
tournament.name = nil
|
|
} else {
|
|
tournament.name = tournamentName
|
|
}
|
|
} else if old == ._information {
|
|
let tournamentInformation = tournamentInformation.prefixMultilineTrimmed(4000)
|
|
if tournamentInformation.isEmpty {
|
|
tournament.information = nil
|
|
} else {
|
|
tournament.information = tournamentInformation
|
|
}
|
|
} else if old == ._entryFee {
|
|
tournament.entryFee = entryFee
|
|
} else if old == ._umpireCustomMail {
|
|
_confirmUmpireMail()
|
|
} else if old == ._umpireCustomPhone {
|
|
_confirmUmpirePhone()
|
|
} else if old == ._umpireCustomContact {
|
|
_confirmUmpireContact()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func _confirmUmpireMail() {
|
|
umpireCustomMailIsInvalid = false
|
|
if umpireCustomMail.isEmpty {
|
|
tournament.umpireCustomMail = nil
|
|
} else if umpireCustomMail.isValidEmail() {
|
|
tournament.umpireCustomMail = umpireCustomMail
|
|
} else {
|
|
umpireCustomMailIsInvalid = true
|
|
}
|
|
}
|
|
|
|
private func _deleteUmpireMail() {
|
|
umpireCustomMailIsInvalid = false
|
|
umpireCustomMail = ""
|
|
tournament.umpireCustomMail = nil
|
|
}
|
|
|
|
private func _confirmUmpirePhone() {
|
|
umpireCustomPhoneIsInvalid = false
|
|
if umpireCustomPhone.isEmpty {
|
|
tournament.umpireCustomPhone = nil
|
|
} else if umpireCustomPhone.isPhoneNumber() {
|
|
tournament.umpireCustomPhone = umpireCustomPhone.prefixMultilineTrimmed(15)
|
|
} else {
|
|
umpireCustomPhoneIsInvalid = true
|
|
}
|
|
}
|
|
|
|
private func _deleteUmpirePhone() {
|
|
umpireCustomPhoneIsInvalid = false
|
|
umpireCustomPhone = ""
|
|
tournament.umpireCustomPhone = nil
|
|
}
|
|
|
|
private func _confirmUmpireContact() {
|
|
if umpireCustomContact.isEmpty {
|
|
tournament.umpireCustomContact = nil
|
|
} else {
|
|
tournament.umpireCustomContact = umpireCustomContact.prefixMultilineTrimmed(200)
|
|
}
|
|
}
|
|
|
|
private func _deleteUmpireContact() {
|
|
umpireCustomContact = ""
|
|
tournament.umpireCustomContact = nil
|
|
}
|
|
|
|
private func _save() {
|
|
do {
|
|
try dataStore.tournaments.addOrUpdate(instance: tournament)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
|
|
private func _customUmpireView() -> some View {
|
|
Section {
|
|
VStack(alignment: .leading) {
|
|
TextField(dataStore.user.email, text: $umpireCustomMail)
|
|
.frame(maxWidth: .infinity)
|
|
.keyboardType(.emailAddress)
|
|
.autocapitalization(.none)
|
|
.focused($focusedField, equals: ._umpireCustomMail)
|
|
.onSubmit {
|
|
_confirmUmpireMail()
|
|
}
|
|
if umpireCustomMailIsInvalid {
|
|
Text("Vous n'avez pas indiqué un email valide.").foregroundStyle(.logoRed)
|
|
}
|
|
}
|
|
|
|
VStack(alignment: .leading) {
|
|
TextField(dataStore.user.phone ?? "Téléphone", text: $umpireCustomPhone)
|
|
.frame(maxWidth: .infinity)
|
|
.keyboardType(.phonePad)
|
|
.focused($focusedField, equals: ._umpireCustomPhone)
|
|
.onSubmit {
|
|
_confirmUmpirePhone()
|
|
}
|
|
if umpireCustomPhoneIsInvalid {
|
|
Text("Vous n'avez pas indiqué un téléphone valide.").foregroundStyle(.logoRed)
|
|
}
|
|
}
|
|
|
|
|
|
VStack(alignment: .leading) {
|
|
TextField(dataStore.user.fullName(), text: $umpireCustomContact)
|
|
.frame(maxWidth: .infinity)
|
|
.keyboardType(.default)
|
|
.focused($focusedField, equals: ._umpireCustomContact)
|
|
.onSubmit {
|
|
_confirmUmpireContact()
|
|
}
|
|
if dataStore.user.getSummonsMessageSignature() != nil, umpireCustomContact != dataStore.user.fullName() {
|
|
Text("Attention vous avez une signature personnalisée contenant un contact différent.").foregroundStyle(.logoRed)
|
|
|
|
FooterButtonView("retirer la personnalisation ?") {
|
|
dataStore.user.summonsMessageSignature = nil
|
|
self.dataStore.saveUser()
|
|
}
|
|
} }
|
|
|
|
} header: {
|
|
Text("Juge-arbitre")
|
|
} footer: {
|
|
Text("Ces informations seront utilisées pour vous contacter. Vous pouvez les modifier si vous souhaitez utiliser les informations de contact différentes de votre compte Padel Club.")
|
|
}
|
|
}
|
|
}
|
|
|