Merge branch 'main' of https://stax.alwaysdata.net/gitea/staxriver/PadelClub
commit
70c943330f
@ -0,0 +1,80 @@ |
|||||||
|
// |
||||||
|
// MenuWarningView.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by razmig on 28/04/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
|
||||||
|
struct MenuWarningView: View { |
||||||
|
let teams: [TeamRegistration] |
||||||
|
var date: Date? |
||||||
|
var message: String? |
||||||
|
var umpireMail: String? |
||||||
|
var subject: String? |
||||||
|
|
||||||
|
@Binding var contactType: ContactType? |
||||||
|
|
||||||
|
private func _getUmpireMail() -> [String]? { |
||||||
|
if let umpireMail { |
||||||
|
return [umpireMail] |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
@ViewBuilder |
||||||
|
private func _actionView(players: [PlayerRegistration], privateMode: Bool = false) -> some View { |
||||||
|
Button("Message") { |
||||||
|
contactType = .message(date: date, recipients: players.compactMap({ $0.phoneNumber }), body: message, tournamentBuild: nil) |
||||||
|
} |
||||||
|
Button("Mail") { |
||||||
|
contactType = .mail(date: date, recipients: privateMode ? _getUmpireMail() : players.compactMap({ $0.email }), bccRecipients: privateMode ? players.compactMap({ $0.email }) : nil, body: message, subject: subject, tournamentBuild: nil) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
|
||||||
|
Menu { |
||||||
|
Menu("Tout le monde") { |
||||||
|
let players = teams.flatMap({ $0.players() }) |
||||||
|
_actionView(players: players, privateMode: true) |
||||||
|
} |
||||||
|
Divider() |
||||||
|
ForEach(teams) { team in |
||||||
|
_teamView(team) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
Text("Prévenir") |
||||||
|
.underline() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func _playerView(_ player: PlayerRegistration) -> some View { |
||||||
|
Menu { |
||||||
|
let players = [player] |
||||||
|
_actionView(players: players) |
||||||
|
} label: { |
||||||
|
Text(player.playerLabel(.short)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func _teamView(_ team: TeamRegistration) -> some View { |
||||||
|
Menu { |
||||||
|
Menu("Toute l'équipe") { |
||||||
|
let players = team.players() |
||||||
|
_actionView(players: players) |
||||||
|
} |
||||||
|
Divider() |
||||||
|
ForEach(team.players()) { player in |
||||||
|
_playerView(player) |
||||||
|
} |
||||||
|
} label: { |
||||||
|
Text(team.teamLabel(.short)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#Preview { |
||||||
|
MenuWarningView(teams: [], contactType: .constant(nil)) |
||||||
|
} |
||||||
@ -0,0 +1,167 @@ |
|||||||
|
// |
||||||
|
// SendToAllView.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Razmig Sarkissian on 28/04/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
import LeStorage |
||||||
|
|
||||||
|
struct SendToAllView: View { |
||||||
|
@Environment(Tournament.self) var tournament: Tournament |
||||||
|
@EnvironmentObject var networkMonitor: NetworkMonitor |
||||||
|
|
||||||
|
@State private var contactType: ContactType? = nil |
||||||
|
@State private var contactMethod: Int = 1 |
||||||
|
@State private var contactRecipients: Set<String> = Set() |
||||||
|
@State private var sentError: ContactManagerError? = nil |
||||||
|
|
||||||
|
var messageSentFailed: Binding<Bool> { |
||||||
|
Binding { |
||||||
|
sentError != nil |
||||||
|
} set: { newValue in |
||||||
|
if newValue == false { |
||||||
|
sentError = nil |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
NavigationStack { |
||||||
|
List(selection: $contactRecipients) { |
||||||
|
Section { |
||||||
|
Picker(selection: $contactMethod) { |
||||||
|
Text("Contacter par sms").tag(0) |
||||||
|
Text("Contacter par mail").tag(1) |
||||||
|
} label: { |
||||||
|
Text("méthode") |
||||||
|
} |
||||||
|
.labelsHidden() |
||||||
|
.pickerStyle(.inline) |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
ForEach(tournament.groupStages()) { groupStage in |
||||||
|
let teams = groupStage.teams() |
||||||
|
if teams.isEmpty == false { |
||||||
|
LabeledContent { |
||||||
|
Text(teams.count.formatted() + " équipe" + teams.count.pluralSuffix) |
||||||
|
} label: { |
||||||
|
Text(groupStage.groupStageTitle()) |
||||||
|
} |
||||||
|
.tag(groupStage.id) |
||||||
|
} |
||||||
|
} |
||||||
|
ForEach(tournament.rounds()) { round in |
||||||
|
let teams = round.teams() |
||||||
|
if teams.isEmpty == false { |
||||||
|
LabeledContent { |
||||||
|
Text(teams.count.formatted() + " équipe" + teams.count.pluralSuffix) |
||||||
|
} label: { |
||||||
|
Text(round.roundTitle()) |
||||||
|
} |
||||||
|
.tag(round.id) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
RowButtonView("Contacter \(_totalString())") { |
||||||
|
if contactMethod == 0 { |
||||||
|
contactType = .message(date: nil, recipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.phoneNumber }, body: tournament.tournamentTitle(), tournamentBuild: nil) |
||||||
|
} else { |
||||||
|
contactType = .mail(date: nil, recipients: nil, bccRecipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.email }, body: nil, subject: tournament.tournamentTitle(), tournamentBuild: nil) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.environment(\.editMode, Binding.constant(EditMode.active)) |
||||||
|
.headerProminence(.increased) |
||||||
|
.navigationTitle("Réglages") |
||||||
|
.navigationBarTitleDisplayMode(.inline) |
||||||
|
.toolbarBackground(.visible, for: .navigationBar) |
||||||
|
.alert("Un problème est survenu", isPresented: messageSentFailed) { |
||||||
|
Button("OK") { |
||||||
|
} |
||||||
|
} message: { |
||||||
|
let message = [networkMonitor.connected == false ? "L'appareil n'est pas connecté à internet." as String? : nil, sentError == .mailNotSent ? "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." as String? : nil, (sentError == .messageFailed || sentError == .messageNotSent) ? "Le SMS n'a pas été envoyé" as String? : nil, sentError == .mailFailed ? "Le mail n'a pas été envoyé" as String? : nil].compacted().joined(separator: "\n") |
||||||
|
Text(message) |
||||||
|
} |
||||||
|
.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(showLackOfPlanMessage: true) |
||||||
|
} |
||||||
|
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(showLackOfPlanMessage: true) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.tint(.master) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func _teams() -> [TeamRegistration] { |
||||||
|
_roundTeams() + _groupStagesTeams() |
||||||
|
} |
||||||
|
|
||||||
|
func _roundTeams() -> [TeamRegistration] { |
||||||
|
let rounds : [Round] = contactRecipients.compactMap { Store.main.findById($0) } |
||||||
|
return rounds.flatMap({ $0.teams() }) |
||||||
|
} |
||||||
|
|
||||||
|
func _groupStagesTeams() -> [TeamRegistration] { |
||||||
|
let groupStages : [GroupStage] = contactRecipients.compactMap { Store.main.findById($0) } |
||||||
|
return groupStages.flatMap({ $0.teams() }) |
||||||
|
} |
||||||
|
|
||||||
|
func _totalString() -> String { |
||||||
|
if contactRecipients.isEmpty { |
||||||
|
return "toutes les équipes" |
||||||
|
} else { |
||||||
|
let teams = _teams() |
||||||
|
return teams.count.formatted() + " équipe" + teams.count.pluralSuffix |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#Preview { |
||||||
|
SendToAllView() |
||||||
|
} |
||||||
Loading…
Reference in new issue