@ -7,16 +7,15 @@
import SwiftUI
import LeStorage
import CoreData
struct AddTeamView : View {
@ EnvironmentObject var dataStore : DataStore
@ Environment ( \ . dismiss ) var dismiss
@ FetchRequest (
sortDescriptors : [ ] ,
animation : . default )
private var fetchPlayers : FetchedResults < ImportedPlayer >
private var fetchRequest : FetchRequest < ImportedPlayer >
private var fetchPlayers : FetchedResults < ImportedPlayer > { fetchRequest . wrappedValue }
var tournament : Tournament
var cancelShouldDismiss : Bool = false
@ -69,14 +68,19 @@ struct AddTeamView: View {
_createdPlayerIds = . init ( wrappedValue : createdPlayerIds )
}
let request : NSFetchRequest < ImportedPlayer > = ImportedPlayer . fetchRequest ( )
request . sortDescriptors = [ NSSortDescriptor ( keyPath : \ ImportedPlayer . rank , ascending : true ) ]
request . fetchLimit = 1000
if let pasteString {
_pasteString = . init ( wrappedValue : pasteString )
_fetchPlayers = FetchRequest < ImportedPlayer > ( sortDescriptors : [ NSSortDescriptor ( keyPath : \ ImportedPlayer . rank , ascending : true ) ] , predicate : SearchViewModel . pastePredicate ( pasteField : pasteString , mostRecentDate : tournament . rankSourceDate , filterOption : tournament . tournamentCategory . playerFilterOption ) )
request . predicate = SearchViewModel . pastePredicate ( pasteField : pasteString , mostRecentDate : tournament . rankSourceDate , filterOption : tournament . tournamentCategory . playerFilterOption )
_autoSelect = . init ( wrappedValue : true )
_editableTextField = . init ( wrappedValue : pasteString )
_textHeight = . init ( wrappedValue : Self . _calculateHeight ( text : pasteString ) )
cancelShouldDismiss = true
}
fetchRequest = FetchRequest ( fetchRequest : request , animation : . default )
}
var body : some View {
@ -138,12 +142,9 @@ struct AddTeamView: View {
} message : {
Text ( " Cette équipe existe déjà dans votre liste d'inscription. " )
}
. sheet ( isPresented : $ presentPlayerSearch , onDismiss : {
selectionSearchField = nil
} ) {
. sheet ( isPresented : $ presentPlayerSearch ) {
NavigationStack {
SelectablePlayerListView ( allowSelection : - 1 , searchField : searchField , filterOption : _filterOption ( ) , showFemaleInMaleAssimilation : tournament . tournamentCategory . showFemaleInMaleAssimilation ) { players in
selectionSearchField = nil
players . forEach { player in
let newPlayer = PlayerRegistration ( importedPlayer : player )
newPlayer . setComputedRank ( in : tournament )
@ -151,15 +152,24 @@ struct AddTeamView: View {
createdPlayerIds . insert ( newPlayer . id )
}
} contentUnavailableAction : { searchViewModel in
selectionSearchField = searchViewModel . searchText
presentPlayerSearch = false
presentPlayerCreation = true
selectionSearchField = searchViewModel . searchText
}
}
. tint ( . master )
}
. sheet ( isPresented : $ presentPlayerCreation ) {
PlayerPopoverView ( source : _searchSource ( ) , sex : _addPlayerSex ( ) ) { p in
PlayerPopoverView ( sex : _addPlayerSex ( ) ) { p in
p . setComputedRank ( in : tournament )
createdPlayers . insert ( p )
createdPlayerIds . insert ( p . id )
}
. tint ( . master )
}
. sheet ( item : $ selectionSearchField , onDismiss : {
selectionSearchField = nil
} ) { selectionSearchField in
PlayerPopoverView ( source : selectionSearchField , sex : _addPlayerSex ( ) ) { p in
p . setComputedRank ( in : tournament )
createdPlayers . insert ( p )
createdPlayerIds . insert ( p . id )
@ -235,7 +245,11 @@ struct AddTeamView: View {
Section {
RowButtonView ( " Créer un non classé / non licencié " ) {
presentPlayerCreation = true
if let pasteString , pasteString . isEmpty = = false {
selectionSearchField = pasteString
} else {
presentPlayerCreation = true
}
}
} footer : {
Text ( " Si le joueur n'a pas encore de licence ou n'a pas encore participé à une compétition, vous pouvez le créer vous-même. " )
@ -257,11 +271,7 @@ struct AddTeamView: View {
private func _filterOption ( ) -> PlayerFilterOption {
return tournament . tournamentCategory . playerFilterOption
}
private func _searchSource ( ) -> String ? {
selectionSearchField ? ? pasteString
}
private func _currentSelection ( ) -> Set < PlayerRegistration > {
var currentSelection = Set < PlayerRegistration > ( )
createdPlayerIds . compactMap { id in
@ -437,9 +447,11 @@ struct AddTeamView: View {
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 ( )
} else if tournament . isPlayerAgeInadequate ( player : p ) {
}
if tournament . isPlayerAgeInadequate ( player : p ) {
Text ( " Âge invalide ! " ) . foregroundStyle ( . logoRed ) . bold ( )
} else if tournament . isPlayerRankInadequate ( player : p ) {
}
if tournament . isPlayerRankInadequate ( player : p ) {
Text ( " Trop bien classé ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
PlayerView ( player : p ) . tag ( p . id )
@ -450,9 +462,11 @@ struct AddTeamView: View {
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 ( )
} else if tournament . isPlayerAgeInadequate ( player : p ) {
}
if tournament . isPlayerAgeInadequate ( player : p ) {
Text ( " Âge invalide ! " ) . foregroundStyle ( . logoRed ) . bold ( )
} else if tournament . isPlayerRankInadequate ( player : p ) {
}
if tournament . isPlayerRankInadequate ( player : p ) {
Text ( " Trop bien classé ! " ) . foregroundStyle ( . logoRed ) . bold ( )
}
ImportedPlayerView ( player : p ) . tag ( p . license ! )
@ -515,7 +529,7 @@ struct AddTeamView: View {
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 : {
RowButtonView ( " Créer un joueur non classé " ) {
presentPlayerCreation = true
selectionSearchField = pasteString
}
RowButtonView ( " Chercher dans la base " ) {
@ -584,16 +598,17 @@ struct AddTeamView: View {
@ MainActor
private func handlePasteString ( _ first : String ) {
if first . isEmpty = = false {
fetchPlayers . nsPredicate = SearchViewModel . pastePredicate ( pasteField : first , mostRecentDate : SourceFileManager . shared . mostRecentDateAvailable , filterOption : _filterOption ( ) )
fetchPlayers . nsSortDescriptors = [ NSSortDescriptor ( keyPath : \ ImportedPlayer . rank , ascending : true ) ]
autoSelect = true
DispatchQueue . main . async {
fetchPlayers . nsPredicate = SearchViewModel . pastePredicate ( pasteField : first , mostRecentDate : SourceFileManager . shared . mostRecentDateAvailable , filterOption : _filterOption ( ) )
fetchPlayers . nsSortDescriptors = [ NSSortDescriptor ( keyPath : \ ImportedPlayer . rank , ascending : true ) ]
autoSelect = true
}
}
pasteString = first
editableTextField = first
textHeight = Self . _calculateHeight ( text : first )
}
@ ViewBuilder
private func _listOfPlayers ( searchFilteredPlayers : [ ImportedPlayer ] , pasteString : String ) -> some View {
let sortedPlayers = _sortedPlayers ( searchFilteredPlayers : searchFilteredPlayers , pasteString : pasteString )