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.
269 lines
10 KiB
269 lines
10 KiB
//
|
|
// PlayerPopoverView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 24/03/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import PadelClubData
|
|
|
|
struct PlayerPopoverView: View {
|
|
enum PlayerCreationField {
|
|
case firstName, lastName, license, rank
|
|
}
|
|
|
|
@Environment(\.dismiss) var dismiss
|
|
|
|
@State private var displayWrongLicenceError: Bool = false
|
|
@State private var firstName: String = ""
|
|
@State private var lastName: String = ""
|
|
@State private var license: String = ""
|
|
@State private var rank: Int?
|
|
@State var sex: Int = 1
|
|
|
|
let requiredField: [PlayerCreationField]
|
|
let creationCompletionHandler: ((PlayerRegistration) -> Void)
|
|
|
|
@FocusState private var firstNameIsFocused: Bool
|
|
@FocusState private var lastNameIsFocused: Bool
|
|
@FocusState private var licenseIsFocused: Bool
|
|
@FocusState private var amountIsFocused: Bool
|
|
|
|
@State private var source: String?
|
|
|
|
init(source: String? = nil, sex: Int, requiredField: [PlayerCreationField] = [], creationCompletionHandler: @escaping (PlayerRegistration) -> Void) {
|
|
if let source {
|
|
let words = source.components(separatedBy: .whitespaces)
|
|
if words.isEmpty == false {
|
|
_firstName = State(wrappedValue: words.first?.capitalized ?? "")
|
|
|
|
if words.count > 1 {
|
|
_lastName = State(wrappedValue: words.last?.capitalized ?? "")
|
|
}
|
|
} else {
|
|
_firstName = State(wrappedValue: source)
|
|
}
|
|
|
|
_source = State(wrappedValue: source)
|
|
}
|
|
|
|
_sex = State(wrappedValue: sex)
|
|
_rank = State(wrappedValue: nil)
|
|
|
|
self.requiredField = requiredField
|
|
self.creationCompletionHandler = creationCompletionHandler
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
List {
|
|
if let source {
|
|
Section {
|
|
Text(source).foregroundColor(.clear).padding(8)
|
|
.frame(maxWidth: .infinity)
|
|
.overlay(
|
|
TextEditor(text: .constant(source))
|
|
)
|
|
.frame(minHeight: 20.0)
|
|
} header: {
|
|
HStack {
|
|
Spacer()
|
|
Button(role: .cancel) {
|
|
self.source = nil
|
|
} label: {
|
|
Text("effacer le contenu du presse-papier")
|
|
.font(.caption)
|
|
}
|
|
.buttonStyle(.borderless)
|
|
}
|
|
}
|
|
.textCase(nil)
|
|
}
|
|
Section {
|
|
Picker(selection: $sex) {
|
|
Text("Homme").tag(1 as Int)
|
|
Text("Femme").tag(0 as Int)
|
|
} label: {
|
|
|
|
}
|
|
.labelsHidden()
|
|
.pickerStyle(.segmented)
|
|
|
|
HStack {
|
|
Text("Prénom").foregroundStyle(.secondary)
|
|
Spacer()
|
|
TextField("Prénom", text: $firstName)
|
|
.submitLabel(.next)
|
|
.autocorrectionDisabled()
|
|
.keyboardType(.alphabet)
|
|
.textInputAutocapitalization(.words)
|
|
.focused($firstNameIsFocused)
|
|
.onSubmit {
|
|
firstName = firstName.trimmedMultiline
|
|
lastNameIsFocused = true
|
|
}
|
|
.fixedSize()
|
|
}
|
|
HStack {
|
|
Text("Nom").foregroundStyle(.secondary)
|
|
Spacer()
|
|
TextField("Nom", text: $lastName)
|
|
.submitLabel(.next)
|
|
.autocorrectionDisabled()
|
|
.textInputAutocapitalization(.words)
|
|
.keyboardType(.alphabet)
|
|
.focused($lastNameIsFocused)
|
|
.onSubmit {
|
|
lastName = lastName.trimmedMultiline
|
|
licenseIsFocused = true
|
|
}
|
|
.fixedSize()
|
|
}
|
|
HStack {
|
|
Text("Licence").foregroundStyle(.secondary)
|
|
Spacer()
|
|
TextField("Licence", text: $license)
|
|
.focused($licenseIsFocused)
|
|
.textInputAutocapitalization(.never)
|
|
.keyboardType(.alphabet)
|
|
.submitLabel(.next)
|
|
.onSubmit {
|
|
license = license.trimmedMultiline
|
|
if license.isEmpty == false {
|
|
if license.isLicenseNumber {
|
|
amountIsFocused = true
|
|
} else {
|
|
displayWrongLicenceError = true
|
|
}
|
|
} else {
|
|
amountIsFocused = true
|
|
}
|
|
}
|
|
.fixedSize()
|
|
}
|
|
HStack {
|
|
Text("Rang").foregroundStyle(.secondary)
|
|
Spacer()
|
|
TextField("Non Classé" + (sex == 1 ? "" : "e"), value: $rank, format: .number)
|
|
.focused($amountIsFocused)
|
|
.textInputAutocapitalization(.never)
|
|
.keyboardType(.numberPad)
|
|
.submitLabel(.done)
|
|
.fixedSize()
|
|
}
|
|
} header: {
|
|
HStack {
|
|
Spacer()
|
|
Button(role: .cancel) {
|
|
let last = firstName
|
|
firstName = lastName
|
|
lastName = last
|
|
} label: {
|
|
Text("inverser nom & prénom")
|
|
.font(.caption)
|
|
}.buttonStyle(.borderless)
|
|
}
|
|
.textCase(nil)
|
|
}
|
|
.multilineTextAlignment(.trailing)
|
|
|
|
Section {
|
|
RowButtonView("Valider et ajouter un autre") {
|
|
createManualPlayer()
|
|
lastName = ""
|
|
firstName = ""
|
|
license = ""
|
|
rank = nil
|
|
firstNameIsFocused = true
|
|
}
|
|
.disabled(isPlayerValid() == false)
|
|
}
|
|
}
|
|
.onAppear {
|
|
firstNameIsFocused = true
|
|
}
|
|
.navigationTitle(sex == 1 ? "Nouveau joueur" : "Nouvelle joueuse")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbarBackground(.visible, for: .navigationBar)
|
|
.toolbar {
|
|
ToolbarItem(placement: .confirmationAction) {
|
|
ButtonValidateView {
|
|
createManualPlayer()
|
|
dismiss()
|
|
}
|
|
.disabled(isPlayerValid() == false)
|
|
}
|
|
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Annuler", role : .cancel) {
|
|
dismiss()
|
|
}
|
|
}
|
|
|
|
if licenseIsFocused || amountIsFocused {
|
|
ToolbarItemGroup(placement: .keyboard) {
|
|
Spacer()
|
|
Button("Confirmer") {
|
|
if licenseIsFocused {
|
|
license = license.trimmedMultiline
|
|
if requiredField.contains(.license) {
|
|
if license.isLicenseNumber {
|
|
amountIsFocused = true
|
|
} else {
|
|
displayWrongLicenceError = true
|
|
}
|
|
} else {
|
|
amountIsFocused = true
|
|
}
|
|
} else {
|
|
amountIsFocused = false
|
|
}
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
}
|
|
}
|
|
}
|
|
.alert("Attention", isPresented: $displayWrongLicenceError) {
|
|
Button("OK") {
|
|
|
|
}
|
|
} message: {
|
|
Text("La licence n'est pas valide")
|
|
}
|
|
}
|
|
}
|
|
|
|
func isPlayerValid() -> Bool {
|
|
guard (lastName.isEmpty == false && requiredField.contains(.lastName)) || requiredField.contains(.lastName) == false else {
|
|
return false
|
|
}
|
|
|
|
guard (license.isEmpty == false && license.isLicenseNumber && requiredField.contains(.license)) || requiredField.contains(.license) == false else {
|
|
return false
|
|
}
|
|
|
|
guard (firstName.isEmpty == false && requiredField.contains(.firstName)) || requiredField.contains(.firstName) == false else {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func createManualPlayer() {
|
|
|
|
let playerRegistration = PlayerRegistration(
|
|
firstName: firstName.trimmedMultiline,
|
|
lastName: lastName.trimmedMultiline,
|
|
licenceId: license.trimmedMultiline.isEmpty ? nil : license,
|
|
rank: rank,
|
|
sex: PlayerSexType(rawValue: sex))
|
|
self.creationCompletionHandler(playerRegistration)
|
|
}
|
|
|
|
}
|
|
|
|
//#Preview {
|
|
// PlayerPopoverView(source: "Razmig Sarkissian", sex: 1) { player in
|
|
//
|
|
// }
|
|
//}
|
|
|