You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
PadelClub/PadelClub/Views/Navigation/Umpire/PadelClubView.swift

270 lines
11 KiB

//
// PadelClubView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 01/03/2024.
//
import SwiftUI
import LeStorage
struct PadelClubView: View {
@State private var uuid: UUID = UUID()
@State private var checkingFilesAttempt: Int = 0
@State private var checkingFiles: Bool = false
@EnvironmentObject var dataStore: DataStore
var lastDataSource: String? {
dataStore.appSettings.lastDataSource
}
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [],
animation: .default)
private var players: FetchedResults<ImportedPlayer>
var _mostRecentDateAvailable: Date? {
SourceFileManager.shared.mostRecentDateAvailable
}
var _lastDataSourceDate: Date? {
guard let lastDataSource else { return nil }
return URL.importDateFormatter.date(from: lastDataSource)
}
var body: some View {
List {
let monthData = dataStore.monthData.sorted(by: \.creationDate).reversed()
if let currentMonth = monthData.first, currentMonth.incompleteMode {
Section {
Text("Attention, depuis Août 2024, les données fédérales publiques des joueurs (messieurs) récupérables sont incomplètes car limité au 40.000 premiers joueurs. Le rang d'un joueur non-classé n'est donc pas calculable pour le moment, Padel Club utilisera une valeur par défaut de de 60.000.")
Text("Un classement souligné comme ci-dessous indiquera que l'information provient d'un mois précédent.")
Text("10342ème")
.background {
UnderlineView()
}
}
}
#if DEBUG
/*
["36435", "BOUNOUA", "walid", "France", "3311600", "15,00", "Non", "2", "AUVERGNE RHONE-ALPES", "50 73 0046", "CHAMBERY TC"]
["36435", "BRUL", "Romain", "France", "2993139", "15,00", "Non", "2", "NOUVELLE AQUITAINE", "59 33 0447", "SAINT LOUBES TC"]
*/
Section {
RowButtonView("Exporter en csv") {
for fileURL in SourceFileManager.shared.jsonFiles() {
let decoder = JSONDecoder()
decoder.userInfo[.maleData] = fileURL.manData
do {
let data = try Data(contentsOf: fileURL)
let players = try decoder.decode([FederalPlayer].self, from: data)
var anonymousPlayers = players.filter { $0.firstName.isEmpty && $0.lastName.isEmpty }
let okPlayers = players.filter { $0.firstName.isEmpty == false && $0.lastName.isEmpty == false }
print("before anonymousPlayers.count", anonymousPlayers.count)
FileImportManager.shared.updatePlayers(isMale: fileURL.manData, players: &anonymousPlayers)
print("after anonymousPlayers.count", anonymousPlayers.filter { $0.firstName.isEmpty && $0.lastName.isEmpty }
.count)
SourceFileManager.shared.exportToCSV(players: okPlayers + anonymousPlayers, sourceFileType: fileURL.manData ? .messieurs : .dames, date: fileURL.dateFromPath)
} catch {
Logger.error(error)
}
}
}
}
#endif
if let _lastDataSourceDate {
Section {
LabeledContent {
Image(systemName: "checkmark")
} label: {
Text(_lastDataSourceDate.monthYearFormatted)
Text("Classement mensuel utilisé")
}
} footer: {
FooterButtonView("Ré-importer") {
_startImporting()
}
}
if let mostRecentDateAvailable = SourceFileManager.shared.mostRecentDateAvailable, _lastDataSourceDate.isEarlierThan(mostRecentDateAvailable), FileImportManager.shared.isImportingFile() == false {
Section {
RowButtonView("Importer \(mostRecentDateAvailable.monthYearFormatted)") {
_startImporting()
}
}
}
}
Section {
RowButtonView("Télécharger les données précédentes", role: .destructive) {
await _downloadPreviousDate()
}
} footer: {
Text("Padel Club va récupérer les données des mois précédents")
}
if FileImportManager.shared.isImportingFile() {
ContentUnavailableView("Importation en cours", systemImage: "server.rack", description: Text("Une importation des données fédérales publiques est en cours, veuillez patienter."))
} else if (players.isEmpty || lastDataSource == nil) {
ContentUnavailableView {
Label("Aucun joueur importé", systemImage: "person.slash")
} description: {
Text("Padel Club peut importer toutes les données publiques de la FFT concernant tous les compétiteurs et compétitrices.")
} actions: {
if let _mostRecentDateAvailable {
RowButtonView("Importer \(_mostRecentDateAvailable.monthYearFormatted)") {
_startImporting()
}
}
}
}
ForEach(monthData) { monthData in
Section {
LabeledContent {
if let maleCount = monthData.maleCount {
Text(maleCount.formatted())
}
} label: {
Text("Messieurs")
}
LabeledContent {
if let femaleCount = monthData.femaleCount {
Text(femaleCount.formatted())
}
} label: {
Text("Dames")
}
if monthData.incompleteMode {
LabeledContent {
if let anonymousCount = monthData.anonymousCount {
Text(anonymousCount.formatted())
}
} label: {
Text("Joueurs anonymes")
}
}
LabeledContent {
if let maleUnrankedValue = monthData.maleUnrankedValue {
Text(maleUnrankedValue.formatted())
}
} label: {
Text("Rang d'un non classé")
if monthData.incompleteMode {
Text("Messieurs (estimation car incomplet)")
} else {
Text("Messieurs")
}
}
LabeledContent {
if let femaleUnrankedValue = monthData.femaleUnrankedValue {
Text(femaleUnrankedValue.formatted())
}
} label: {
Text("Rang d'une non classée")
Text("Dames")
}
} header: {
HStack {
Text(monthData.monthKey)
Spacer()
Text(monthData.total().formatted() + " joueurs")
}
} footer: {
HStack {
Spacer()
FooterButtonView("recalculer") {
Task {
if let monthKeyDate = URL.importDateFormatter.date(from: monthData.monthKey) {
await MonthData.calculateCurrentUnrankedValues(fromDate: monthKeyDate)
}
}
}
}
}
}
}
.id(uuid)
.task {
await self._checkSourceFileAvailability()
}
.refreshable {
Task {
await self._checkSourceFileAvailability()
}
}
.headerProminence(.increased)
.navigationTitle("Données fédérales")
}
@ViewBuilder
func _activityStatus() -> some View {
if checkingFiles || FileImportManager.shared.isImportingFile() {
HStack(spacing: 20) {
ProgressView()
Text(FileImportManager.shared.currentlyImportingLabel())
}
} else if let _mostRecentDateAvailable {
if _mostRecentDateAvailable > _lastDataSourceDate ?? .distantPast {
Text(_mostRecentDateAvailable.monthYearFormatted + " disponible à l'importation")
} else {
Label(_mostRecentDateAvailable.monthYearFormatted, systemImage: "checkmark").labelStyle(.titleAndIcon)
}
} else {
Text("Aucune donnée disponible")
}
}
private func _checkSourceFileAvailability() async {
print("check internet")
print("check files on internet")
print("check if any files on internet are more recent than here")
checkingFiles = true
await SourceFileManager.shared.fetchData()
checkingFilesAttempt += 1
checkingFiles = false
uuid = UUID()
}
private func _startImporting() {
let importingDate = SourceFileManager.shared.mostRecentDateAvailable
FileImportManager.shared.currentImportDate = importingDate
Task {
if let importingDate {
let lastDataSource = await FileImportManager.shared.importDataFromFFT(importingDate: importingDate)
dataStore.appSettings.lastDataSource = lastDataSource
dataStore.appSettingsStorage.write()
if let lastDataSource, let mostRecentDate = URL.importDateFormatter.date(from: lastDataSource) {
await MonthData.calculateCurrentUnrankedValues(fromDate: mostRecentDate)
}
viewContext.refreshAllObjects()
}
await MainActor.run {
FileImportManager.shared.currentImportDate = nil
}
}
}
private func _downloadPreviousDate() async {
await SourceFileManager.shared.getAllFiles(initialDate: "08-2022")
self.uuid = UUID()
}
}
//#Preview {
// PadelClubView()
//}