Laurent 1 year ago
commit 7f3c190e3f
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 35
      PadelClub/Utils/ContactManager.swift
  3. 2
      PadelClub/Utils/Network/NetworkFederalService.swift
  4. 3
      PadelClub/Utils/PadelRule.swift
  5. 19
      PadelClub/Utils/SourceFileManager.swift
  6. 5
      PadelClub/ViewModel/SearchViewModel.swift
  7. 58
      PadelClub/Views/Calling/CallView.swift
  8. 4
      PadelClub/Views/Calling/Components/PlayersWithoutContactView.swift
  9. 8
      PadelClub/Views/Calling/GroupStageCallingView.swift
  10. 12
      PadelClub/Views/Calling/SeedsCallingView.swift
  11. 50
      PadelClub/Views/Calling/SendToAllView.swift
  12. 31
      PadelClub/Views/Calling/TeamsCallingView.swift
  13. 37
      PadelClub/Views/GroupStage/Components/GroupStageTeamView.swift
  14. 42
      PadelClub/Views/Match/MatchDetailView.swift
  15. 2
      PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift
  16. 46
      PadelClub/Views/Navigation/Agenda/TournamentSubscriptionView.swift
  17. 21
      PadelClub/Views/Shared/SelectablePlayerListView.swift
  18. 17
      PadelClub/Views/Shared/SupportButtonView.swift
  19. 2
      PadelClub/Views/Shared/TournamentFilterView.swift
  20. 42
      PadelClub/Views/Team/EditingTeamView.swift
  21. 89
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  22. 2
      PadelClub/Views/Tournament/Screen/TournamentCallView.swift

@ -3155,7 +3155,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.10; MARKETING_VERSION = 1.0.12;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3198,7 +3198,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.10; MARKETING_VERSION = 1.0.12;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

@ -18,6 +18,41 @@ enum ContactManagerError: LocalizedError {
case calendarAccessDenied case calendarAccessDenied
case calendarEventSaveFailed case calendarEventSaveFailed
case noCalendarAvailable case noCalendarAvailable
case uncalledTeams([TeamRegistration])
var localizedDescription: String {
switch self {
case .mailFailed:
return "Le mail n'a pas été envoyé"
case .mailNotSent:
return "Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer."
case .messageFailed:
return "Le SMS n'a pas été envoyé"
case .messageNotSent:
return "Le SMS n'a pas été envoyé"
case .uncalledTeams(let array):
let verb = array.count > 1 ? "peuvent" : "peut"
return "Attention, \(array.count) équipe\(array.count.pluralSuffix) ne \(verb) pas être contacté par la méthode choisie"
case .calendarAccessDenied:
return "Padel Club n'a pas accès à votre calendrier"
case .calendarEventSaveFailed:
return "Padel Club n'a pas réussi à sauver ce tournoi dans votre calendrier"
case .noCalendarAvailable:
return "Padel Club n'a pas réussi à trouver un calendrier pour y inscrire ce tournoi"
}
}
static func getNetworkErrorMessage(sentError: ContactManagerError?, networkMonitorConnected: Bool) -> String {
var errors: [String] = []
if networkMonitorConnected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if let sentError {
errors.append(sentError.localizedDescription)
}
return errors.joined(separator: "\n")
}
} }
enum ContactType: Identifiable { enum ContactType: Identifiable {

@ -206,7 +206,7 @@ recherche_type=club&club[autocomplete][value_container][value_field]=\(codeClub.
var levelsParameter = "" var levelsParameter = ""
if levels.isEmpty == false { if levels.isEmpty == false {
levelsParameter = levels.map { "categorie_tournoi[\($0.localizedLabel)]=\($0.localizedLabel)" }.joined(separator: "&") + "&" levelsParameter = levels.map { "categorie_tournoi[\($0.searchRawValue())]=\($0.searchRawValue())" }.joined(separator: "&") + "&"
} }
var categoriesParameter = "" var categoriesParameter = ""

@ -293,6 +293,9 @@ enum TournamentLevel: Int, Hashable, Codable, CaseIterable, Identifiable {
self.init(rawValue: value) self.init(rawValue: value)
} }
func searchRawValue() -> String {
String(describing: self)
}
func pointsRange(first: Int, last: Int, teamsCount: Int) -> String { func pointsRange(first: Int, last: Int, teamsCount: Int) -> String {
let range = [points(for: first - 1, count: teamsCount), let range = [points(for: first - 1, count: teamsCount),

@ -227,23 +227,8 @@ class SourceFileManager {
} }
static func getSortOption() -> [SortOption] { static func getSortOption() -> [SortOption] {
if canFilterByAge() { return SortOption.allCases
return SortOption.allCases }
} else {
return [.name, .rank, .tournamentCount, .points]
}
}
static func canFilterByAge() -> Bool {
let currentMonthData = DataStore.shared.monthData.first(where: { data in
data.monthKey == DataStore.shared.appSettings.lastDataSource
})
let currentModelVersion = PersistenceController.getModelVersion()
if let currentMonthData, currentMonthData.fileModelIdentifier == currentModelVersion, currentModelVersion != nil {
return true
}
return false
}
} }
enum SourceFile: String, CaseIterable { enum SourceFile: String, CaseIterable {

@ -525,10 +525,7 @@ enum DataSet: Int, Identifiable {
_tokens = [.rankMoreThan, .rankLessThan, .rankBetween] _tokens = [.rankMoreThan, .rankLessThan, .rankBetween]
} }
if SourceFileManager.canFilterByAge() { _tokens.append(.age)
_tokens.append(.age)
}
return _tokens return _tokens
} }
} }

