|
|
|
|
@ -23,13 +23,14 @@ struct InscriptionManagerView: View { |
|
|
|
|
@State private var presentPlayerCreation: Bool = false |
|
|
|
|
@State private var presentImportView: Bool = false |
|
|
|
|
@State private var createdPlayers: Set<PlayerRegistration> = Set() |
|
|
|
|
@State private var testCreatedPlayers: Set<String> = Set() |
|
|
|
|
@State private var createdPlayerIds: Set<String> = Set() |
|
|
|
|
@State private var editedTeam: TeamRegistration? |
|
|
|
|
@State private var pasteString: String? |
|
|
|
|
@State private var currentRankSourceDate: Date? |
|
|
|
|
@State private var confirmUpdateRank = false |
|
|
|
|
@State private var updatingRank = false |
|
|
|
|
|
|
|
|
|
@State private var selectionSearchField: String? |
|
|
|
|
|
|
|
|
|
let slideToDeleteTip = SlideToDeleteTip() |
|
|
|
|
let inscriptionManagerWomanRankTip = InscriptionManagerWomanRankTip() |
|
|
|
|
let fileTip = InscriptionManagerFileInputTip() |
|
|
|
|
@ -54,6 +55,10 @@ struct InscriptionManagerView: View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func _searchSource() -> String? { |
|
|
|
|
selectionSearchField ?? pasteString |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func _pastePredicate(pasteField: String, mostRecentDate: Date?) -> NSPredicate? { |
|
|
|
|
let text = pasteField.canonicalVersion |
|
|
|
|
|
|
|
|
|
@ -95,7 +100,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
|
|
|
|
|
private func _currentSelection() -> Set<PlayerRegistration> { |
|
|
|
|
var currentSelection = Set<PlayerRegistration>() |
|
|
|
|
testCreatedPlayers.compactMap { id in |
|
|
|
|
createdPlayerIds.compactMap { id in |
|
|
|
|
fetchPlayers.first(where: { id == $0.license }) |
|
|
|
|
}.forEach { player in |
|
|
|
|
let player = PlayerRegistration(importedPlayer: player) |
|
|
|
|
@ -103,7 +108,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
currentSelection.insert(player) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
testCreatedPlayers.compactMap { id in |
|
|
|
|
createdPlayerIds.compactMap { id in |
|
|
|
|
createdPlayers.first(where: { id == $0.id }) |
|
|
|
|
}.forEach { |
|
|
|
|
currentSelection.insert($0) |
|
|
|
|
@ -114,22 +119,22 @@ struct InscriptionManagerView: View { |
|
|
|
|
private func _createTeam() { |
|
|
|
|
tournament.addTeam(_currentSelection()) |
|
|
|
|
createdPlayers.removeAll() |
|
|
|
|
testCreatedPlayers.removeAll() |
|
|
|
|
createdPlayerIds.removeAll() |
|
|
|
|
pasteString = nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func _updateTeam() { |
|
|
|
|
editedTeam?.updatePlayers(_currentSelection()) |
|
|
|
|
createdPlayers.removeAll() |
|
|
|
|
testCreatedPlayers.removeAll() |
|
|
|
|
createdPlayerIds.removeAll() |
|
|
|
|
pasteString = nil |
|
|
|
|
editedTeam = nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func _buildingTeamView() -> some View { |
|
|
|
|
List(selection: $testCreatedPlayers) { |
|
|
|
|
List(selection: $createdPlayerIds) { |
|
|
|
|
Section { |
|
|
|
|
ForEach(testCreatedPlayers.sorted(), id: \.self) { id in |
|
|
|
|
ForEach(createdPlayerIds.sorted(), id: \.self) { id in |
|
|
|
|
if let p = createdPlayers.first(where: { $0.id == id }) { |
|
|
|
|
PlayerView(player: p).tag(p.id) |
|
|
|
|
} |
|
|
|
|
@ -143,7 +148,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if editedTeam == nil { |
|
|
|
|
if testCreatedPlayers.isEmpty { |
|
|
|
|
if createdPlayerIds.isEmpty { |
|
|
|
|
RowButtonView(title: "Bloquer une place") { |
|
|
|
|
_createTeam() |
|
|
|
|
} |
|
|
|
|
@ -169,7 +174,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
Button("effacer", role: .destructive) { |
|
|
|
|
self.pasteString = nil |
|
|
|
|
self.createdPlayers.removeAll() |
|
|
|
|
self.testCreatedPlayers.removeAll() |
|
|
|
|
self.createdPlayerIds.removeAll() |
|
|
|
|
} |
|
|
|
|
.buttonStyle(.borderless) |
|
|
|
|
} |
|
|
|
|
@ -204,7 +209,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
.onReceive(fetchPlayers.publisher.count()) { _ in // <-- here |
|
|
|
|
if let pasteString, count == 2 { |
|
|
|
|
fetchPlayers.filter { $0.hitForSearch(pasteString) >= hitTarget }.sorted(by: { $0.hitForSearch(pasteString) > $1.hitForSearch(pasteString) }).forEach { player in |
|
|
|
|
testCreatedPlayers.insert(player.license!) |
|
|
|
|
createdPlayerIds.insert(player.license!) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -307,7 +312,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
editedTeam = team |
|
|
|
|
team.unsortedPlayers().forEach { player in |
|
|
|
|
createdPlayers.insert(player) |
|
|
|
|
testCreatedPlayers.insert(player.id) |
|
|
|
|
createdPlayerIds.insert(player.id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Divider() |
|
|
|
|
@ -325,12 +330,14 @@ struct InscriptionManagerView: View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.searchable(text: $searchField, isPresented: $presentSearch, prompt: Text("Chercher parmi les équipes inscrites")) |
|
|
|
|
.keyboardType(.alphabet) |
|
|
|
|
.autocorrectionDisabled() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
VStack(spacing: 0) { |
|
|
|
|
_managementView() |
|
|
|
|
if testCreatedPlayers.isEmpty == false || pasteString != nil || editedTeam != nil { |
|
|
|
|
if createdPlayerIds.isEmpty == false || pasteString != nil || editedTeam != nil { |
|
|
|
|
_buildingTeamView() |
|
|
|
|
} else if tournament.unsortedTeams().isEmpty { |
|
|
|
|
_inscriptionTipsView() |
|
|
|
|
@ -338,22 +345,29 @@ struct InscriptionManagerView: View { |
|
|
|
|
_teamRegisteredView() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.sheet(isPresented: $presentPlayerSearch) { |
|
|
|
|
.sheet(isPresented: $presentPlayerSearch, onDismiss: { |
|
|
|
|
selectionSearchField = nil |
|
|
|
|
}) { |
|
|
|
|
NavigationStack { |
|
|
|
|
SelectablePlayerListView(allowSelection: -1, filterOption: _filterOption()) { players in |
|
|
|
|
selectionSearchField = nil |
|
|
|
|
players.forEach { player in |
|
|
|
|
let newPlayer = PlayerRegistration(importedPlayer: player) |
|
|
|
|
newPlayer.setWeight(in: tournament) |
|
|
|
|
createdPlayers.insert(newPlayer) |
|
|
|
|
testCreatedPlayers.insert(newPlayer.id) |
|
|
|
|
createdPlayerIds.insert(newPlayer.id) |
|
|
|
|
} |
|
|
|
|
} contentUnavailableAction: { searchViewModel in |
|
|
|
|
selectionSearchField = searchViewModel.searchText |
|
|
|
|
presentPlayerSearch = false |
|
|
|
|
presentPlayerCreation = true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.sheet(isPresented: $presentPlayerCreation) { |
|
|
|
|
PlayerPopoverView(sex: _addPlayerSex()) { p in |
|
|
|
|
PlayerPopoverView(source: _searchSource(), sex: _addPlayerSex()) { p in |
|
|
|
|
createdPlayers.insert(p) |
|
|
|
|
testCreatedPlayers.insert(p.id) |
|
|
|
|
createdPlayerIds.insert(p.id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.sheet(isPresented: $presentImportView) { |
|
|
|
|
@ -374,11 +388,11 @@ struct InscriptionManagerView: View { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.toolbar { |
|
|
|
|
if testCreatedPlayers.isEmpty == false { |
|
|
|
|
if createdPlayerIds.isEmpty == false { |
|
|
|
|
ToolbarItem(placement: .cancellationAction) { |
|
|
|
|
Button("Annuler", role: .cancel) { |
|
|
|
|
createdPlayers.removeAll() |
|
|
|
|
testCreatedPlayers.removeAll() |
|
|
|
|
createdPlayerIds.removeAll() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -443,7 +457,7 @@ struct InscriptionManagerView: View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.navigationBarBackButtonHidden(testCreatedPlayers.isEmpty == false) |
|
|
|
|
.navigationBarBackButtonHidden(createdPlayerIds.isEmpty == false) |
|
|
|
|
.toolbarBackground(.visible, for: .navigationBar) |
|
|
|
|
.navigationTitle("Inscriptions") |
|
|
|
|
.navigationBarTitleDisplayMode(.inline) |
|
|
|
|
|