sync2
Raz 9 months ago
parent 6e31435840
commit 738b79bf9c
  1. 5
      PadelClub/Data/Federal/FederalTournamentHolder.swift
  2. 4
      PadelClub/Data/Tournament.swift
  3. 32
      PadelClub/ViewModel/SearchViewModel.swift
  4. 71
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  5. 3
      PadelClub/Views/Tournament/Screen/AddTeamView.swift
  6. 17
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift
  7. 4
      PadelClub/Views/Tournament/TournamentInscriptionView.swift

@ -19,14 +19,9 @@ protocol FederalTournamentHolder {
var dayPeriod: DayPeriod { get }
func tournamentTitle(_ displayStyle: DisplayStyle, forBuild build: any TournamentBuildHolder) -> String
func displayAgeAndCategory(forBuild build: any TournamentBuildHolder) -> Bool
func togglePrivate(isPrivate: Bool)
}
extension FederalTournamentHolder {
func togglePrivate(isPrivate: Bool) {
}
func durationLabel() -> String {
switch dayDuration {
case 1:

@ -2680,10 +2680,6 @@ extension Tournament: Hashable {
}
extension Tournament: FederalTournamentHolder {
func togglePrivate(isPrivate: Bool) {
self.isPrivate = isPrivate
}
func tournamentTitle(_ displayStyle: DisplayStyle, forBuild build: any TournamentBuildHolder) -> String {
if isAnimation() {
if let name {

@ -356,6 +356,17 @@ class SearchViewModel: ObservableObject, Identifiable {
static func pastePredicate(pasteField: String, mostRecentDate: Date?, filterOption: PlayerFilterOption) -> NSPredicate? {
var andPredicates = [NSPredicate]()
var orPredicates = [NSPredicate]()
let matches = pasteField.licencesFound()
let licensesPredicates = matches.map { NSPredicate(format: "license contains[cd] %@", $0) }
orPredicates = licensesPredicates
if matches.count == 2 {
return NSCompoundPredicate(orPredicateWithSubpredicates: orPredicates)
}
let allowedCharacterSet = CharacterSet.alphanumerics.union(.whitespaces)
// Remove all characters that are not in the allowedCharacterSet
@ -369,14 +380,8 @@ class SearchViewModel: ObservableObject, Identifiable {
let textStrings: [String] = text.components(separatedBy: .whitespacesAndNewlines)
let nonEmptyStrings: [String] = textStrings.compactMap { $0.isEmpty ? nil : $0 }
let nameComponents = nonEmptyStrings.filter({ $0 != "de" && $0 != "la" && $0 != "le" && $0.count > 1 })
var andPredicates = [NSPredicate]()
var orPredicates = [NSPredicate]()
//self.wordsCount = nameComponents.count
if let slashPredicate = getSpecialSlashPredicate(inputString: pasteField) {
orPredicates.append(slashPredicate)
}
//self.wordsCount = nameComponents.count
if filterOption == .female {
andPredicates.append(NSPredicate(format: "male == NO"))
}
@ -385,12 +390,21 @@ class SearchViewModel: ObservableObject, Identifiable {
andPredicates.append(NSPredicate(format: "importDate == %@", mostRecentDate as CVarArg))
}
if let slashPredicate = getSpecialSlashPredicate(inputString: pasteField) {
orPredicates.append(slashPredicate)
}
print("nameComponents", nameComponents.count)
if nameComponents.count < 50 {
if nameComponents.count > 1 {
orPredicates.append(contentsOf: nameComponents.pairs().map {
return NSPredicate(format: "(firstName BEGINSWITH[cd] %@ AND lastName BEGINSWITH[cd] %@) OR (firstName BEGINSWITH[cd] %@ AND lastName BEGINSWITH[cd] %@)", $0, $1, $1, $0) })
} else {
orPredicates.append(contentsOf: nameComponents.map { NSPredicate(format: "firstName contains[cd] %@ OR lastName contains[cd] %@", $0,$0) })
}
}
let components = text.split(separator: " ")
let pattern = components.joined(separator: ".*")
@ -398,10 +412,6 @@ class SearchViewModel: ObservableObject, Identifiable {
let canonicalFullNamePredicate = NSPredicate(format: "canonicalFullName MATCHES[c] %@", pattern)
orPredicates.append(canonicalFullNamePredicate)
let matches = pasteField.licencesFound()
let licensesPredicates = matches.map { NSPredicate(format: "license contains[cd] %@", $0) }
orPredicates = orPredicates + licensesPredicates
var predicate = NSCompoundPredicate(andPredicateWithSubpredicates: andPredicates)
if orPredicates.isEmpty == false {

@ -92,9 +92,35 @@ struct EventListView: View {
private func _menuOptions(_ pcTournaments: [Tournament]) -> some View {
Menu {
_options(pcTournaments)
} label: {
Text("Options rapides pour ce mois")
.underline()
}
}
@ViewBuilder
private func _options(_ pcTournaments: [Tournament]) -> some View {
Section {
if pcTournaments.anySatisfy({ $0.isPrivate == true }) {
Button {
pcTournaments.forEach { tournament in
tournament.isPrivate = false
}
do {
try dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments)
} catch {
Logger.error(error)
}
} label: {
Text("Afficher ce\(pcTournaments.count.pluralSuffix) tournoi\(pcTournaments.count.pluralSuffix) sur Padel Club")
}
}
if pcTournaments.anySatisfy({ $0.isPrivate == false }) {
Button {
pcTournaments.forEach { tournament in
tournament.togglePrivate(isPrivate: false)
tournament.isPrivate = true
}
do {
try dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments)
@ -102,11 +128,19 @@ struct EventListView: View {
Logger.error(error)
}
} label: {
Text("Afficher ces tournois sur Padel Club")
Text("Masquer ce\(pcTournaments.count.pluralSuffix) tournoi\(pcTournaments.count.pluralSuffix) sur Padel Club")
}
}
} header: {
Text("Visibilité sur Padel Club")
}
Divider()
if pcTournaments.anySatisfy({ $0.hasEnded() == false && $0.enableOnlineRegistration == false && $0.onlineRegistrationCanBeEnabled() }) || pcTournaments.anySatisfy({ $0.enableOnlineRegistration == true }) {
Section {
if pcTournaments.anySatisfy({ $0.hasEnded() == false && $0.enableOnlineRegistration == false && $0.onlineRegistrationCanBeEnabled() }) {
Button {
pcTournaments.forEach { tournament in
tournament.togglePrivate(isPrivate: true)
tournament.enableOnlineRegistration = true
}
do {
try dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments)
@ -114,13 +148,27 @@ struct EventListView: View {
Logger.error(error)
}
} label: {
Text("Masquer ces tournois sur Padel Club")
Text("Activer l'inscription en ligne")
}
}
if pcTournaments.anySatisfy({ $0.enableOnlineRegistration == true }) {
Button {
pcTournaments.forEach { tournament in
tournament.enableOnlineRegistration = false
}
do {
try dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments)
} catch {
Logger.error(error)
}
} label: {
Text("Gérer la visibilité sur Padel Club")
.font(.caption)
.underline()
Text("Désactiver l'inscription en ligne")
}
}
} header: {
Text("Inscription en ligne")
}
}
}
@ -160,13 +208,20 @@ struct EventListView: View {
NavigationLink(value: tournament) {
TournamentCellView(tournament: tournament, shouldTournamentBeOver: tournament.shouldTournamentBeOver())
}
.listRowView(isActive: tournament.enableOnlineRegistration, color: .green, hideColorVariation: true)
.contextMenu {
if tournament.hasEnded() == false {
Button {
navigation.openTournamentInOrganizer(tournament)
} label: {
Label("Voir dans le gestionnaire", systemImage: "line.diagonal.arrow")
Label("Afficher dans le gestionnaire", systemImage: "line.diagonal.arrow")
}
Divider()
_options([tournament])
}
}
#if DEBUG

@ -620,15 +620,12 @@ struct AddTeamView: View {
return 1
}
@MainActor
private func handlePasteString(_ first: String) {
if first.isEmpty == false {
DispatchQueue.main.async {
fetchPlayers.nsPredicate = SearchViewModel.pastePredicate(pasteField: first, mostRecentDate: SourceFileManager.shared.mostRecentDateAvailable, filterOption: _filterOption())
fetchPlayers.nsSortDescriptors = [NSSortDescriptor(keyPath: \ImportedPlayer.rank, ascending: true)]
autoSelect = true
}
}
pasteString = first
editableTextField = first
textHeight = Self._calculateHeight(text: first)

@ -141,17 +141,18 @@ struct RegistrationSetupView: View {
}
Section {
Toggle(isOn: $targetTeamCountEnabled) {
Text("Activer une limite")
}
if targetTeamCountEnabled {
// Toggle(isOn: $targetTeamCountEnabled) {
// Text("Activer une limite")
// }
//
// if targetTeamCountEnabled {
// StepperView(count: $targetTeamCount, minimum: 4)
// }
StepperView(count: $targetTeamCount, minimum: 4)
}
} header: {
Text("Paires admises")
} footer: {
Text("Si une limite de paire existe, les inscriptions seront indiqués en attente pour les joueurs au-délà de cette limite dans le cas où aucune limite de liste d'attente n'est active ou non atteinte. Dans le cas contraire, plus aucune inscription ne seront possibles.")
Text("Les inscriptions seront indiqués en attente pour les joueurs au-délà de cette limite dans le cas où aucune limite de liste d'attente n'est active ou non atteinte. Dans le cas contraire, plus aucune inscription ne seront possibles.")
}
Section {
@ -160,7 +161,7 @@ struct RegistrationSetupView: View {
}
if waitingListLimitEnabled {
StepperView(count: $waitingListLimit, minimum: 1)
StepperView(count: $waitingListLimit, minimum: 0)
}
} header: {
Text("Liste d'attente")

@ -21,6 +21,10 @@ struct TournamentInscriptionView: View {
Text("Gestion des inscriptions")
if let closedRegistrationDate = tournament.closedRegistrationDate {
Text("clôturé le " + closedRegistrationDate.formatted(date: .abbreviated, time: .shortened))
} else if tournament.enableOnlineRegistration {
Text("Inscription en ligne activée")
} else if tournament.onlineRegistrationCanBeEnabled() {
Text("Inscription en ligne désactivée")
}
}
}

Loading…
Cancel
Save