@ -81,13 +81,13 @@ struct CallView: View {
} }
} }
private func _called(_ success: Bool) { private func _called(_ calledTeams: [TeamRegistration], _ success: Bool) {
if success { if success {
self.teams.forEach { team in calledTeams.forEach { team in
team.callDate = callDate team.callDate = callDate
} }
do { do {
try self.tournamentStore.teamRegistrations.addOrUpdate(contentOfs: teams) try self.tournamentStore.teamRegistrations.addOrUpdate(contentOfs: calledTeams)
} catch { } catch {
Logger.error(error) Logger.error(error)
} }
@ -124,6 +124,14 @@ struct CallView: View {
.alert("Un problème est survenu", isPresented: messageSentFailed) { .alert("Un problème est survenu", isPresented: messageSentFailed) {
Button("OK") { Button("OK") {
} }
if case .uncalledTeams(let uncalledTeams) = sentError {
NavigationLink("Voir les équipes non contactées") {
TeamsCallingView(teams: uncalledTeams)
.environment(tournament)
}
}
} message: { } message: {
Text(_networkErrorMessage) Text(_networkErrorMessage)
} }
@ -138,10 +146,20 @@ struct CallView: View {
case .failed: case .failed:
self.sentError = .messageFailed self.sentError = .messageFailed
case .sent: case .sent:
let calledTeams = teams.filter { $0.getPhoneNumbers().isEmpty == false }
let uncalledTeams = teams.filter { $0.getPhoneNumbers().isEmpty }
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.sentError = .messageNotSent if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .messageNotSent
}
} else { } else {
self._called(true) if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
}
self._called(calledTeams, true)
} }
@unknown default: @unknown default:
break break
@ -156,11 +174,21 @@ struct CallView: View {
self.contactType = nil self.contactType = nil
self.sentError = .mailFailed self.sentError = .mailFailed
case .sent: case .sent:
let calledTeams = teams.filter { $0.getMail().isEmpty == false }
let uncalledTeams = teams.filter { $0.getMail().isEmpty }
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.contactType = nil self.contactType = nil
self.sentError = .mailNotSent if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .mailNotSent
}
} else { } else {
self._called(true) if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
}
self._called(calledTeams, true)
} }
@unknown default: @unknown default:
break break
@ -260,21 +288,7 @@ struct CallView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
} }
} }

