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