improve call team view

main
Razmig Sarkissian 3 weeks ago
parent 858a68c572
commit 757f22cc67
  1. 112
      PadelClub/Views/Calling/CallView.swift
  2. 57
      PadelClub/Views/Calling/TeamsCallingView.swift

@ -60,9 +60,10 @@ struct CallView: View {
@State var showUserCreationView: Bool = false
@State var summonParamByMessage: Bool = false
@State var summonParamReSummon: Bool = false
@State var summonParamReSummon: SummonType = .contact
let simpleMode : Bool
let summonType: SummonType
init(teams: [TeamRegistration], callDate: Date, matchFormat: MatchFormat, roundLabel: String) {
self.teams = teams
@ -71,6 +72,7 @@ struct CallView: View {
self.roundLabel = roundLabel
self.simpleMode = false
self.displayContext = .footer
self.summonType = .contact
}
init(teams: [TeamRegistration]) {
@ -80,12 +82,14 @@ struct CallView: View {
self.roundLabel = ""
self.simpleMode = true
self.displayContext = .footer
self.summonType = .contact
}
init(team: TeamRegistration, displayContext: SummoningDisplayContext) {
init(team: TeamRegistration, displayContext: SummoningDisplayContext, summonType: SummonType) {
self.teams = [team]
let expectedSummonDate = team.expectedSummonDate()
self.displayContext = displayContext
self.summonType = summonType
if let expectedSummonDate, let initialMatch = team.initialMatch() {
self.callDate = expectedSummonDate
@ -97,6 +101,11 @@ struct CallView: View {
self.matchFormat = initialGroupStage.matchFormat
self.roundLabel = "poule"
self.simpleMode = false
} else if let expectedSummonDate {
self.callDate = expectedSummonDate
self.matchFormat = MatchFormat.nineGames
self.roundLabel = ""
self.simpleMode = false
} else {
self.callDate = Date()
self.matchFormat = MatchFormat.nineGames
@ -126,7 +135,7 @@ struct CallView: View {
if success {
calledTeams.forEach { team in
team.callDate = callDate
if reSummon {
if summonType.shouldConfirm() {
team.confirmationDate = nil
}
}
@ -138,21 +147,21 @@ struct CallView: View {
}
}
func finalMessage(reSummon: Bool, forcedEmptyMessage: Bool) -> String {
func finalMessage(summonType: SummonType, forcedEmptyMessage: Bool) -> String {
if simpleMode || forcedEmptyMessage {
let signature = dataStore.user.getSummonsMessageSignature() ?? dataStore.user.defaultSignature(tournament)
return "\n\n\n\n" + signature
}
return ContactType.callingMessage(tournament: tournament, startDate: callDate, roundLabel: roundLabel, matchFormat: matchFormat, reSummon: reSummon)
}
var reSummon: Bool {
if simpleMode {
return false
}
return self.teams.allSatisfy({ $0.called() })
return ContactType.callingMessage(tournament: tournament, startDate: callDate, roundLabel: roundLabel, matchFormat: matchFormat, summonType: summonType)
}
//
// var summonType: SummonType {
// if simpleMode {
// return .contact
// }
// return self.teams.allSatisfy({ $0.called() }) == true ? .summon : .summonWalkoutFollowUp
// }
var mainWord: String {
if simpleMode {
@ -263,7 +272,7 @@ struct CallView: View {
LoginView(reason: LoginReason.loginRequiredForFeature) { _ in
self.showUserCreationView = false
self._summon(byMessage: self.summonParamByMessage,
reSummon: self.summonParamByMessage)
summonType: self.summonType)
}
}
})
@ -271,7 +280,7 @@ struct CallView: View {
private func _footerStyleView() -> some View {
HStack {
let callWord : String = (reSummon ? "Reconvoquer" : mainWord)
let callWord : String = (summonType.isRecall() ? "Reconvoquer" : mainWord)
if self.teams.count == 1 {
if simpleMode {
Text("\(callWord) cette paire par")
@ -299,19 +308,24 @@ struct CallView: View {
self._summonMenu(byMessage: true)
self._summonMenu(byMessage: false)
} label: {
let callWord : String = (reSummon ? "Reconvoquer" : mainWord)
if self.teams.count == 1 {
if simpleMode {
Text("\(callWord) cette paire")
} else {
if let previousCallDate = teams.first?.callDate, Calendar.current.compare(previousCallDate, to: callDate, toGranularity: .minute) != .orderedSame {
Text("Reconvoquer \(self.callDate.localizedDate())")
} else {
VStack(alignment: .leading) {
let callWord : String = (summonType.isRecall() ? "Reconvoquer" : mainWord)
if self.teams.count == 1 {
if simpleMode {
Text("\(callWord) cette paire")
} else {
if let previousCallDate = teams.first?.callDate, Calendar.current.compare(previousCallDate, to: callDate, toGranularity: .minute) != .orderedSame {
Text("Reconvoquer \(self.callDate.localizedDate())")
} else {
Text("\(callWord) cette paire")
}
}
} else {
Text("\(callWord) ces \(self.teams.count) paires")
}
if let caption = summonType.caption() {
Text(caption).foregroundStyle(.secondary).font(.caption)
}
} else {
Text("\(callWord) ces \(self.teams.count) paires")
}
}
}
@ -319,20 +333,40 @@ struct CallView: View {
@ViewBuilder
private func _summonMenu(byMessage: Bool) -> some View {
if self.reSummon {
if displayContext == .menu {
Button {
switch summonType {
case .contact:
self._summon(byMessage: byMessage, summonType: .contact, forcedEmptyMessage: true)
case .summon:
self._summon(byMessage: byMessage, summonType: .summon)
case .summonWalkoutFollowUp:
self._summon(byMessage: byMessage, summonType: .summonWalkoutFollowUp)
case .summonErrorFollowUp:
self._summon(byMessage: byMessage, summonType: .summonErrorFollowUp)
}
} label: {
Text(byMessage ? "sms" : "mail")
.underline()
}
} else if summonType.isRecall() {
Menu {
Button(mainWord) {
self._summon(byMessage: byMessage, reSummon: false)
self._summon(byMessage: byMessage, summonType: simpleMode ? .contact : .summon)
}
Button("Re-convoquer") {
self._summon(byMessage: byMessage, reSummon: true)
Button("Re-convoquer suite à des forfaits") {
self._summon(byMessage: byMessage, summonType: .summonWalkoutFollowUp)
}
Button("Re-convoquer suite à une erreur") {
self._summon(byMessage: byMessage, summonType: .summonErrorFollowUp)
}
if simpleMode == false {
Divider()
Button("Contacter") {
self._summon(byMessage: byMessage, reSummon: false, forcedEmptyMessage: true)
self._summon(byMessage: byMessage, summonType: .contact, forcedEmptyMessage: true)
}
}
@ -342,19 +376,19 @@ struct CallView: View {
}
} else {
FooterButtonView(byMessage ? "sms" : "mail") {
self._summon(byMessage: byMessage, reSummon: false)
self._summon(byMessage: byMessage, summonType: summonType)
}
}
}
private func _summon(byMessage: Bool, reSummon: Bool, forcedEmptyMessage: Bool = false) {
private func _summon(byMessage: Bool, summonType: SummonType, forcedEmptyMessage: Bool = false) {
self.summonParamByMessage = byMessage
self.summonParamReSummon = reSummon
self.summonParamReSummon = summonType
self._verifyUser {
if byMessage {
self._contactByMessage(reSummon: reSummon, forcedEmptyMessage: forcedEmptyMessage)
self._contactByMessage(summonType: summonType, forcedEmptyMessage: forcedEmptyMessage)
} else {
self._contactByMail(reSummon: reSummon, forcedEmptyMessage: forcedEmptyMessage)
self._contactByMail(summonType: summonType, forcedEmptyMessage: forcedEmptyMessage)
}
}
}
@ -376,18 +410,18 @@ struct CallView: View {
// }
// }
fileprivate func _contactByMessage(reSummon: Bool, forcedEmptyMessage: Bool) {
fileprivate func _contactByMessage(summonType: SummonType, forcedEmptyMessage: Bool) {
self.contactType = .message(date: callDate,
recipients: teams.flatMap { $0.getPhoneNumbers() },
body: finalMessage(reSummon: reSummon, forcedEmptyMessage: forcedEmptyMessage),
body: finalMessage(summonType: summonType, forcedEmptyMessage: forcedEmptyMessage),
tournamentBuild: nil)
}
fileprivate func _contactByMail(reSummon: Bool, forcedEmptyMessage: Bool) {
fileprivate func _contactByMail(summonType: SummonType, forcedEmptyMessage: Bool) {
self.contactType = .mail(date: callDate,
recipients: tournament.umpireMail(),
bccRecipients: teams.flatMap { $0.getMail() },
body: finalMessage(reSummon: reSummon, forcedEmptyMessage: forcedEmptyMessage),
body: finalMessage(summonType: summonType, forcedEmptyMessage: forcedEmptyMessage),
subject: tournament.mailSubject(),
tournamentBuild: nil)
}

@ -129,21 +129,28 @@ struct CallMenuOptionsView: View {
@Environment(Tournament.self) var tournament: Tournament
let team: TeamRegistration
let action: (() -> Void)?
@State private var callDate: Date
init(team: TeamRegistration, action: (() -> Void)?) {
self.team = team
self.action = action
_callDate = .init(wrappedValue: team.expectedSummonDate() ?? team.tournamentObject()?.startDate ?? Date())
}
var confirmed: Binding<Bool> {
Binding {
team.confirmed()
} set: { _ in
team.toggleSummonConfirmation()
do {
try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
_save()
action?()
}
}
private func _save() {
self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
}
var body: some View {
List {
Section {
@ -151,11 +158,33 @@ struct CallMenuOptionsView: View {
Toggle(isOn: confirmed) {
Text("Confirmation reçue")
}
DatePicker(selection: $callDate) {
if callDate != team.expectedSummonDate() {
HStack {
Button("Valider", systemImage: "checkmark.circle") {
team.callDate = callDate
_save()
}
.tint(.green)
Divider()
Button("Annuler", systemImage: "xmark.circle", role: .cancel) {
callDate = team.expectedSummonDate() ?? tournament.startDate
}
.tint(.logoRed)
}
.labelStyle(.iconOnly)
.buttonStyle(.borderedProminent)
} else {
Text("Heure de convocation")
}
}
if team.expectedSummonDate() != nil {
CallView(team: team, displayContext: .menu)
CallView(team: team, displayContext: .menu, summonType: .summon)
CallView(team: team, displayContext: .menu, summonType: .summonWalkoutFollowUp)
CallView(team: team, displayContext: .menu, summonType: .summonErrorFollowUp)
}
} footer: {
CallView(teams: [team])
}
Section {
@ -170,11 +199,7 @@ struct CallMenuOptionsView: View {
Section {
RowButtonView("Effacer la date de convocation", role: .destructive) {
team.callDate = nil
do {
try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
_save()
action?()
dismiss()
}
@ -183,11 +208,7 @@ struct CallMenuOptionsView: View {
Section {
RowButtonView("Indiquer comme convoquée", role: .destructive) {
team.callDate = team.initialMatch()?.startDate ?? tournament.startDate
do {
try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
_save()
action?()
dismiss()
}

Loading…
Cancel
Save