diff --git a/PadelClub/Views/Calling/CallView.swift b/PadelClub/Views/Calling/CallView.swift index c6ccc2d..3cc8fc4 100644 --- a/PadelClub/Views/Calling/CallView.swift +++ b/PadelClub/Views/Calling/CallView.swift @@ -59,7 +59,7 @@ struct CallView: View { @State private var contactType: ContactType? = nil @State private var sentError: ContactManagerError? = nil - @State var cannotPayForTournament: Bool = false + @State var showSubscriptionView: Bool = false var messageSentFailed: Binding { Binding { @@ -101,22 +101,23 @@ struct CallView: View { Text(callWord + " ces \(teams.count) paires par") } Button { - contactType = .message(date: callDate, recipients: teams.flatMap { $0.getPhoneNumbers() }, body: finalMessage, tournamentBuild: nil) + self._payTournamentAndExecute { + self._contactByMessage() + } } label: { Text("sms") .underline() } Text("ou") Button { - contactType = .mail(date: callDate, recipients: tournament.umpireMail(), bccRecipients: teams.flatMap { $0.getMail() }, body: finalMessage, subject: tournament.tournamentTitle(), tournamentBuild: nil) + self._payTournamentAndExecute { + self._contactByMail() + } } label: { Text("mail") .underline() } } - .onAppear { - self.cannotPayForTournament = Guard.main.paymentForNewTournament() == nil - } .font(.subheadline) .buttonStyle(.borderless) .alert("Un problème est survenu", isPresented: messageSentFailed) { @@ -130,7 +131,6 @@ struct CallView: View { Group { switch contactType { case .message(_, let recipients, let body, _): - if !self.cannotPayForTournament { MessageComposeView(recipients: recipients, body: body) { result in switch result { case .cancelled: @@ -146,36 +146,52 @@ struct CallView: View { @unknown default: break } - } - } else { - SubscriptionView(isPresented: self.$cannotPayForTournament, showLackOfPlanMessage: true) - } + } case .mail(_, let recipients, let bccRecipients, let body, let subject, _): - if !self.cannotPayForTournament { - MailComposeView(recipients: recipients, bccRecipients: bccRecipients, body: body, subject: subject) { result in - switch result { - case .cancelled, .saved: + MailComposeView(recipients: recipients, bccRecipients: bccRecipients, body: body, subject: subject) { result in + switch result { + case .cancelled, .saved: + self.contactType = nil + case .failed: + self.contactType = nil + self.sentError = .mailFailed + case .sent: + if networkMonitor.connected == false { self.contactType = nil - case .failed: - self.contactType = nil - self.sentError = .mailFailed - case .sent: - if networkMonitor.connected == false { - self.contactType = nil - self.sentError = .mailNotSent - } else { - _called(true) - } - @unknown default: - break + self.sentError = .mailNotSent + } else { + _called(true) } + @unknown default: + break } - } else { - SubscriptionView(isPresented: self.$cannotPayForTournament, showLackOfPlanMessage: true) } } } .tint(.master) } + .sheet(isPresented: self.$showSubscriptionView, content: { + NavigationStack { + SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true) + } + }) } + + fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { + do { + try tournament.payIfNecessary() + handler() + } catch { + self.showSubscriptionView = true + } + } + + fileprivate func _contactByMessage() { + contactType = .message(date: callDate, recipients: teams.flatMap { $0.getPhoneNumbers() }, body: finalMessage, tournamentBuild: nil) + } + + fileprivate func _contactByMail() { + contactType = .mail(date: callDate, recipients: tournament.umpireMail(), bccRecipients: teams.flatMap { $0.getMail() }, body: finalMessage, subject: tournament.tournamentTitle(), tournamentBuild: nil) + } + } diff --git a/PadelClub/Views/Calling/SendToAllView.swift b/PadelClub/Views/Calling/SendToAllView.swift index cf7d8a8..38f1704 100644 --- a/PadelClub/Views/Calling/SendToAllView.swift +++ b/PadelClub/Views/Calling/SendToAllView.swift @@ -71,11 +71,7 @@ struct SendToAllView: View { Section { RowButtonView("Contacter \(_totalString())") { - if contactMethod == 0 { - contactType = .message(date: nil, recipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.phoneNumber }, body: addLink ? tournament.shareURL()?.absoluteString : nil, tournamentBuild: nil) - } else { - contactType = .mail(date: nil, recipients: tournament.umpireMail(), bccRecipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.email }, body: addLink ? tournament.shareURL()?.absoluteString : nil, subject: tournament.tournamentTitle(), tournamentBuild: nil) - } + self._contactAndPay() } } } @@ -166,6 +162,24 @@ struct SendToAllView: View { return teams.count.formatted() + " équipe" + teams.count.pluralSuffix } } + + fileprivate func _contactAndPay() { + do { + try tournament.payIfNecessary() + self._contact() + } catch { + self.cannotPayForTournament = true + } + } + + fileprivate func _contact() { + if contactMethod == 0 { + contactType = .message(date: nil, recipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.phoneNumber }, body: addLink ? tournament.shareURL()?.absoluteString : nil, tournamentBuild: nil) + } else { + contactType = .mail(date: nil, recipients: tournament.umpireMail(), bccRecipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.email }, body: addLink ? tournament.shareURL()?.absoluteString : nil, subject: tournament.tournamentTitle(), tournamentBuild: nil) + } + } + } #Preview { diff --git a/PadelClub/Views/Match/MatchDetailView.swift b/PadelClub/Views/Match/MatchDetailView.swift index 3ed5934..36d2a7e 100644 --- a/PadelClub/Views/Match/MatchDetailView.swift +++ b/PadelClub/Views/Match/MatchDetailView.swift @@ -254,7 +254,9 @@ struct MatchDetailView: View { } } } else { - SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true) + NavigationStack { + SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true) + } } case .mail(_, let recipients, let bccRecipients, let body, let subject, _): if Guard.main.paymentForNewTournament() != nil { @@ -275,7 +277,9 @@ struct MatchDetailView: View { } } } else { - SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true) + NavigationStack { + SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true) + } } } } diff --git a/PadelClub/Views/Subscription/Guard.swift b/PadelClub/Views/Subscription/Guard.swift index 8228dd3..92d8fd1 100644 --- a/PadelClub/Views/Subscription/Guard.swift +++ b/PadelClub/Views/Subscription/Guard.swift @@ -163,7 +163,7 @@ import LeStorage let userTransactions = self.purchasedTransactions.filter { currentUserUUID == $0.appAccountToken } - let now = Date() + let now: Date = Date() // print("now = \(now)") return userTransactions.filter { transaction in if let expirationDate = transaction.expirationDate { diff --git a/PadelClub/Views/Subscription/SubscriptionView.swift b/PadelClub/Views/Subscription/SubscriptionView.swift index 8d02c60..823ad3b 100644 --- a/PadelClub/Views/Subscription/SubscriptionView.swift +++ b/PadelClub/Views/Subscription/SubscriptionView.swift @@ -52,6 +52,10 @@ class SubscriptionModel: ObservableObject, StoreDelegate { @Published var products: [Product] = [] @Published var totalPrice: String = "" + init() { + Logger.log("SubscriptionModel init ") + } + func load() { self.isLoading = true if self.storeManager == nil { @@ -116,27 +120,32 @@ struct SubscriptionView: View { @State var isPurchasing: Bool = false @State var showSuccessfulPurchaseView: Bool = false + init(isPresented: Binding, showLackOfPlanMessage: Bool = false) { + self._isPresented = isPresented + self.showLackOfPlanMessage = showLackOfPlanMessage + + Logger.log(">>> SubscriptionView init") + + } + var body: some View { - Group { + VStack { if self.showLoginView { LoginView { _ in self.showLoginView = false self._purchase() } } else { - + + if self.showLackOfPlanMessage { + SubscriptionDetailView() + .clipShape(.rect(cornerRadius: 16.0)) + .padding() + } + List { - if self.showLackOfPlanMessage { - HStack { - Image(systemName: "exclamationmark.bubble.fill").foregroundStyle(Color.accentColor) - .font(.title) - Text("Vous ne disposez malheureusement plus d'offre pour continuer votre tournoi. Voici ce que nous proposons:") - .fontWeight(.semibold) - } - } - if self.model.products.count > 0 { Section { @@ -198,6 +207,20 @@ struct SubscriptionView: View { } } + } else { + if self.model.isLoading { + ProgressView() + } else { + HStack { + if let plan = Guard.main.currentPlan { + Image(systemName: plan.systemImage) + } else { + Image(systemName: "questionmark.diamond.fill") + } + Text("Il n'y a pas de produits à vous proposer") + } + } + } } .listStyle(.grouped) @@ -344,6 +367,27 @@ struct SubscriptionFooterView: View { } } +struct SubscriptionDetailView: View { + + var body: some View { + HStack { + Image(systemName: "exclamationmark.bubble.fill") + //.foregroundStyle(Color.accentColor) + .font(.title) + Text("Vous ne disposez malheureusement plus d'offre pour continuer votre tournoi. Voici ce que nous proposons:") + .fontWeight(.semibold) + } + .padding() + .background(.orange) + .foregroundStyle(.black) + } + +} + +#Preview { + SubscriptionDetailView() +} + #Preview { NavigationStack { SubscriptionView(isPresented: .constant(true), showLackOfPlanMessage: false) diff --git a/PadelClub/Views/User/UserCreationView.swift b/PadelClub/Views/User/UserCreationView.swift index 7a5d3c0..7135355 100644 --- a/PadelClub/Views/User/UserCreationView.swift +++ b/PadelClub/Views/User/UserCreationView.swift @@ -25,6 +25,7 @@ struct UserCreationFormView: View { @State var alertMessage: String = "" { didSet { self.showAlertView = true + self.isLoading = false } } @@ -97,7 +98,6 @@ struct UserCreationFormView: View { } ) } - fileprivate func _selectCountry() { guard let regionCode = Locale.current.region?.identifier, let country = Locale.current.localizedString(forRegionCode: regionCode) else { return @@ -107,7 +107,9 @@ struct UserCreationFormView: View { } fileprivate func _create() { - + + self.isLoading = true + guard self.password1 == self.password2 else { self.alertMessage = "Les mots de passe ne correspondent pas" return @@ -133,8 +135,6 @@ struct UserCreationFormView: View { return } - self.isLoading = true - Task { do { let userCreationForm = UserCreationForm(