add QoL features on summoning screen

paca_championship
Raz 1 year ago
parent 20eeea99b8
commit a51adc6bbe
  1. 5
      PadelClub/Utils/DisplayContext.swift
  2. 4
      PadelClub/Views/Calling/BracketCallingView.swift
  3. 128
      PadelClub/Views/Calling/CallView.swift
  4. 2
      PadelClub/Views/Calling/GroupStageCallingView.swift
  5. 2
      PadelClub/Views/Calling/SeedsCallingView.swift
  6. 130
      PadelClub/Views/Calling/TeamsCallingView.swift
  7. 9
      PadelClub/Views/Tournament/Screen/Components/InscriptionInfoView.swift

@ -21,6 +21,11 @@ enum DisplayStyle {
case short
}
enum SummoningDisplayContext {
case footer
case menu
}
enum MatchViewStyle {
case standardStyle // vue normal
case sectionedStandardStyle // vue normal avec des sections indiquant déjà la manche

@ -162,7 +162,7 @@ struct BracketCallingView: View {
if badCalled.isEmpty == false {
Section {
ForEach(badCalled) { team in
CallView.TeamView(team: team)
TeamCallView(team: team)
}
} header: {
HStack {
@ -179,7 +179,7 @@ struct BracketCallingView: View {
Section {
ForEach(seeds) { team in
CallView.TeamView(team: team)
TeamCallView(team: team)
}
} header: {
HStack {

@ -41,14 +41,6 @@ struct CallView: View {
}
}
struct TeamView: View {
let team: TeamRegistration
var body: some View {
TeamRowView(team: team, displayCallDate: true)
}
}
@EnvironmentObject var dataStore: DataStore
@EnvironmentObject var networkMonitor: NetworkMonitor
@ -58,6 +50,7 @@ struct CallView: View {
let callDate: Date
let matchFormat: MatchFormat
let roundLabel: String
let displayContext: SummoningDisplayContext
@State private var contactType: ContactType? = nil
@State private var sentError: ContactManagerError? = nil
@ -76,6 +69,7 @@ struct CallView: View {
self.matchFormat = matchFormat
self.roundLabel = roundLabel
self.simpleMode = false
self.displayContext = .footer
}
init(teams: [TeamRegistration]) {
@ -84,6 +78,30 @@ struct CallView: View {
self.matchFormat = MatchFormat.nineGames
self.roundLabel = ""
self.simpleMode = true
self.displayContext = .footer
}
init(team: TeamRegistration, displayContext: SummoningDisplayContext) {
self.teams = [team]
let expectedSummonDate = team.expectedSummonDate()
self.displayContext = displayContext
if let expectedSummonDate, let initialMatch = team.initialMatch() {
self.callDate = expectedSummonDate
self.matchFormat = initialMatch.matchFormat
self.roundLabel = initialMatch.roundTitle() ?? "tableau"
self.simpleMode = false
} else if let expectedSummonDate, let initialGroupStage = team.groupStageObject() {
self.callDate = expectedSummonDate
self.matchFormat = initialGroupStage.matchFormat
self.roundLabel = "poule"
self.simpleMode = false
} else {
self.callDate = Date()
self.matchFormat = MatchFormat.nineGames
self.roundLabel = ""
self.simpleMode = true
}
}
var tournamentStore: TournamentStore {
@ -107,6 +125,9 @@ struct CallView: View {
if success {
calledTeams.forEach { team in
team.callDate = callDate
if reSummon {
team.confirmationDate = nil
}
}
do {
try self.tournamentStore.teamRegistrations.addOrUpdate(contentOfs: calledTeams)
@ -141,28 +162,14 @@ struct CallView: View {
}
var body: some View {
let callWord : String = (reSummon ? "Reconvoquer" : mainWord)
HStack {
if self.teams.count == 1 {
if simpleMode {
Text("\(callWord) cette paire par")
} else {
if let previousCallDate = teams.first?.callDate, Calendar.current.compare(previousCallDate, to: callDate, toGranularity: .minute) != .orderedSame {
Text("Reconvoquer \(self.callDate.localizedDate()) par")
} else {
Text("\(callWord) cette paire par")
}
}
} else {
Text("\(callWord) ces \(self.teams.count) paires par")
Group {
switch displayContext {
case .footer:
_footerStyleView()
case .menu:
_menuStyleView()
}
self._summonMenu(byMessage: true)
Text("ou")
self._summonMenu(byMessage: false)
}
.font(.subheadline)
.buttonStyle(.borderless)
.alert("Un problème est survenu", isPresented: messageSentFailed) {
Button("OK") {
}
@ -258,6 +265,54 @@ struct CallView: View {
}
})
}
private func _footerStyleView() -> some View {
HStack {
let callWord : String = (reSummon ? "Reconvoquer" : mainWord)
if self.teams.count == 1 {
if simpleMode {
Text("\(callWord) cette paire par")
} else {
if let previousCallDate = teams.first?.callDate, Calendar.current.compare(previousCallDate, to: callDate, toGranularity: .minute) != .orderedSame {
Text("Reconvoquer \(self.callDate.localizedDate()) par")
} else {
Text("\(callWord) cette paire par")
}
}
} else {
Text("\(callWord) ces \(self.teams.count) paires par")
}
self._summonMenu(byMessage: true)
Text("ou")
self._summonMenu(byMessage: false)
}
.font(.subheadline)
.buttonStyle(.borderless)
}
private func _menuStyleView() -> some View {
Menu {
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 {
Text("\(callWord) cette paire")
}
}
} else {
Text("\(callWord) ces \(self.teams.count) paires")
}
}
}
@ViewBuilder
private func _summonMenu(byMessage: Bool) -> some View {
@ -334,3 +389,20 @@ struct CallView: View {
}
}
struct TeamCallView: View {
@Environment(Tournament.self) var tournament: Tournament
let team: TeamRegistration
var action: (() -> Void)?
var body: some View {
NavigationLink {
CallMenuOptionsView(team: team, action: action)
.environment(tournament)
} label: {
TeamRowView(team: team, displayCallDate: true)
}
.buttonStyle(.plain)
.listRowView(isActive: team.confirmed(), color: .green, hideColorVariation: true)
}
}

@ -86,7 +86,7 @@ struct GroupStageCallingView: View {
ForEach(teams) { team in
if let startDate = groupStage.initialStartDate(forTeam: team) {
Section {
CallView.TeamView(team: team)
TeamCallView(team: team)
} header: {
Text(startDate.localizedDate())
} footer: {

@ -101,7 +101,7 @@ struct SeedsCallingView: View {
let teams = round.seeds(inMatchIndex: match.index)
Section {
ForEach(teams) { team in
CallView.TeamView(team: team)
TeamCallView(team: team)
}
} header: {
HStack {

@ -55,28 +55,16 @@ struct TeamsCallingView: View {
Text("Paire\(confirmed.count.pluralSuffix) confirmée\(confirmed.count.pluralSuffix)")
}
} footer: {
Text("Vous pouvez indiquer si une équipe vous a confirmé sa convocation en appuyant sur ") + Text(Image(systemName: "ellipsis.circle"))
Text("Vous pouvez filtrer cette liste en appuyant sur ") + Text(Image(systemName: "line.3.horizontal.decrease.circle"))
}
}
if teams.isEmpty == false {
if filteredTeams.isEmpty == false {
Section {
ForEach(filteredTeams) { team in
Menu {
_menuOptions(team: team)
} label: {
HStack {
TeamRowView(team: team, displayCallDate: true)
Spacer()
Menu {
_menuOptions(team: team)
} label: {
LabelOptions().labelStyle(.iconOnly)
}
}
TeamCallView(team: team) {
searchText = ""
}
.buttonStyle(.plain)
.listRowView(isActive: team.confirmed(), color: .green, hideColorVariation: true)
}
} header: {
HStack {
@ -115,63 +103,79 @@ struct TeamsCallingView: View {
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
}
}
@ViewBuilder
func _menuOptions(team: TeamRegistration) -> some View {
Button {
struct CallMenuOptionsView: View {
@Environment(\.dismiss) private var dismiss
@Environment(Tournament.self) var tournament: Tournament
let team: TeamRegistration
let action: (() -> Void)?
var confirmed: Binding<Bool> {
Binding {
team.confirmed()
} set: { _ in
team.toggleSummonConfirmation()
do {
try self.tournament.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
searchText = ""
} label: {
if team.confirmed() {
Label("Confirmation reçue", systemImage: "checkmark.circle.fill").foregroundStyle(.green)
} else {
Label("Confirmation reçue", systemImage: "circle").foregroundStyle(.logoRed)
}
action?()
}
Divider()
NavigationLink {
EditingTeamView(team: team)
.environment(tournament)
} label: {
Text("Détails de l'équipe")
}
Divider()
Button(role: .destructive) {
team.callDate = nil
do {
try self.tournament.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
var body: some View {
List {
Section {
TeamRowView(team: team, displayCallDate: true)
Toggle(isOn: confirmed) {
Text("Confirmation reçue")
}
if team.expectedSummonDate() != nil {
CallView(team: team, displayContext: .menu)
}
} footer: {
CallView(teams: [team])
}
searchText = ""
} label: {
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)
Section {
NavigationLink {
EditingTeamView(team: team)
.environment(tournament)
} label: {
Text("Détails de l'équipe")
}
}
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)
}
action?()
dismiss()
}
}
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)
}
action?()
dismiss()
}
}
searchText = ""
} label: {
Text("Indiquer comme convoquée")
}
.navigationTitle("Options de convocation")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
}
}

@ -57,14 +57,7 @@ struct InscriptionInfoView: View {
Section {
DisclosureGroup {
ForEach(callDateIssue) { team in
CallView.TeamView(team: team)
if let groupStage = team.groupStageObject(), let callDate = groupStage.startDate {
CallView(teams: [team], callDate: callDate, matchFormat: groupStage.matchFormat, roundLabel: "poule")
} else if let initialRound = team.initialRound(),
let initialMatch = team.initialMatch(),
let callDate = initialMatch.startDate {
CallView(teams: [team], callDate: callDate, matchFormat: initialMatch.matchFormat, roundLabel: initialRound.roundTitle())
}
TeamCallView(team: team)
}
} label: {
LabeledContent {

Loading…
Cancel
Save