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.
696 lines
29 KiB
696 lines
29 KiB
//
|
|
// RegistrationSetupView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by razmig on 20/11/2024.
|
|
//
|
|
|
|
import LeStorage
|
|
import SwiftUI
|
|
import PadelClubData
|
|
|
|
struct RegistrationSetupView: View {
|
|
@Environment(\.openURL) private var openURL
|
|
@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 teamCountLimit: 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 showMoreRegistrationInfos: Bool = false
|
|
@State private var showMoreOnlineWaitingListInfos: Bool = false
|
|
@State private var showMorePaymentInfos: Bool = false
|
|
@State private var enableTimeToConfirm: Bool
|
|
@State private var isTemplate: Bool
|
|
@State private var isCorporateTournament: Bool
|
|
@State private var isValidating = false
|
|
@State private var unregisterDeltaInHours: Int
|
|
|
|
// Online Payment
|
|
@State private var enableOnlinePayment: Bool
|
|
@State private var onlinePaymentIsMandatory: Bool
|
|
@State private var enableOnlinePaymentRefund: Bool
|
|
@State private var refundDateLimit: Date
|
|
@State private var refundDateLimitEnabled: Bool
|
|
@State private var stripeAccountId: String
|
|
@State private var stripeAccountIdIsInvalid: Bool?
|
|
|
|
@State private var paymentConfig: PaymentConfig?
|
|
@State private var timeToConfirmConfig: TimeToConfirmConfig?
|
|
|
|
@FocusState private var focusedField: Tournament.CodingKeys?
|
|
|
|
@State private var hasChanges: Bool = false
|
|
|
|
@State private var stripeOnBoardingURL: URL? = nil
|
|
@State private var errorMessage: String? = nil
|
|
@State private var presentErrorAlert: Bool = false
|
|
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
init(tournament: Tournament) {
|
|
self.tournament = tournament
|
|
_enableOnlineRegistration = .init(wrappedValue: tournament.enableOnlineRegistration)
|
|
_isTemplate = .init(wrappedValue: tournament.isTemplate)
|
|
_isCorporateTournament = .init(wrappedValue: tournament.isCorporateTournament)
|
|
_unregisterDeltaInHours = .init(wrappedValue: tournament.unregisterDeltaInHours)
|
|
// 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
|
|
_teamCountLimit = .init(wrappedValue: tournament.teamCountLimit)
|
|
|
|
// 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)
|
|
|
|
// Online Payment
|
|
_enableOnlinePayment = .init(wrappedValue: tournament.enableOnlinePayment)
|
|
_onlinePaymentIsMandatory = .init(wrappedValue: tournament.onlinePaymentIsMandatory)
|
|
_enableOnlinePaymentRefund = .init(wrappedValue: tournament.enableOnlinePaymentRefund)
|
|
_stripeAccountId = .init(wrappedValue: tournament.stripeAccountId ?? "")
|
|
_enableTimeToConfirm = .init(wrappedValue: tournament.enableTimeToConfirm)
|
|
|
|
// Refund Date Limit
|
|
if let refundDateLimit = tournament.refundDateLimit {
|
|
_refundDateLimit = .init(wrappedValue: refundDateLimit)
|
|
_refundDateLimitEnabled = .init(wrappedValue: true)
|
|
} else {
|
|
_refundDateLimit = .init(wrappedValue: tournament.startDate.truncateMinutesAndSeconds())
|
|
_refundDateLimitEnabled = .init(wrappedValue: false)
|
|
}
|
|
}
|
|
|
|
func displayWarning() -> Bool {
|
|
let unsortedTeamsCount = tournament.unsortedTeamsCount()
|
|
return tournament.shouldWarnOnlineRegistrationUpdates() && targetTeamCount != tournament.teamCount && (tournament.teamCount <= unsortedTeamsCount || targetTeamCount <= unsortedTeamsCount)
|
|
}
|
|
|
|
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.showMoreRegistrationInfos = true
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if enableOnlineRegistration {
|
|
|
|
Section {
|
|
Toggle(isOn: $isTemplate) {
|
|
Text("Définir en tant que réglages par défaut")
|
|
}
|
|
} footer: {
|
|
Text("Définisser ce tournoi comme la source de vos réglages concernant l'inscription en ligne. Tous les tournois crées après celui-ci utiliseront ces réglages.")
|
|
}
|
|
|
|
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")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if dataStore.user.canEnableOnlinePayment() {
|
|
Section {
|
|
Toggle(isOn: $enableTimeToConfirm) {
|
|
Text("Confirmation obligatoire")
|
|
}
|
|
} header: {
|
|
Text("Procédure de la liste d'attente")
|
|
} footer: {
|
|
VStack(alignment: .leading) {
|
|
Text("Si activé, les équipes sortant de la liste d'attente et entrant dans le tournoi auront un temps pre-determiné pour confirmer leur changement de statut sinon l'équipe suivante de la liste sera prévenu automatiquement. Si désactivé, une équipe devra indiquer si elle n'est plus disponible pour que la liste d'attente passe à la prochaine équipe.")
|
|
FooterButtonView("En savoir plus") {
|
|
self.showMoreOnlineWaitingListInfos = true
|
|
}
|
|
}
|
|
}
|
|
.task {
|
|
do {
|
|
self.timeToConfirmConfig = try await ConfigurationService.fetchTournamentConfig()
|
|
} catch {
|
|
print("Error fetching timeToConfirmConfig: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
Section {
|
|
Text("Par défaut, sans date définie, les inscriptions en ligne sont possible dès son activation.")
|
|
|
|
Toggle(isOn: $openingRegistrationDateEnabled) {
|
|
Text("Définir une date ultérieur")
|
|
}
|
|
|
|
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 {
|
|
LabeledContent {
|
|
StepperView(count: $unregisterDeltaInHours)
|
|
} label: {
|
|
Text("\(unregisterDeltaInHours)h avant")
|
|
}
|
|
} header: {
|
|
Text("Limite de désinscription")
|
|
} footer: {
|
|
Text("Empêche la désinscription plusieurs heures avant le début du tournoi")
|
|
}
|
|
|
|
Section {
|
|
if displayWarning() {
|
|
Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.")
|
|
.foregroundStyle(.logoRed)
|
|
}
|
|
|
|
|
|
Toggle(isOn: $teamCountLimit) {
|
|
Text("Activer une limite")
|
|
}
|
|
|
|
if teamCountLimit {
|
|
StepperView(count: $targetTeamCount, minimum: 4)
|
|
}
|
|
} header: {
|
|
Text("Paires admises")
|
|
} footer: {
|
|
Text("Les inscriptions seront indiquées 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 dataStore.user.canEnableOnlinePayment() {
|
|
_onlinePaymentsView()
|
|
}
|
|
|
|
if tournament.isAnimation() {
|
|
Section {
|
|
Toggle(isOn: $userAccountIsRequired) {
|
|
Text("Compte Padel Club requis pour s'inscrire")
|
|
}
|
|
|
|
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: $showMoreRegistrationInfos) {
|
|
RegistrationInfoSheetView()
|
|
}
|
|
.sheet(isPresented: $showMoreOnlineWaitingListInfos) {
|
|
OnlineWaitingListFaqSheetView(timeToConfirmConfig: timeToConfirmConfig ?? TimeToConfirmConfig.defaultConfig)
|
|
}
|
|
.sheet(isPresented: $showMorePaymentInfos) {
|
|
PaymentInfoSheetView(paymentConfig: paymentConfig ?? PaymentConfig.defaultConfig)
|
|
}
|
|
|
|
.toolbar(content: {
|
|
if hasChanges {
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
Button("Annuler", role: .cancel) {
|
|
dismiss()
|
|
}
|
|
}
|
|
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
ButtonValidateView(role: .destructive) {
|
|
_save()
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.toolbar {
|
|
if focusedField == ._stripeAccountId, stripeAccountId.isEmpty == false {
|
|
ToolbarItemGroup(placement: .keyboard) {
|
|
Button("Effacer") {
|
|
stripeAccountId = ""
|
|
stripeAccountIdIsInvalid = nil
|
|
tournament.stripeAccountId = nil
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
Spacer()
|
|
Button("Valider") {
|
|
focusedField = nil
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
}
|
|
}
|
|
}
|
|
.alert("Paiement en ligne", isPresented: $presentErrorAlert, actions: {
|
|
Button("Fermer") {
|
|
self.presentErrorAlert = false
|
|
}
|
|
}, message: {
|
|
Text(ValidationError.onlinePaymentNotEnabled.localizedDescription)
|
|
})
|
|
.headerProminence(.increased)
|
|
.navigationTitle("Inscription en ligne")
|
|
.ifAvailableiOS26 {
|
|
if #available(iOS 26.0, *) {
|
|
$0.navigationSubtitle(tournament.tournamentTitle())
|
|
}
|
|
}
|
|
.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: teamCountLimit) {
|
|
_hasChanged()
|
|
}
|
|
|
|
.onChange(of: targetTeamCount) {
|
|
_hasChanged()
|
|
}
|
|
|
|
.onChange(of: waitingListLimitEnabled) {
|
|
_hasChanged()
|
|
}
|
|
|
|
.onChange(of: waitingListLimit) {
|
|
_hasChanged()
|
|
}
|
|
|
|
.onChange(of: [minPlayerPerTeam, maxPlayerPerTeam]) {
|
|
_hasChanged()
|
|
}
|
|
.onChange(of: [isTemplate, userAccountIsRequired, licenseIsRequired, enableTimeToConfirm, isCorporateTournament]) {
|
|
_hasChanged()
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _onlinePaymentsView() -> some View {
|
|
|
|
let entryFee = tournament.entryFee ?? 20
|
|
|
|
Section {
|
|
Toggle(isOn: $enableOnlinePayment) {
|
|
Text("Activer le paiement en ligne")
|
|
Text("Cette fonction peut entraîner un coût supplémentaire.")
|
|
.foregroundStyle(.logoRed)
|
|
.bold()
|
|
}
|
|
|
|
if enableOnlinePayment {
|
|
|
|
Toggle(isOn: $onlinePaymentIsMandatory) {
|
|
Text("Paiement obligatoire")
|
|
}
|
|
}
|
|
|
|
Toggle(isOn: $enableOnlinePaymentRefund) {
|
|
Text("Autoriser les remboursements en ligne")
|
|
}
|
|
|
|
if enableOnlinePaymentRefund {
|
|
Toggle(isOn: $refundDateLimitEnabled) {
|
|
Text("Définir une date limite")
|
|
}
|
|
|
|
if refundDateLimitEnabled {
|
|
DatePicker(selection: $refundDateLimit) {
|
|
DateMenuView(date: $refundDateLimit)
|
|
}
|
|
}
|
|
}
|
|
|
|
if dataStore.user.registrationPaymentMode == .corporate {
|
|
Toggle(isOn: $isCorporateTournament) {
|
|
Text("Revenu Padel Club")
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Paiement en ligne")
|
|
} footer: {
|
|
VStack(alignment: .leading) {
|
|
Text("Permettez aux joueurs de payer leur inscription en ligne. Vous devez connecter un compte Stripe pour recevoir les paiements.")
|
|
|
|
FooterButtonView("En savoir plus") {
|
|
self.showMorePaymentInfos = true
|
|
}
|
|
}
|
|
}
|
|
.task {
|
|
do {
|
|
self.paymentConfig = try await ConfigurationService.fetchPaymentConfig()
|
|
} catch {
|
|
print("Error fetching paymentConfig: \(error)")
|
|
}
|
|
}
|
|
.onChange(of: [enableOnlinePayment, onlinePaymentIsMandatory, enableOnlinePaymentRefund]) {
|
|
_hasChanged()
|
|
}
|
|
.onChange(of: refundDateLimitEnabled) {
|
|
_hasChanged()
|
|
}
|
|
.onChange(of: refundDateLimit) {
|
|
_hasChanged()
|
|
}
|
|
|
|
if isCorporateTournament == false, dataStore.user.registrationPaymentMode.requiresStripe() {
|
|
Section {
|
|
LabeledContent {
|
|
if isValidating {
|
|
ProgressView()
|
|
} else if focusedField == nil, stripeAccountIdIsInvalid == false, stripeAccountId.isEmpty == false, isValidating == false {
|
|
Image(systemName: "checkmark.circle.fill").foregroundStyle(.green)
|
|
}
|
|
} label: {
|
|
TextField("Identifiant du compte Stripe", text: $stripeAccountId)
|
|
.frame(maxWidth: .infinity)
|
|
.focused($focusedField, equals: ._stripeAccountId)
|
|
.disabled(isValidating)
|
|
.keyboardType(.alphabet)
|
|
.textContentType(nil)
|
|
.autocorrectionDisabled()
|
|
}
|
|
.onChange(of: focusedField) { old, new in
|
|
if old == ._stripeAccountId {
|
|
_confirmStripeAccountId()
|
|
}
|
|
}
|
|
|
|
if stripeAccountIdIsInvalid == true {
|
|
Text("Identifiant Stripe invalide. Vous ne pouvez pas activer le paiement en ligne.").foregroundStyle(.logoRed)
|
|
}
|
|
|
|
if stripeAccountId.isEmpty == false {
|
|
Button("Vérifier le compte Stripe") {
|
|
_confirmStripeAccountId()
|
|
}
|
|
.disabled(isValidating)
|
|
}
|
|
|
|
if let errorMessage {
|
|
Text(errorMessage).foregroundStyle(.logoRed)
|
|
}
|
|
|
|
RowButtonView("Connecter ou créer un compte Stripe", role: .destructive) {
|
|
errorMessage = nil
|
|
stripeAccountIdIsInvalid = nil
|
|
stripeAccountId = ""
|
|
stripeOnBoardingURL = nil
|
|
do {
|
|
let createStripeAccountResponse = try await StripeValidationService.createStripeConnectAccount()
|
|
print("createStripeAccountResponse", createStripeAccountResponse)
|
|
|
|
guard let accounId = createStripeAccountResponse.accountId else {
|
|
throw ValidationError.accountNotFound
|
|
}
|
|
|
|
let createStripeAccountLinkResponse = try await StripeValidationService.createStripeAccountLink(accounId)
|
|
print("createStripeAccountLinkResponse", createStripeAccountLinkResponse)
|
|
stripeOnBoardingURL = createStripeAccountLinkResponse.url
|
|
stripeAccountIdIsInvalid = nil
|
|
stripeAccountId = accounId
|
|
|
|
if let stripeOnBoardingURL {
|
|
openURL(stripeOnBoardingURL)
|
|
} else {
|
|
throw ValidationError.urlNotFound
|
|
}
|
|
|
|
} catch {
|
|
self.errorMessage = error.localizedDescription
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Compte Stripe")
|
|
} footer: {
|
|
Text("Vous devez connecter un compte Stripe à Padel Club. En cliquant sur le bouton ci-dessus, vous serez dirigé vers Stripe pour choisir votre compte Stripe à connecter ou pour en créer un.")
|
|
}
|
|
|
|
Section {
|
|
let fixedFee = RegistrationPaymentMode.stripeFixedFee // Fixed fee in euros
|
|
let percentageFee = RegistrationPaymentMode.stripePercentageFee
|
|
let totalStripeFee = fixedFee + (entryFee * percentageFee)
|
|
|
|
LabeledContent {
|
|
Text("\(fixedFee, format: .currency(code: "EUR")) + \(percentageFee, format: .percent)")
|
|
} label: {
|
|
Text("Commission Stripe")
|
|
}
|
|
Text("Soit \(totalStripeFee, format: .currency(code: "EUR")) pour \(entryFee, format: .currency(code: "EUR")).")
|
|
}
|
|
}
|
|
|
|
Section {
|
|
if isCorporateTournament == false, dataStore.user.registrationPaymentMode.requiresStripe(), dataStore.user.registrationPaymentMode.hasPadelClubFee() {
|
|
|
|
let padelClubFee = paymentConfig?.stripeFee ?? PaymentConfig.defaultConfig.stripeFee
|
|
let feeAmount = entryFee * padelClubFee
|
|
|
|
LabeledContent {
|
|
Text(padelClubFee, format: .percent)
|
|
} label: {
|
|
Text("Commission Padel Club")
|
|
}
|
|
|
|
Text("Soit \(feeAmount, format: .currency(code: "EUR")) pour \(entryFee, format: .currency(code: "EUR")).")
|
|
// } else {
|
|
// Text("Aucune commission Padel Club ne sera prélevée.").foregroundStyle(.logoRed).bold()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func _confirmStripeAccountId() {
|
|
stripeAccountIdIsInvalid = nil
|
|
if stripeAccountId.isEmpty {
|
|
tournament.stripeAccountId = nil
|
|
} else if stripeAccountId.count >= 5, stripeAccountId.starts(with: "acct_") {
|
|
_checkStripeAccount(stripeAccountId.prefixMultilineTrimmed(255))
|
|
} else {
|
|
stripeAccountIdIsInvalid = true
|
|
}
|
|
}
|
|
|
|
private func _checkStripeAccount(_ accId: String) {
|
|
Task {
|
|
isValidating = true
|
|
do {
|
|
let response = try await StripeValidationService.validateStripeAccount(accountId: accId)
|
|
print("validateStripeAccount", response)
|
|
stripeAccountId = accId
|
|
stripeAccountIdIsInvalid = response.canProcessPayments == false
|
|
} catch {
|
|
stripeAccountIdIsInvalid = true
|
|
}
|
|
isValidating = false
|
|
}
|
|
}
|
|
|
|
private func _hasChanged() {
|
|
hasChanges = true
|
|
}
|
|
|
|
private func _save() {
|
|
hasChanges = false
|
|
|
|
tournament.enableOnlineRegistration = enableOnlineRegistration
|
|
tournament.isTemplate = isTemplate
|
|
tournament.isCorporateTournament = isCorporateTournament
|
|
tournament.unregisterDeltaInHours = unregisterDeltaInHours
|
|
|
|
var shouldDismiss = true
|
|
if enableOnlineRegistration {
|
|
tournament.accountIsRequired = userAccountIsRequired
|
|
tournament.licenseIsRequired = licenseIsRequired
|
|
tournament.minimumPlayerPerTeam = minPlayerPerTeam
|
|
tournament.maximumPlayerPerTeam = maxPlayerPerTeam
|
|
|
|
// Online Payment
|
|
tournament.enableOnlinePayment = enableOnlinePayment
|
|
tournament.onlinePaymentIsMandatory = onlinePaymentIsMandatory
|
|
tournament.enableOnlinePaymentRefund = enableOnlinePaymentRefund
|
|
|
|
if refundDateLimitEnabled == false {
|
|
tournament.refundDateLimit = nil
|
|
} else {
|
|
tournament.refundDateLimit = refundDateLimit
|
|
}
|
|
|
|
tournament.enableTimeToConfirm = enableTimeToConfirm
|
|
if stripeAccountIdIsInvalid == false {
|
|
tournament.stripeAccountId = stripeAccountId
|
|
} else {
|
|
tournament.stripeAccountId = nil
|
|
|
|
if enableOnlinePayment, isCorporateTournament == false, dataStore.user.registrationPaymentMode.requiresStripe() {
|
|
enableOnlinePayment = false
|
|
tournament.enableOnlinePayment = false
|
|
shouldDismiss = false
|
|
}
|
|
}
|
|
} else {
|
|
tournament.accountIsRequired = true
|
|
tournament.licenseIsRequired = true
|
|
tournament.minimumPlayerPerTeam = 2
|
|
tournament.maximumPlayerPerTeam = 2
|
|
tournament.enableTimeToConfirm = false
|
|
// When online registration is disabled, also disable online payment
|
|
tournament.enableOnlinePayment = false
|
|
tournament.onlinePaymentIsMandatory = false
|
|
tournament.enableOnlinePaymentRefund = false
|
|
tournament.refundDateLimit = nil
|
|
tournament.stripeAccountId = nil
|
|
}
|
|
|
|
if openingRegistrationDateEnabled == false {
|
|
tournament.openingRegistrationDate = nil
|
|
} else {
|
|
tournament.openingRegistrationDate = openingRegistrationDate
|
|
}
|
|
|
|
if registrationDateLimitEnabled == false {
|
|
tournament.registrationDateLimit = nil
|
|
} else {
|
|
tournament.registrationDateLimit = registrationDateLimit
|
|
}
|
|
|
|
tournament.teamCountLimit = teamCountLimit
|
|
tournament.teamCount = targetTeamCount
|
|
|
|
if waitingListLimitEnabled == false {
|
|
tournament.waitingListLimit = nil
|
|
} else {
|
|
tournament.waitingListLimit = waitingListLimit
|
|
}
|
|
|
|
self.dataStore.tournaments.addOrUpdate(instance: tournament)
|
|
if shouldDismiss {
|
|
dismiss()
|
|
} else {
|
|
presentErrorAlert = true
|
|
}
|
|
}
|
|
}
|
|
|
|
|