|
|
|
|
@ -9,6 +9,51 @@ import SwiftUI |
|
|
|
|
import TipKit |
|
|
|
|
import LeStorage |
|
|
|
|
|
|
|
|
|
enum FileImportCustomField: Int, Identifiable, CaseIterable { |
|
|
|
|
var id: Int { self.rawValue } |
|
|
|
|
|
|
|
|
|
case sexType |
|
|
|
|
case teamName |
|
|
|
|
case lastName |
|
|
|
|
case firstName |
|
|
|
|
case rank |
|
|
|
|
case licenceId |
|
|
|
|
case clubName |
|
|
|
|
|
|
|
|
|
func columnLabel() -> String { |
|
|
|
|
let columnIndex: Int = self.rawValue + 1 |
|
|
|
|
return columnIndex.formatted() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func descriptionLabel() -> String? { |
|
|
|
|
switch self { |
|
|
|
|
case .sexType: |
|
|
|
|
return "f ou m" |
|
|
|
|
default: |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func localizedLabel() -> String { |
|
|
|
|
switch self { |
|
|
|
|
case .sexType: |
|
|
|
|
return "Sexe" |
|
|
|
|
case .teamName: |
|
|
|
|
return "Nom de l'équipe" |
|
|
|
|
case .lastName: |
|
|
|
|
return "Nom" |
|
|
|
|
case .firstName: |
|
|
|
|
return "Prénom" |
|
|
|
|
case .rank: |
|
|
|
|
return "Rang" |
|
|
|
|
case .licenceId: |
|
|
|
|
return "Licence" |
|
|
|
|
case .clubName: |
|
|
|
|
return "Nom du club" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct FileImportView: View { |
|
|
|
|
@EnvironmentObject var dataStore: DataStore |
|
|
|
|
@Environment(Tournament.self) var tournament: Tournament |
|
|
|
|
@ -29,6 +74,7 @@ struct FileImportView: View { |
|
|
|
|
@State private var fileProvider: FileImportManager.FileProvider = .frenchFederation |
|
|
|
|
@State private var validationInProgress: Bool = false |
|
|
|
|
@State private var multiImport: Bool = false |
|
|
|
|
@State private var presentFormatHelperView: Bool = false |
|
|
|
|
|
|
|
|
|
private func filteredTeams(tournament: Tournament) -> [FileImportManager.TeamHolder] { |
|
|
|
|
return teams.filter { $0.tournamentCategory == tournament.tournamentCategory }.sorted(by: \.weight) |
|
|
|
|
@ -83,6 +129,10 @@ struct FileImportView: View { |
|
|
|
|
if fileProvider == .frenchFederation { |
|
|
|
|
let footerString = "Fichier provenant de [beach-padel.app.fft.fr](\(URLs.beachPadel.rawValue))" |
|
|
|
|
Text(.init(footerString)) |
|
|
|
|
} else if fileProvider == .custom { |
|
|
|
|
FooterButtonView("Voir le format du fichier") { |
|
|
|
|
presentFormatHelperView = true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -228,6 +278,43 @@ struct FileImportView: View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.navigationBarTitleDisplayMode(.inline) |
|
|
|
|
.toolbarBackground(.visible, for: .navigationBar) |
|
|
|
|
.sheet(isPresented: $presentFormatHelperView) { |
|
|
|
|
NavigationStack { |
|
|
|
|
List { |
|
|
|
|
Section { |
|
|
|
|
Text("Créer un fichier xls, xlsx ou csv qui contient les colonnes suivantes.") |
|
|
|
|
Text("Chaque ligne correspond à un joueur, et chaque groupe de deux lignes correspond à une équipe.") |
|
|
|
|
Text("Aucune valeur n'est obligatoire.") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Section { |
|
|
|
|
ForEach(FileImportCustomField.allCases) { fileImportCustomField in |
|
|
|
|
LabeledContent { |
|
|
|
|
Text(fileImportCustomField.localizedLabel()) |
|
|
|
|
} label: { |
|
|
|
|
Text("Colonne \(fileImportCustomField.columnLabel())") |
|
|
|
|
if let descriptionLabel = fileImportCustomField.descriptionLabel() { |
|
|
|
|
Text(descriptionLabel) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.navigationTitle("Description du format") |
|
|
|
|
.navigationBarTitleDisplayMode(.inline) |
|
|
|
|
.toolbarBackground(.visible, for: .navigationBar) |
|
|
|
|
.toolbar { |
|
|
|
|
ToolbarItem(placement: .topBarLeading) { |
|
|
|
|
Button("Fermer") { |
|
|
|
|
presentFormatHelperView = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.tint(.master) |
|
|
|
|
} |
|
|
|
|
.fileImporter(isPresented: $isShowing, allowedContentTypes: [.spreadsheet, .commaSeparatedText, .text], allowsMultipleSelection: false, onCompletion: { results in |
|
|
|
|
|
|
|
|
|
switch results { |
|
|
|
|
|