@ -372,20 +372,20 @@ struct AddTeamView: View {
self . tournamentStore ? . teamRegistrations . addOrUpdate ( instance : team )
self . tournamentStore ? . teamRegistrations . addOrUpdate ( instance : team )
self . tournamentStore ? . playerRegistrations . addOrUpdate ( contentOfs : players )
self . tournamentStore ? . playerRegistrations . addOrUpdate ( contentOfs : players )
pasteString = nil
pasteString = nil
editableTextField = " "
editableTextField = " "
createdPlayers . removeAll ( )
createdPlayers . removeAll ( )
createdPlayerIds . removeAll ( )
createdPlayerIds . removeAll ( )
if team . players ( ) . count > 1 {
if team . players ( ) . count > 1 {
dismiss ( )
dismiss ( )
} else {
} else {
editedTeam = team
editedTeam = team
team . unsortedPlayers ( ) . forEach { player in
team . unsortedPlayers ( ) . forEach { player in
createdPlayers . insert ( player )
createdPlayers . insert ( player )
createdPlayerIds . insert ( player . id )
createdPlayerIds . insert ( player . id )
}
}
}
}
}
}
private func _updateTeam ( checkDuplicates : Bool ) {
private func _updateTeam ( checkDuplicates : Bool ) {
@ -421,22 +421,14 @@ struct AddTeamView: View {
return max ( boundingRect . height + 20 , 40 ) // A d d s o m e p a d d i n g a n d s e t a m i n i m u m h e i g h t
return max ( boundingRect . height + 20 , 40 ) // A d d s o m e p a d d i n g a n d s e t a m i n i m u m h e i g h t
}
}
struct PasteStringSection : View {
@ ViewBuilder
private func _buildingTeamView ( ) -> some View {
let pasteString : String ?
@ Binding var editableTextField : String
@ Binding var textHeight : CGFloat
@ FocusState var focusedField : AddTeamView . FocusField ?
var handlePasteString : ( String ) -> Void
@ Binding var displayWarningNotEnoughCharacter : Bool
var body : some View {
if let pasteString {
if let pasteString {
Section {
Section {
TextEditor ( text : $ editableTextField )
TextEditor ( text : $ editableTextField )
. frame ( height : textHeight )
. frame ( height : textHeight )
. onChange ( of : editableTextField ) {
. onChange ( of : editableTextField ) {
textHeight = AddTeamView . _calculateHeight ( text : pasteString )
textHeight = Self . _calculateHeight ( text : pasteString )
}
}
. focused ( $ focusedField , equals : . pasteField )
. focused ( $ focusedField , equals : . pasteField )
. toolbar {
. toolbar {
@ -468,104 +460,121 @@ struct AddTeamView: View {
FooterButtonView ( " effacer le texte " ) {
FooterButtonView ( " effacer le texte " ) {
self . focusedField = nil
self . focusedField = nil
self . editableTextField = " "
self . editableTextField = " "
self . handlePasteString ( " " )
self . pasteString = nil
}
}
}
}
}
}
}
}
}
}
Section {
ForEach ( createdPlayerIds . sorted ( ) , id : \ . self ) { id in
if let p = createdPlayers . first ( where : { $0 . id = = id } ) {
VStack ( alignment : . leading , spacing : 0 ) {
if let player = unsortedPlayers . first ( where : { ( $0 . licenceId = = p . licenceId && $0 . licenceId != nil ) } ) , editedTeam ? . includes ( player : player ) = = false {
Text ( " Déjà inscrit ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerAgeInadequate ( player : p ) {
Text ( " Âge invalide ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerRankInadequate ( player : p ) {
Text ( " Trop bien classé ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
PlayerView ( player : p ) . tag ( p . id )
. environment ( tournament )
}
}
if let p = fetchPlayers . first ( where : { $0 . license = = id } ) {
VStack ( alignment : . leading , spacing : 0 ) {
if let pasteString , pasteString . isEmpty = = false , unsortedPlayers . first ( where : { $0 . licenceId = = p . license } ) != nil {
Text ( " Déjà inscrit ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerAgeInadequate ( player : p ) {
Text ( " Âge invalide ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerRankInadequate ( player : p ) {
Text ( " Trop bien classé ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
ImportedPlayerView ( player : p ) . tag ( p . license ! )
}
}
}
if editedTeam = = nil {
if createdPlayerIds . isEmpty {
RowButtonView ( " Bloquer une place " ) {
_createTeam ( checkDuplicates : false , checkHomonym : false )
}
} else {
RowButtonView ( " Ajouter l'équipe " ) {
_createTeam ( checkDuplicates : true , checkHomonym : true )
}
}
} else {
RowButtonView ( " Confirmer " ) {
_updateTeam ( checkDuplicates : false )
dismiss ( )
}
}
} header : {
let _currentSelection = _currentSelection ( )
let selectedSortedTeams = tournament . selectedSortedTeams ( )
let rank = _currentSelection . map {
$0 . computedRank
} . reduce ( 0 , + )
let teamIndex = selectedSortedTeams . firstIndex ( where : { $0 . weight >= rank } ) ? ? selectedSortedTeams . count
if _currentSelection . isEmpty = = false , tournament . hideWeight ( ) = = false , rank > 0 {
HStack ( spacing : 16.0 ) {
VStack ( alignment : . leading , spacing : 0 ) {
Text ( " Rang " ) . font ( . caption )
Text ( " # " + ( teamIndex + 1 ) . formatted ( ) )
}
@ ViewBuilder
VStack ( alignment : . leading , spacing : 0 ) {
private func _buildingTeamView ( ) -> some View {
Text ( " Poids " ) . font ( . caption )
Text ( rank . formatted ( ) )
PasteStringSection (
}
pasteString : pasteString ,
Spacer ( )
editableTextField : $ editableTextField ,
VStack ( alignment : . trailing , spacing : 0 ) {
textHeight : $ textHeight ,
Text ( " " ) . font ( . caption )
focusedField : _focusedField ,
Text ( tournament . cutLabel ( index : teamIndex , teamCount : selectedSortedTeams . count ) )
handlePasteString : handlePasteString ,
}
displayWarningNotEnoughCharacter : $ displayWarningNotEnoughCharacter
}
)
// } e l s e {
// T e x t ( " P r é p a r a t i o n d e l ' é q u i p e " )
}
}
TeamSelectionSection (
createdPlayerIds : createdPlayerIds ,
createdPlayers : createdPlayers ,
unsortedPlayers : unsortedPlayers ,
fetchPlayers : fetchPlayers ,
editedTeam : editedTeam ,
pasteString : pasteString ,
tournament : tournament ,
_createTeam : _createTeam ,
_updateTeam : _updateTeam ,
dismiss : dismiss ,
_currentSelection : _currentSelection
)
if let pasteString , pasteString . isEmpty = = false {
if let pasteString , pasteString . isEmpty = = false {
let sortedPlayers = _searchFilteredPlayers ( )
let sortedPlayers = _searchFilteredPlayers ( )
if sortedPlayers . isEmpty {
if sortedPlayers . isEmpty {
ContentUnavailableView {
ContentUnavailableView {
Label ( " Aucun résultat " , systemImage : " person.2.slash " )
Label ( " Aucun résultat " , systemImage : " person.2.slash " )
} description : {
} description : {
Text ( " Aucun joueur classé n'a été trouvé dans ce message. Attention, si un joueur n'a pas joué de tournoi dans les 12 derniers, Padel Club ne pourra pas le trouver. " )
Text ( " Aucun joueur classé n'a été trouvé dans ce message. Attention, si un joueur n'a pas joué de tournoi dans les 12 derniers, Padel Club ne pourra pas le trouver. " )
} actions : {
} actions : {
RowButtonView ( " Créer un joueur non classé " ) {
RowButtonView ( " Créer un joueur non classé " ) {
selectionSearchField = pasteString
selectionSearchField = pasteString
}
}
RowButtonView ( " Chercher dans la base " ) {
RowButtonView ( " Chercher dans la base " ) {
presentPlayerSearch = true
presentPlayerSearch = true
}
}
RowButtonView ( " Effacer cette recherche " ) {
RowButtonView ( " Effacer cette recherche " ) {
self . pasteString = nil
self . pasteString = nil
self . editableTextField = " "
self . editableTextField = " "
}
}
}
}
} else {
_listOfPlayers ( searchFilteredPlayers : sortedPlayers , pasteString : pasteString )
}
} else {
} else {
_listOfPlayers ( searchFilteredPlayers : sortedPlayers , pasteString : pasteString )
_managementView ( )
}
}
} else {
_managementView ( )
}
}
}
//
// i f l e t p a s t e S t r i n g , p a s t e S t r i n g . i s E m p t y = = f a l s e {
// l e t s o r t e d P l a y e r s = _ s e a r c h F i l t e r e d P l a y e r s ( )
//
// i f s o r t e d P l a y e r s . i s E m p t y {
// C o n t e n t U n a v a i l a b l e V i e w {
// L a b e l ( " A u c u n r é s u l t a t " , s y s t e m I m a g e : " p e r s o n . 2 . s l a s h " )
// } d e s c r i p t i o n : {
// T e x t ( " A u c u n j o u e u r c l a s s é n ' a é t é t r o u v é d a n s c e m e s s a g e . A t t e n t i o n , s i u n j o u e u r n ' a p a s j o u é d e t o u r n o i d a n s l e s 1 2 d e r n i e r s , P a d e l C l u b n e p o u r r a p a s l e t r o u v e r . " )
// } a c t i o n s : {
// R o w B u t t o n V i e w ( " C r é e r u n j o u e u r n o n c l a s s é " ) {
// s e l e c t i o n S e a r c h F i e l d = p a s t e S t r i n g
// }
//
// R o w B u t t o n V i e w ( " C h e r c h e r d a n s l a b a s e " ) {
// p r e s e n t P l a y e r S e a r c h = t r u e
// }
//
// R o w B u t t o n V i e w ( " E f f a c e r c e t t e r e c h e r c h e " ) {
// s e l f . p a s t e S t r i n g = n i l
// s e l f . e d i t a b l e T e x t F i e l d = " "
// }
// }
//
// } e l s e {
// _ l i s t O f P l a y e r s ( s e a r c h F i l t e r e d P l a y e r s : s o r t e d P l a y e r s , p a s t e S t r i n g : p a s t e S t r i n g )
// }
// } e l s e {
// _ m a n a g e m e n t V i e w ( )
// }
// }
@ MainActor
@ MainActor
func hitForSearch ( _ ip : ImportedPlayer , _ pasteString : String ? ) -> Int {
func hitForSearch ( _ ip : ImportedPlayer , _ pasteString : String ? ) -> Int {
guard let pasteString else { return 0 }
guard let pasteString else { return 0 }
@ -642,165 +651,6 @@ struct AddTeamView: View {
}
}
}
}
struct TeamSelectionSection : View {
let createdPlayerIds : Set < String >
let createdPlayers : Set < PlayerRegistration >
let unsortedPlayers : [ PlayerRegistration ]
let fetchPlayers : FetchedResults < ImportedPlayer >
let editedTeam : TeamRegistration ?
let pasteString : String ?
let tournament : Tournament
let _createTeam : ( Bool , Bool ) -> Void
let _updateTeam : ( Bool ) -> Void
let dismiss : DismissAction
let _currentSelection : ( ) -> Set < PlayerRegistration >
var body : some View {
Section {
PlayerListView ( createdPlayerIds : createdPlayerIds ,
createdPlayers : createdPlayers ,
unsortedPlayers : unsortedPlayers ,
fetchPlayers : fetchPlayers ,
editedTeam : editedTeam ,
pasteString : pasteString ,
tournament : tournament )
ActionButton ( editedTeam : editedTeam ,
createdPlayerIds : createdPlayerIds ,
_createTeam : _createTeam ,
_updateTeam : _updateTeam ,
dismiss : dismiss )
} header : {
TeamHeader ( tournament : tournament ,
_currentSelection : _currentSelection )
}
}
}
struct PlayerListView : View {
let createdPlayerIds : Set < String >
let createdPlayers : Set < PlayerRegistration >
let unsortedPlayers : [ PlayerRegistration ]
let fetchPlayers : FetchedResults < ImportedPlayer >
let editedTeam : TeamRegistration ?
let pasteString : String ?
let tournament : Tournament
var body : some View {
ForEach ( createdPlayerIds . sorted ( ) , id : \ . self ) { id in
if let p = createdPlayers . first ( where : { $0 . id = = id } ) {
CreatedPlayerView ( player : p , unsortedPlayers : unsortedPlayers , editedTeam : editedTeam , tournament : tournament )
}
if let p = fetchPlayers . first ( where : { $0 . license = = id } ) {
FetchedPlayerView ( player : p , unsortedPlayers : unsortedPlayers , pasteString : pasteString , tournament : tournament )
}
}
}
}
struct CreatedPlayerView : View {
let player : PlayerRegistration
let unsortedPlayers : [ PlayerRegistration ]
let editedTeam : TeamRegistration ?
let tournament : Tournament
var body : some View {
VStack ( alignment : . leading , spacing : 0 ) {
if let existingPlayer = unsortedPlayers . first ( where : { ( $0 . licenceId = = player . licenceId && $0 . licenceId != nil ) } ) , editedTeam ? . includes ( player : existingPlayer ) = = false {
Text ( " Déjà inscrit ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerAgeInadequate ( player : player ) {
Text ( " Âge invalide ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerRankInadequate ( player : player ) {
Text ( " Trop bien classé ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
PlayerView ( player : player ) . tag ( player . id )
. environment ( tournament )
}
}
}
struct FetchedPlayerView : View {
let player : ImportedPlayer
let unsortedPlayers : [ PlayerRegistration ]
let pasteString : String ?
let tournament : Tournament
var body : some View {
VStack ( alignment : . leading , spacing : 0 ) {
if let pasteString , pasteString . isEmpty = = false , unsortedPlayers . first ( where : { $0 . licenceId = = player . license } ) != nil {
Text ( " Déjà inscrit ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerAgeInadequate ( player : player ) {
Text ( " Âge invalide ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
if tournament . isPlayerRankInadequate ( player : player ) {
Text ( " Trop bien classé ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
ImportedPlayerView ( player : player ) . tag ( player . license ! )
}
}
}
struct ActionButton : View {
let editedTeam : TeamRegistration ?
let createdPlayerIds : Set < String >
let _createTeam : ( Bool , Bool ) -> Void
let _updateTeam : ( Bool ) -> Void
let dismiss : DismissAction
var body : some View {
if editedTeam = = nil {
if createdPlayerIds . isEmpty {
RowButtonView ( " Bloquer une place " ) {
_createTeam ( false , false )
}
} else {
RowButtonView ( " Ajouter l'équipe " ) {
_createTeam ( true , true )
}
}
} else {
RowButtonView ( " Confirmer " ) {
_updateTeam ( false )
dismiss ( )
}
}
}
}
struct TeamHeader : View {
let tournament : Tournament
let _currentSelection : ( ) -> Set < PlayerRegistration >
var body : some View {
let currentSelection = _currentSelection ( )
let selectedSortedTeams = tournament . selectedSortedTeams ( )
let rank = currentSelection . map { $0 . computedRank } . reduce ( 0 , + )
let teamIndex = selectedSortedTeams . firstIndex ( where : { $0 . weight >= rank } ) ? ? selectedSortedTeams . count
if ! currentSelection . isEmpty , ! tournament . hideWeight ( ) , rank > 0 {
HStack ( spacing : 16.0 ) {
VStack ( alignment : . leading , spacing : 0 ) {
Text ( " Rang " ) . font ( . caption )
Text ( " # " + ( teamIndex + 1 ) . formatted ( ) )
}
VStack ( alignment : . leading , spacing : 0 ) {
Text ( " Poids " ) . font ( . caption )
Text ( rank . formatted ( ) )
}
Spacer ( )
VStack ( alignment : . trailing , spacing : 0 ) {
Text ( " " ) . font ( . caption )
Text ( tournament . cutLabel ( index : teamIndex , teamCount : selectedSortedTeams . count ) )
}
}
}
}
}
let testMessages = [
let testMessages = [
" Anthony dovetta ( 3620578 K )et christophe capeau ( 4666443v) " ,
" Anthony dovetta ( 3620578 K )et christophe capeau ( 4666443v) " ,
" " "
" " "