@ -14,10 +14,15 @@ struct TournamentGeneralSettingsView: View {
@ Bindable var tournament : Tournament
@ State private var tournamentName : String = " "
@ State private var entryFee : Double ? = nil
@ State private var confirmationRequired : Bool = false
@ State private var presentConfirmation : Bool = false
@ State private var loserBracketMode : LoserBracketMode
@ FocusState private var focusedField : Tournament . CodingKeys ?
let priceTags : [ Double ] = [ 15.0 , 20.0 , 25.0 ]
init ( tournament : Tournament ) {
self . tournament = tournament
_loserBracketMode = . init ( wrappedValue : tournament . loserBracketMode )
_tournamentName = State ( wrappedValue : tournament . name ? ? " " )
_entryFee = State ( wrappedValue : tournament . entryFee )
}
@ -25,6 +30,17 @@ struct TournamentGeneralSettingsView: View {
var body : some View {
@ Bindable var tournament = tournament
Form {
Section {
TextField ( " Nom du tournoi " , text : $ tournamentName , axis : . vertical )
. lineLimit ( 2 )
. frame ( maxWidth : . infinity )
. keyboardType ( . alphabet )
. focused ( $ focusedField , equals : . _name )
} header : {
Text ( " Nom du tournoi " )
}
Section {
TournamentDatePickerView ( )
TournamentDurationManagerView ( )
@ -37,17 +53,8 @@ struct TournamentGeneralSettingsView: View {
} label : {
Text ( " Inscription " )
}
}
Section {
TextField ( " Nom du tournoi " , text : $ tournamentName , axis : . vertical )
. lineLimit ( 2 )
. frame ( maxWidth : . infinity )
. keyboardType ( . alphabet )
. focused ( $ focusedField , equals : . _name )
} header : {
Text ( " Nom du tournoi " )
} footer : {
Text ( " Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs. " )
}
Section {
@ -55,31 +62,24 @@ struct TournamentGeneralSettingsView: View {
}
Section {
Picker ( selection : $ tournament . loserBracketMode ) {
Picker ( selection : $ loserBracketMode ) {
ForEach ( LoserBracketMode . allCases ) {
Text ( $0 . localizedLoserBracketMode ( ) ) . tag ( $0 )
}
} label : {
Text ( " Position des perdants " )
}
. onChange ( of : tournament . loserBracketMode ) {
_save ( )
let rounds = tournament . rounds ( )
rounds . forEach { round in
round . loserBracketMode = tournament . loserBracketMode
}
do {
try self . tournament . tournamentStore . rounds . addOrUpdate ( contentOfs : rounds )
} catch {
Logger . error ( error )
. onChange ( of : loserBracketMode ) {
if tournament . allLoserRoundMatches ( ) . anySatisfy ( { $0 . hasEnded ( ) } ) = = false {
_refreshLoserBracketMode ( )
} else {
confirmationRequired = true
}
}
} header : {
Text ( " Matchs de classement " )
} footer : {
if confirmationRequired = = false {
if dataStore . user . loserBracketMode != tournament . loserBracketMode {
_footerView ( )
. onTapGesture ( perform : {
@ -89,8 +89,24 @@ struct TournamentGeneralSettingsView: View {
} else {
Text ( tournament . loserBracketMode . localizedLoserBracketModeDescription ( ) )
}
} else {
_footerViewConfirmationRequired ( )
. onTapGesture ( perform : {
presentConfirmation = true
} )
}
}
}
. confirmationDialog ( " Attention " , isPresented : $ presentConfirmation , actions : {
Button ( " Confirmer " , role : . destructive ) {
_refreshLoserBracketMode ( )
confirmationRequired = false
}
Button ( " Annuler " , role : . cancel ) {
loserBracketMode = tournament . loserBracketMode
}
} )
. navigationBarBackButtonHidden ( focusedField != nil )
. toolbar ( content : {
if focusedField != nil {
@ -106,6 +122,26 @@ struct TournamentGeneralSettingsView: View {
if focusedField != nil {
ToolbarItem ( placement : . keyboard ) {
HStack {
if focusedField = = . _entryFee {
if tournament . isFree ( ) {
ForEach ( priceTags , id : \ . self ) { priceTag in
Button ( priceTag . formatted ( . currency ( code : " EUR " ) ) ) {
entryFee = priceTag
tournament . entryFee = priceTag
focusedField = nil
}
. buttonStyle ( . bordered )
}
} else {
Button ( " Gratuit " ) {
entryFee = nil
tournament . entryFee = nil
focusedField = nil
}
. buttonStyle ( . bordered )
}
}
Spacer ( )
Button ( " Valider " ) {
if focusedField = = . _name {
@ -166,9 +202,50 @@ struct TournamentGeneralSettingsView: View {
}
}
private func _refreshLoserBracketMode ( ) {
tournament . loserBracketMode = loserBracketMode
_save ( )
let rounds = tournament . rounds ( )
rounds . forEach { round in
let matches = round . loserRoundsAndChildren ( ) . flatMap ( { $0 . _matches ( ) } )
matches . forEach { match in
match . resetTeamScores ( outsideOf : [ ] )
match . resetMatch ( )
match . confirmed = false
}
round . loserBracketMode = tournament . loserBracketMode
if loserBracketMode = = . automatic {
matches . forEach { match in
match . updateTeamScores ( )
}
}
do {
try self . tournament . tournamentStore . matches . addOrUpdate ( contentOfs : matches )
} catch {
Logger . error ( error )
}
}
do {
try self . tournament . tournamentStore . rounds . addOrUpdate ( contentOfs : rounds )
} catch {
Logger . error ( error )
}
}
private func _footerView ( ) -> some View {
Text ( tournament . loserBracketMode . localizedLoserBracketModeDescription ( ) )
+
Text ( " Modifier le réglage par défaut pour tous vos tournois " ) . foregroundStyle ( . blue )
}
private func _footerViewConfirmationRequired ( ) -> some View {
Text ( " Au moins un match de classement est terminé, en modifiant ce réglage, les résultats de ces matchs de classement seront perdus. " )
+
Text ( " Modifier quand même ? " ) . foregroundStyle ( . red )
}
}