@ -13,7 +13,7 @@ struct PlayersWithoutContactView: View {
var body: some View { var body: some View {
Section { Section {
let withoutEmails = players.filter({ $0.email?.isEmpty == true }) let withoutEmails = players.filter({ $0.email?.isEmpty == true || $0.email == nil })
DisclosureGroup { DisclosureGroup {
ForEach(withoutEmails) { player in ForEach(withoutEmails) { player in
NavigationLink { NavigationLink {
@ -31,7 +31,7 @@ struct PlayersWithoutContactView: View {
} }
} }
let withoutPhones = players.filter({ $0.phoneNumber?.isEmpty == true }) let withoutPhones = players.filter({ $0.phoneNumber?.isEmpty == true || $0.phoneNumber == nil })
DisclosureGroup { DisclosureGroup {
ForEach(withoutPhones) { player in ForEach(withoutPhones) { player in
NavigationLink { NavigationLink {

@ -14,6 +14,14 @@ struct GroupStageCallingView: View {
var body: some View { var body: some View {
let groupStages = tournament.groupStages() let groupStages = tournament.groupStages()
List { List {
NavigationLink {
TeamsCallingView(teams: groupStages.flatMap({ $0.unsortedTeams() }).filter({ $0.callDate == nil }))
.environment(tournament)
} label: {
LabeledContent("Équipes non contactées", value: groupStages.flatMap({ $0.unsortedTeams() }).filter({ $0.callDate == nil }).count.formatted())
}
PlayersWithoutContactView(players: groupStages.flatMap({ $0.unsortedTeams() }).flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank)) PlayersWithoutContactView(players: groupStages.flatMap({ $0.unsortedTeams() }).flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank))
_sameTimeGroupStageView(groupStages: groupStages) _sameTimeGroupStageView(groupStages: groupStages)

@ -14,6 +14,14 @@ struct SeedsCallingView: View {
var body: some View { var body: some View {
List { List {
let tournamentRounds = tournament.rounds() let tournamentRounds = tournament.rounds()
NavigationLink {
TeamsCallingView(teams: tournament.seededTeams().filter({ $0.callDate == nil }))
.environment(tournament)
} label: {
LabeledContent("Équipes non contactées", value: tournament.seededTeams().filter({ $0.callDate == nil }).count.formatted())
}
PlayersWithoutContactView(players: tournament.seededTeams().flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank)) PlayersWithoutContactView(players: tournament.seededTeams().flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank))
ForEach(tournamentRounds) { round in ForEach(tournamentRounds) { round in
@ -55,6 +63,10 @@ struct SeedsCallingView: View {
} }
} }
NavigationLink("Équipes non contactées") {
TeamsCallingView(teams: round.teams().filter({ $0.callDate == nil }))
}
if displayByMatch == false { if displayByMatch == false {
ForEach(keys, id: \.self) { time in ForEach(keys, id: \.self) { time in

@ -121,6 +121,13 @@ struct SendToAllView: View {
.alert("Un problème est survenu", isPresented: messageSentFailed) { .alert("Un problème est survenu", isPresented: messageSentFailed) {
Button("OK") { Button("OK") {
} }
if case .uncalledTeams(let uncalledTeams) = sentError {
NavigationLink("Voir les équipes non contactées") {
TeamsCallingView(teams: uncalledTeams)
.environment(tournament)
}
}
} message: { } message: {
Text(_networkErrorMessage) Text(_networkErrorMessage)
} }
@ -135,9 +142,21 @@ struct SendToAllView: View {
case .failed: case .failed:
self.sentError = .messageFailed self.sentError = .messageFailed
case .sent: case .sent:
let uncalledTeams = _teams().filter { $0.getPhoneNumbers().isEmpty }
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.sentError = .messageNotSent self.contactType = nil
if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .messageNotSent
}
} else {
if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
}
} }
@unknown default: @unknown default:
break break
} }
@ -151,9 +170,19 @@ struct SendToAllView: View {
self.contactType = nil self.contactType = nil
self.sentError = .mailFailed self.sentError = .mailFailed
case .sent: case .sent:
let uncalledTeams = _teams().filter { $0.getMail().isEmpty }
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.contactType = nil self.contactType = nil
self.sentError = .mailNotSent if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .mailNotSent
}
} else {
if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
}
} }
@unknown default: @unknown default:
break break
@ -254,23 +283,8 @@ struct SendToAllView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
} }
} }
//#Preview { //#Preview {

@ -10,10 +10,10 @@ import LeStorage
struct TeamsCallingView: View { struct TeamsCallingView: View {
@Environment(Tournament.self) var tournament: Tournament @Environment(Tournament.self) var tournament: Tournament
let teams : [TeamRegistration]
var body: some View { var body: some View {
List { List {
let teams = tournament.selectedSortedTeams()
Section { Section {
ForEach(teams) { team in ForEach(teams) { team in
Menu { Menu {
@ -21,13 +21,11 @@ struct TeamsCallingView: View {
} label: { } label: {
HStack { HStack {
TeamRowView(team: team, displayCallDate: true) TeamRowView(team: team, displayCallDate: true)
if team.called() { Spacer()
Spacer() Menu {
Menu { _menuOptions(team: team)
_menuOptions(team: team) } label: {
} label: { LabelOptions().labelStyle(.iconOnly)
LabelOptions().labelStyle(.iconOnly)
}
} }
} }
} }
@ -70,6 +68,21 @@ struct TeamsCallingView: View {
} label: { } label: {
Text("Effacer la date de convocation") Text("Effacer la date de convocation")
} }
Divider()
Button(role: .destructive) {
team.callDate = team.initialMatch()?.startDate ?? tournament.startDate
do {
try self.tournament.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
} label: {
Text("Indiquer comme convoquée")
}
} }
} }

@ -110,7 +110,16 @@ struct GroupStageTeamView: View {
self.sentError = .messageFailed self.sentError = .messageFailed
case .sent: case .sent:
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.sentError = .messageNotSent self.contactType = nil
if team.getPhoneNumbers().isEmpty == false {
self.sentError = .uncalledTeams([team])
} else {
self.sentError = .messageNotSent
}
} else {
if team.getPhoneNumbers().isEmpty == false {
self.sentError = .uncalledTeams([team])
}
} }
@unknown default: @unknown default:
break break
@ -132,7 +141,15 @@ struct GroupStageTeamView: View {
case .sent: case .sent:
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.contactType = nil self.contactType = nil
self.sentError = .mailNotSent if team.getMail().isEmpty == false {
self.sentError = .uncalledTeams([team])
} else {
self.sentError = .mailNotSent
}
} else {
if team.getMail().isEmpty == false {
self.sentError = .uncalledTeams([team])
}
} }
@unknown default: @unknown default:
break break
@ -153,21 +170,7 @@ struct GroupStageTeamView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
} }
private func _save() { private func _save() {

@ -210,8 +210,19 @@ struct MatchDetailView: View {
case .failed: case .failed:
self.sentError = .messageFailed self.sentError = .messageFailed
case .sent: case .sent:
let uncalledTeams = match.teams().filter { $0.getPhoneNumbers().isEmpty }
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.sentError = .messageNotSent self.contactType = nil
if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .messageNotSent
}
} else {
if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
}
} }
@unknown default: @unknown default:
break break
@ -226,9 +237,19 @@ struct MatchDetailView: View {
self.contactType = nil self.contactType = nil
self.sentError = .mailFailed self.sentError = .mailFailed
case .sent: case .sent:
let uncalledTeams = match.teams().filter { $0.getMail().isEmpty }
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.contactType = nil self.contactType = nil
self.sentError = .mailNotSent if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .mailNotSent
}
} else {
if uncalledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
}
} }
@unknown default: @unknown default:
break break
@ -529,23 +550,8 @@ struct MatchDetailView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
} }
} }
//#Preview { //#Preview {

@ -267,7 +267,7 @@ struct TournamentLookUpView: View {
Text(2.formatted()).tag(2 as Int?) Text(2.formatted()).tag(2 as Int?)
Text(3.formatted()).tag(3 as Int?) Text(3.formatted()).tag(3 as Int?)
} label: { } label: {
Text("Durée max (en jours)") Text("Durée souhaitée (en jours)")
} }
Picker(selection: $appSettings.dayPeriod) { Picker(selection: $appSettings.dayPeriod) {

@ -204,13 +204,10 @@ struct TournamentSubscriptionView: View {
Label("Prévenir votre partenaire", systemImage: "person.2") Label("Prévenir votre partenaire", systemImage: "person.2")
} }
Button("Ajouter à votre agenda") { Button("Ajouter à votre agenda", systemImage: "calendar") {
addEvent() addEvent()
} }
ShareLink(item: federalTournament.shareMessage) {
Label("Partager les infos", systemImage: "info")
}
Link(destination: URL(string:"https://tenup.fft.fr/tournoi/\(federalTournament.id)")!) { Link(destination: URL(string:"https://tenup.fft.fr/tournoi/\(federalTournament.id)")!) {
Label("Voir sur Tenup", systemImage: "tennisball") Label("Voir sur Tenup", systemImage: "tennisball")
} }
@ -226,7 +223,12 @@ struct TournamentSubscriptionView: View {
Button("OK") { Button("OK") {
} }
if sentError == .calendarAccessDenied || sentError == .noCalendarAvailable { if case .calendarAccessDenied = sentError {
Button("Voir vos réglages") {
openAppSettings()
}
}
if case .noCalendarAvailable = sentError{
Button("Voir vos réglages") { Button("Voir vos réglages") {
openAppSettings() openAppSettings()
} }
@ -290,14 +292,14 @@ struct TournamentSubscriptionView: View {
var messageBody: String { var messageBody: String {
let bonjourOuBonsoir = Date().timeOfDay.hello let bonjourOuBonsoir = Date().timeOfDay.hello
let bonneSoireeOuBonneJournee = Date().timeOfDay.goodbye let bonneSoireeOuBonneJournee = Date().timeOfDay.goodbye
let body = [["\(bonjourOuBonsoir),\n\nJe souhaiterais inscrire mon équipe au tournoi : ", build.buildHolderTitle(), "du", federalTournament.computedStartDate, "au", federalTournament.clubLabel() + ".\n"].compacted().joined(separator: " "), teamsString, "\nCordialement,\n", user.fullName() ?? bonneSoireeOuBonneJournee, "----------------------------------\nCe message a été préparé grâce à l'application Padel Club !"].compactMap { $0 }.joined(separator: "\n") + "\n" let body = [["\(bonjourOuBonsoir),\n\nJe souhaiterais inscrire mon équipe au tournoi : ", build.buildHolderTitle(), "du", federalTournament.computedStartDate, "au", federalTournament.clubLabel() + ".\n"].compacted().joined(separator: " "), teamsString, "\nCordialement,\n", user.fullName() ?? bonneSoireeOuBonneJournee, "----------------------------------\nCe message a été préparé grâce à l'application Padel Club !\n\(URLs.appStore.rawValue)"].compactMap { $0 }.joined(separator: "\n") + "\n"
return body return body
} }
var messageBodyShort: String { var messageBodyShort: String {
let bonjourOuBonsoir = Date().timeOfDay.hello let bonjourOuBonsoir = Date().timeOfDay.hello
let bonneSoireeOuBonneJournee = Date().timeOfDay.goodbye let bonneSoireeOuBonneJournee = Date().timeOfDay.goodbye
let body = [["\(bonjourOuBonsoir),\n\nJe souhaiterais inscrire mon équipe au tournoi : ", build.buildHolderTitle(), "du", federalTournament.computedStartDate, "au", federalTournament.clubLabel() + ".\n"].compacted().joined(separator: " "), teamsString, "\nCordialement,\n", user.fullName() ?? bonneSoireeOuBonneJournee].compactMap { $0 }.joined(separator: "\n") + "\n" let body = [["\(bonjourOuBonsoir),\n\nJe souhaiterais inscrire mon équipe au tournoi : ", build.buildHolderTitle(), "du", federalTournament.computedStartDate, "au", federalTournament.clubLabel() + ".\n"].compacted().joined(separator: " "), teamsString, "\nCordialement,\n", user.fullName() ?? bonneSoireeOuBonneJournee, "----------------------------------\nCe message a été préparé grâce à l'application Padel Club !\n\(URLs.appStore.rawValue)"].compactMap { $0 }.joined(separator: "\n") + "\n"
return body return body
} }
@ -322,35 +324,7 @@ struct TournamentSubscriptionView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
if sentError == .calendarAccessDenied {
errors.append("Padel Club n'a pas accès à votre calendrier")
}
if sentError == .calendarEventSaveFailed {
errors.append("Padel Club n'a pas réussi à sauver ce tournoi dans votre calendrier")
}
if sentError == .noCalendarAvailable {
errors.append("Padel Club n'a pas réussi à trouver un calendrier pour y inscrire ce tournoi")
}
return errors.joined(separator: "\n")
} }
func openAppSettings() { func openAppSettings() {

@ -91,21 +91,20 @@ struct SelectablePlayerListView: View {
} }
Divider() Divider()
if SourceFileManager.canFilterByAge() { Section {
Section { Picker(selection: $searchViewModel.selectedAgeCategory) {
Picker(selection: $searchViewModel.selectedAgeCategory) { ForEach(FederalTournamentAge.allCases) { ageCategory in
ForEach(FederalTournamentAge.allCases) { ageCategory in Text(ageCategory.localizedLabel(.title)).tag(ageCategory)
Text(ageCategory.localizedLabel(.title)).tag(ageCategory)
}
} label: {
Text("Catégorie d'âge")
} }
} label: {
} header: {
Text("Catégorie d'âge") Text("Catégorie d'âge")
} }
Divider()
} header: {
Text("Catégorie d'âge")
} }
Divider()
Section { Section {
Toggle(isOn: .init(get: { Toggle(isOn: .init(get: {
return searchViewModel.hideAssimilation == false return searchViewModel.hideAssimilation == false

@ -103,21 +103,6 @@ struct SupportButtonView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
} }
} }

@ -36,7 +36,7 @@ struct TournamentFilterView: View {
Text(2.formatted()).tag(2 as Int?) Text(2.formatted()).tag(2 as Int?)
Text(3.formatted()).tag(3 as Int?) Text(3.formatted()).tag(3 as Int?)
} label: { } label: {
Text("Durée max (en jours)") Text("Durée souhaitée (en jours)")
} }
Picker(selection: $federalDataViewModel.dayPeriod) { Picker(selection: $federalDataViewModel.dayPeriod) {

@ -200,8 +200,19 @@ struct EditingTeamView: View {
case .failed: case .failed:
self.sentError = .messageFailed self.sentError = .messageFailed
case .sent: case .sent:
let uncalledTeams = team.getPhoneNumbers().isEmpty
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.sentError = .messageNotSent self.contactType = nil
if team.getPhoneNumbers().isEmpty == false {
self.sentError = .uncalledTeams([team])
} else {
self.sentError = .messageNotSent
}
} else {
if team.getPhoneNumbers().isEmpty == false {
self.sentError = .uncalledTeams([team])
}
} }
@unknown default: @unknown default:
break break
@ -221,9 +232,19 @@ struct EditingTeamView: View {
self.contactType = nil self.contactType = nil
self.sentError = .mailFailed self.sentError = .mailFailed
case .sent: case .sent:
let uncalledTeams = team.getMail().isEmpty
if networkMonitor.connected == false { if networkMonitor.connected == false {
self.contactType = nil self.contactType = nil
self.sentError = .mailNotSent if team.getMail().isEmpty == false {
self.sentError = .uncalledTeams([team])
} else {
self.sentError = .mailNotSent
}
} else {
if team.getMail().isEmpty == false {
self.sentError = .uncalledTeams([team])
}
} }
@unknown default: @unknown default:
break break
@ -294,23 +315,8 @@ struct EditingTeamView: View {
} }
private var _networkErrorMessage: String { private var _networkErrorMessage: String {
var errors: [String] = [] ContactManagerError.getNetworkErrorMessage(sentError: sentError, networkMonitorConnected: networkMonitor.connected)
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
} }
} }
//#Preview { //#Preview {

@ -24,7 +24,6 @@ struct InscriptionManagerView: View {
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@EnvironmentObject var networkMonitor: NetworkMonitor
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
var tournament: Tournament var tournament: Tournament
@ -45,9 +44,6 @@ struct InscriptionManagerView: View {
@State private var filterMode: FilterMode = .all @State private var filterMode: FilterMode = .all
@State private var sortingMode: SortingMode = .teamWeight @State private var sortingMode: SortingMode = .teamWeight
@State private var byDecreasingOrdering: Bool = false @State private var byDecreasingOrdering: Bool = false
@State private var contactType: ContactType? = nil
@State private var sentError: ContactManagerError? = nil
@State private var showSubscriptionView: Bool = false
@State private var confirmDuplicate: Bool = false @State private var confirmDuplicate: Bool = false
@State private var presentAddTeamView: Bool = false @State private var presentAddTeamView: Bool = false
@State private var compactMode: Bool = true @State private var compactMode: Bool = true
@ -56,17 +52,6 @@ struct InscriptionManagerView: View {
var tournamentStore: TournamentStore { var tournamentStore: TournamentStore {
return self.tournament.tournamentStore return self.tournament.tournamentStore
} }
var messageSentFailed: Binding<Bool> {
Binding {
sentError != nil
} set: { newValue in
if newValue == false {
sentError = nil
}
}
}
enum SortingMode: Int, Identifiable, CaseIterable { enum SortingMode: Int, Identifiable, CaseIterable {
var id: Int { self.rawValue } var id: Int { self.rawValue }
@ -238,61 +223,6 @@ struct InscriptionManagerView: View {
.onDisappear { .onDisappear {
_handleHashDiff() _handleHashDiff()
} }
.alert("Un problème est survenu", isPresented: messageSentFailed) {
Button("OK") {
}
} message: {
Text(_networkErrorMessage)
}
.sheet(item: $contactType) { contactType in
Group {
switch contactType {
case .message(_, let recipients, let body, _):
if Guard.main.paymentForNewTournament() != nil {
MessageComposeView(recipients: recipients, body: body) { result in
switch result {
case .cancelled:
break
case .failed:
self.sentError = .messageFailed
case .sent:
if networkMonitor.connected == false {
self.sentError = .messageNotSent
}
@unknown default:
break
}
}
} else {
SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
.environment(\.colorScheme, .light)
}
case .mail(_, let recipients, let bccRecipients, let body, let subject, _):
if Guard.main.paymentForNewTournament() != nil {
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
self.sentError = .mailNotSent
}
@unknown default:
break
}
}
} else {
SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
.environment(\.colorScheme, .light)
}
}
}
.tint(.master)
}
.sheet(isPresented: $isLearningMore) { .sheet(isPresented: $isLearningMore) {
LearnMoreSheetView(tournament: tournament) LearnMoreSheetView(tournament: tournament)
.tint(.master) .tint(.master)
@ -997,25 +927,6 @@ struct InscriptionManagerView: View {
Logger.error(error) Logger.error(error)
} }
} }
private var _networkErrorMessage: String {
var errors: [String] = []
if networkMonitor.connected == false {
errors.append("L'appareil n'est pas connecté à internet.")
}
if sentError == .mailNotSent {
errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
}
if (sentError == .messageFailed || sentError == .messageNotSent) {
errors.append("Le SMS n'a pas été envoyé")
}
if sentError == .mailFailed {
errors.append("Le mail n'a pas été envoyé")
}
return errors.joined(separator: "\n")
}
} }
//#Preview { //#Preview {

@ -106,7 +106,7 @@ struct TournamentCallView: View {
case .some(let selectedCall): case .some(let selectedCall):
switch selectedCall { switch selectedCall {
case .teams: case .teams:
TeamsCallingView() TeamsCallingView(teams: tournament.selectedSortedTeams())
case .groupStages: case .groupStages:
GroupStageCallingView() GroupStageCallingView()
case .seeds: case .seeds:

Loading…
Cancel
Save