parent
cbbf8b970b
commit
f8c4c76c47
@ -0,0 +1,241 @@ |
||||
// |
||||
// ConsolationTournamentImportView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by razmig on 27/03/2025. |
||||
// |
||||
|
||||
import SwiftUI |
||||
import LeStorage |
||||
|
||||
struct ConsolationTournamentImportView: View { |
||||
@EnvironmentObject var dataStore: DataStore |
||||
@Environment(Tournament.self) var tournament: Tournament |
||||
@Environment(\.dismiss) private var dismiss |
||||
|
||||
@State private var selectedTournament: Tournament? |
||||
@State private var selectedImportSelector: ImportSelector = .groupStage |
||||
@State private var selectedImportType: ImportType = .losers |
||||
|
||||
enum ImportType: Int, Identifiable, CaseIterable { |
||||
case losers |
||||
case winners |
||||
case all |
||||
|
||||
func importTypeLocalizedLabel() -> String { |
||||
switch self { |
||||
case .losers: |
||||
return "Perdants" |
||||
case .winners: |
||||
return "Gagnants" |
||||
case .all: |
||||
return "Tous" |
||||
} |
||||
} |
||||
|
||||
var id: Int { |
||||
self.rawValue |
||||
} |
||||
} |
||||
|
||||
|
||||
enum ImportSelector: Identifiable, Hashable { |
||||
case groupStage |
||||
case round(index: Int) |
||||
case all |
||||
|
||||
func importSelectorLocalizedLabel() -> String { |
||||
switch self { |
||||
case .groupStage: |
||||
return "Poule" |
||||
case .round(let index): |
||||
return RoundRule.roundName(fromRoundIndex: index) |
||||
case .all: |
||||
return "Tous" |
||||
} |
||||
} |
||||
|
||||
var id: String { |
||||
switch self { |
||||
case .groupStage, .all: |
||||
return String(describing: self) |
||||
case .round(let index): |
||||
return String(describing: index) |
||||
} |
||||
} |
||||
} |
||||
|
||||
var importSelectors: [ImportSelector] { |
||||
guard let selectedTournament, selectedTournament.unsortedTeams().isEmpty == false else { |
||||
return [] |
||||
} |
||||
|
||||
var _imports = [ImportSelector]() |
||||
|
||||
|
||||
if selectedTournament.groupStages().isEmpty == false { |
||||
if selectedTournament.groupStageTeams().isEmpty == false { |
||||
_imports.append(.groupStage) |
||||
} |
||||
} |
||||
|
||||
selectedTournament.rounds().forEach { round in |
||||
if round.teams().isEmpty == false { |
||||
_imports.append(.round(index: round.index)) |
||||
} |
||||
} |
||||
|
||||
_imports.append(.all) |
||||
|
||||
return _imports |
||||
} |
||||
|
||||
var tournaments: [Tournament] { |
||||
dataStore.tournaments.filter({ $0.isDeleted == false && $0.id != tournament.id }).sorted(by: \.startDate, order: .descending) |
||||
} |
||||
|
||||
var body: some View { |
||||
List { |
||||
Picker(selection: $selectedTournament) { |
||||
Text("Aucun tournoi").tag(nil as Tournament?) |
||||
ForEach(tournaments) { tournament in |
||||
TournamentCellView(tournament: tournament).tag(tournament) |
||||
} |
||||
} label: { |
||||
if selectedTournament == nil { |
||||
Text("Choisir la source") |
||||
} else { |
||||
EmptyView() |
||||
} |
||||
} |
||||
.pickerStyle(.navigationLink) |
||||
|
||||
let importSelectors = importSelectors |
||||
|
||||
if let selectedTournament { |
||||
if importSelectors.isEmpty == false { |
||||
Section { |
||||
Picker(selection: $selectedImportSelector) { |
||||
ForEach(importSelectors) { importSelector in |
||||
Text(importSelector.importSelectorLocalizedLabel()) |
||||
.tag(importSelector) |
||||
} |
||||
} label: { |
||||
Text("Équipes") |
||||
} |
||||
|
||||
if selectedImportSelector != .all { |
||||
Picker(selection: $selectedImportType) { |
||||
ForEach(ImportType.allCases) { importType in |
||||
Text(importType.importTypeLocalizedLabel()) |
||||
.tag(importType) |
||||
} |
||||
} label: { |
||||
Text("Type") |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
let unsortedTeams = tournament.unsortedTeams() |
||||
let onlineTeams = unsortedTeams.filter({ $0.hasRegisteredOnline() }) |
||||
if unsortedTeams.count > 0 { |
||||
Section { |
||||
RowButtonView("Effacer les équipes actuelles", role: .destructive) { |
||||
await _deleteTeams(teams: unsortedTeams) |
||||
} |
||||
.disabled(onlineTeams.isEmpty == false) |
||||
} footer: { |
||||
if onlineTeams.isEmpty == false { |
||||
Text("Ce tournoi contient des inscriptions en ligne, vous ne pouvez pas effacer toute votre liste d'inscription d'un coup.") |
||||
} |
||||
} |
||||
} |
||||
|
||||
let teams = _teamsToImport(selectedTournament: selectedTournament) |
||||
|
||||
Section { |
||||
RowButtonView("Importer les équipes") { |
||||
await _importTeams(selectedTournament: selectedTournament, teams: teams) |
||||
dismiss() |
||||
} |
||||
.disabled(teams.isEmpty) |
||||
} footer: { |
||||
if teams.isEmpty { |
||||
Text("Aucune équipe détectée").foregroundStyle(.logoRed) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.onChange(of: selectedTournament) { |
||||
selectedImportSelector = importSelectors.first ?? .groupStage |
||||
selectedImportType = .losers |
||||
} |
||||
.navigationTitle("Importation") |
||||
.navigationBarTitleDisplayMode(.inline) |
||||
.toolbarBackground(.visible, for: .navigationBar) |
||||
} |
||||
|
||||
private func _teamsToImport(selectedTournament: Tournament) -> [TeamRegistration] { |
||||
var teams = [TeamRegistration]() |
||||
switch selectedImportSelector { |
||||
case .all: |
||||
teams = selectedTournament.unsortedTeams() |
||||
case .groupStage: |
||||
teams = selectedTournament.groupStageTeams().filter({ |
||||
switch selectedImportType { |
||||
case .losers: |
||||
return $0.qualified == false |
||||
case .winners: |
||||
return $0.qualified |
||||
case .all: |
||||
return true |
||||
} |
||||
}) |
||||
|
||||
|
||||
case .round(let index): |
||||
if let round = selectedTournament.rounds().filter({ $0.index == index }).first { |
||||
if selectedImportType == .all { |
||||
teams = round.teams() |
||||
} else { |
||||
teams = round.playedMatches().compactMap({ match in |
||||
if selectedImportType == .losers { |
||||
return match.loser() |
||||
} else if selectedImportType == .winners { |
||||
return match.winner() |
||||
} else { |
||||
return nil |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
return teams |
||||
} |
||||
|
||||
private func _importTeams(selectedTournament: Tournament, teams: [TeamRegistration]) async { |
||||
let teamHolders = teams.map { team in |
||||
let players = team.players().map { player in |
||||
let playerCopy = PlayerRegistration(firstName: player.firstName, lastName: player.lastName, licenceId: player.licenceId, rank: player.rank, sex: player.sex, tournamentPlayed: player.tournamentPlayed, points: player.points, clubName: player.clubName, ligueName: player.ligueName, assimilation: player.assimilation, phoneNumber: player.phoneNumber, email: player.email, birthdate: player.birthdate, computedRank: player.computedRank, source: player.source, hasArrived: false) |
||||
return playerCopy |
||||
} |
||||
|
||||
let teamHolder = FileImportManager.TeamHolder.init(players: players, tournamentCategory: tournament.category, tournamentAgeCategory: tournament.federalAgeCategory, previousTeam: tournament.findTeam(players), registrationDate: Date(), name: team.name, tournament: tournament) |
||||
|
||||
return teamHolder |
||||
} |
||||
|
||||
tournament.rankSourceDate = selectedTournament.rankSourceDate |
||||
dataStore.tournaments.addOrUpdate(instance: tournament) |
||||
tournament.importTeams(teamHolders) |
||||
} |
||||
|
||||
private func _deleteTeams(teams: [TeamRegistration]) async { |
||||
await MainActor.run { |
||||
tournament.tournamentStore?.teamRegistrations.delete(contentOfs: teams) |
||||
} |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue