online_reg
Raz 10 months ago
parent d11af504b5
commit 15870383e0
  1. 10
      PadelClub/Data/PlayerRegistration.swift
  2. 4
      PadelClub/Data/Tournament.swift
  3. 24
      PadelClub/InscriptionLegendView.swift
  4. 8
      PadelClub/RegistrationInfoSheetView.swift
  5. 18
      PadelClub/Views/Player/PlayerDetailView.swift
  6. 2
      PadelClub/Views/Shared/DateMenuView.swift
  7. 97
      PadelClub/Views/Shared/SelectablePlayerListView.swift
  8. 4
      PadelClub/Views/Team/EditingTeamView.swift
  9. 10
      PadelClub/Views/Team/TeamDetailView.swift
  10. 5
      PadelClub/Views/Team/TeamRowView.swift
  11. 3
      PadelClub/Views/Tournament/Screen/Components/TournamentCategorySettingsView.swift
  12. 38
      PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift
  13. 36
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  14. 4
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift
  15. 4
      PadelClub/Views/Tournament/TournamentView.swift

@ -45,11 +45,11 @@ final class PlayerRegistration: ModelObject, Storable {
func localizedSourceLabel() -> String {
switch source {
case .frenchFederation, .onlineRegistration:
return "Via la base fédérale"
return "base fédérale"
case .beachPadel:
return "Via le fichier beach-padel"
return "beach-padel"
case nil:
return "Manuellement"
return "créé par vous-même"
}
}
@ -233,6 +233,10 @@ final class PlayerRegistration: ModelObject, Storable {
source == .beachPadel
}
func unrankedOrUnknown() -> Bool {
source == nil
}
func isValidLicenseNumber(year: Int) -> Bool {
guard let licenceId else { return false }
guard licenceId.isLicenseNumber else { return false }

@ -2165,6 +2165,10 @@ defer {
}
}
func onlineRegistrationCanBeEnabled() -> Bool {
isAnimation() == false
}
func roundSmartMatchFormat(_ roundIndex: Int) -> MatchFormat {
let format = tournamentLevel.federalFormatForBracketRound(roundIndex)
if tournamentLevel == .p25 { return .superTie }

@ -13,38 +13,38 @@ struct InscriptionLegendView: View {
var body: some View {
NavigationView {
List {
Section {
Label("Inscrit en ligne", systemImage: "circle.fill").foregroundStyle(.green)
} footer: {
Text("Icône indiquant que le joueur s'est inscrit en ligne.")
}
Section {
ForEach(RoundRule.colors.prefix(6).indices, id: \.self) { colorIndex in
Text("Équipe placée en \(RoundRule.roundName(fromRoundIndex: colorIndex))")
.listRowView(isActive: true, color: Color(uiColor: .init(fromHex: RoundRule.colors[colorIndex])), hideColorVariation: true, alignment: .trailing)
.listRowView(isActive: true, color: Color(uiColor: .init(fromHex: RoundRule.colors[colorIndex])), hideColorVariation: true, alignment: .leading)
}
}
Section {
Text("Équipe placée en poule")
.listRowView(isActive: true, color: .blue, hideColorVariation: true, alignment: .trailing)
.listRowView(isActive: true, color: .blue, hideColorVariation: true, alignment: .leading)
}
Section {
Text("Équipe estimée en tableau")
.listRowView(isActive: true, color: .mint, hideColorVariation: true, alignment: .trailing)
.listRowView(isActive: true, color: .mint, hideColorVariation: true, alignment: .leading)
Text("Équipe estimée en poule")
.listRowView(isActive: true, color: .cyan, hideColorVariation: true, alignment: .trailing)
.listRowView(isActive: true, color: .cyan, hideColorVariation: true, alignment: .leading)
}
Section {
Text("Équipe en liste d'attente")
.listRowView(isActive: true, color: .gray, hideColorVariation: true, alignment: .trailing)
.listRowView(isActive: true, color: .gray, hideColorVariation: true, alignment: .leading)
Text("Équipe forfaite")
.listRowView(isActive: true, color: .logoRed, hideColorVariation: true, alignment: .trailing)
}
Section {
Label("Inscrit en ligne", systemImage: "person.badge.shield.checkmark.fill")
} footer: {
Text("Icône indiquant que le joueur s'est inscrit en ligne.")
.listRowView(isActive: true, color: .logoRed, hideColorVariation: true, alignment: .leading)
}
Section {

@ -45,12 +45,6 @@ struct RegistrationInfoSheetView: View {
NavigationView {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
// Title
Text("Inscriptions en ligne")
.font(.title)
.fontWeight(.bold)
.padding(.bottom, 5)
// Content sections
ForEach(registrationInfoText.components(separatedBy: "\n\n"), id: \.self) { section in
if !section.isEmpty {
@ -84,6 +78,8 @@ struct RegistrationInfoSheetView: View {
.navigationBarItems(trailing: Button("Fermer") {
dismiss()
})
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle("Inscription en ligne")
}
}
}

@ -32,6 +32,22 @@ struct PlayerDetailView: View {
var body: some View {
Form {
Section {
Text(player.localizedSourceLabel().firstCapitalized)
} header: {
Text("Source des informations")
}
if tournament.enableOnlineRegistration {
Section {
LabeledContent {
Text(player.registeredOnline ? "Oui" : "Non")
} label: {
Text("Inscription en ligne")
}
}
}
Section {
Toggle("Joueur sur place", isOn: $player.hasArrived)
Toggle("Capitaine", isOn: $player.captain)
@ -70,8 +86,6 @@ struct PlayerDetailView: View {
if let birthdate = player.birthdate {
Text(birthdate)
}
} footer: {
Text(player.localizedSourceLabel())
}
Section {

@ -26,7 +26,7 @@ struct DateMenuView: View {
Button("24h après") { adjustDate(byDays: 1) }
Button("48h après") { adjustDate(byDays: 2) }
} label: {
Text("Ajuster la date")
Text("Ajuster")
.underline()
}
}

@ -379,102 +379,7 @@ struct MySearchView: View {
let array = Array(searchViewModel.selectedPlayers)
Section {
ForEach(array) { player in
let index : Int? = nil
VStack(alignment: .leading) {
HStack {
if player.isAnonymous() {
Text("Joueur Anonyme")
} else {
Text(player.getLastName().capitalized)
Text(player.getFirstName().capitalized)
}
if index == nil {
Text(player.male ? "" : "")
}
Spacer()
if let index {
HStack(alignment: .top, spacing: 0) {
Text(index.formatted())
.foregroundStyle(.secondary)
.font(.title3)
Text(index.ordinalFormattedSuffix())
.foregroundStyle(.secondary)
.font(.caption)
}
}
}
.font(.title3)
.lineLimit(1)
HStack {
HStack(alignment: .top, spacing: 0) {
Text(player.formattedRank()).italic(player.isAssimilated)
.font(.title3)
.background {
if player.isNotFromCurrentDate() {
UnderlineView()
}
}
if let rank = player.getRank() {
Text(rank.ordinalFormattedSuffix()).italic(player.isAssimilated)
.font(.caption)
}
}
if showProgression, player.getProgression() != 0 {
HStack(alignment: .top, spacing: 2) {
Text("(")
Text(player.getProgression().formatted(.number.sign(strategy: .always())))
.foregroundStyle(player.getProgressionColor(progression: player.getProgression()))
Text(")")
}.font(.title3)
}
if let pts = player.getPoints(), pts > 0 {
HStack(alignment: .lastTextBaseline, spacing: 0) {
Text(pts.formatted()).font(.title3)
Text(" pts").font(.caption)
}
}
if let tournamentPlayed = player.tournamentPlayed, tournamentPlayed > 0 {
HStack(alignment: .lastTextBaseline, spacing: 0) {
Text(tournamentPlayed.formatted()).font(.title3)
Text(" tournoi" + tournamentPlayed.pluralSuffix).font(.caption)
}
}
}
.lineLimit(1)
.truncationMode(.tail)
if showFemaleInMaleAssimilation, let assimilatedAsMaleRank = player.getAssimilatedAsMaleRank() {
HStack(alignment: .top, spacing: 2) {
Text("(")
Text(assimilatedAsMaleRank.formatted())
VStack(alignment: .leading, spacing: 0) {
Text("équivalence")
Text("messieurs")
}
.font(.caption)
Text(")").font(.title3)
}
}
HStack {
Text(player.formattedLicense())
if let computedAge = player.computedAge {
Text(computedAge.formatted() + " ans")
}
}
.font(.caption)
if let clubName = player.clubName {
Text(clubName)
.font(.caption)
}
if let ligueName = player.ligueName {
Text(ligueName)
.font(.caption)
}
}
ImportedPlayerView(player: player, index: nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
}
.onDelete { indexSet in
for index in indexSet {

@ -65,15 +65,13 @@ struct EditingTeamView: View {
var body: some View {
List {
Section {
RowButtonView("Modifier la composition de l'équipe", role: team.hasRegisteredOnline() ? .destructive : .none) {
RowButtonView("Modifier la composition de l'équipe", role: team.hasRegisteredOnline() ? .destructive : .none, confirmationMessage: "Vous êtes sur le point de modifier une équipe qui s'est inscrite en ligne.") {
editedTeam = team
}
TeamDetailView(team: team)
} header: {
if team.hasRegisteredOnline() {
Text("Inscription en ligne")
.foregroundStyle(.master)
} else {
Text("Inscription par vous-même")
}

@ -22,7 +22,15 @@ struct TeamDetailView: View {
PlayerDetailView(player: player)
.environment(tournament)
} label: {
PlayerView(player: player)
VStack(alignment: .leading, spacing: 0) {
HStack {
Text("inscrit en ligne")
Spacer()
Text(player.localizedSourceLabel())
}
.font(.caption).foregroundStyle(.secondary)
PlayerView(player: player)
}
}
}
}

@ -118,9 +118,10 @@ struct TeamRowView: View {
var body: some View {
ForEach(team.players()) { player in
HStack {
HStack(spacing: 4) {
if player.registeredOnline {
Image(systemName: "person.badge.shield.checkmark.fill")
Image(systemName: "circle.fill").foregroundStyle(.green)
.font(.system(size: 8))
}
Text(player.playerLabel()).lineLimit(1).truncationMode(.tail)
}

@ -36,6 +36,9 @@ struct TournamentCategorySettingsView: View {
private func _save() {
do {
if tournament.onlineRegistrationCanBeEnabled() == false, tournament.enableOnlineRegistration {
tournament.enableOnlineRegistration = false
}
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)

@ -48,27 +48,29 @@ struct TournamentGeneralSettingsView: View {
Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.")
}
Section {
NavigationLink {
RegistrationSetupView(tournament: tournament)
} label: {
LabeledContent {
if tournament.enableOnlineRegistration {
Text("activée").foregroundStyle(.green)
.font(.headline)
} else {
Text("désactivée").foregroundStyle(.logoRed)
.font(.headline)
}
if tournament.onlineRegistrationCanBeEnabled() {
Section {
NavigationLink {
RegistrationSetupView(tournament: tournament)
} label: {
Text("Accéder aux paramètres")
Text(tournament.getOnlineRegistrationStatus().statusLocalized())
LabeledContent {
if tournament.enableOnlineRegistration {
Text("activée").foregroundStyle(.green)
.font(.headline)
} else {
Text("désactivée").foregroundStyle(.logoRed)
.font(.headline)
}
} label: {
Text("Accéder aux paramètres")
Text(tournament.getOnlineRegistrationStatus().statusLocalized())
}
}
} header: {
Text("Inscription en ligne")
} footer: {
Text("Paramétrez les possibilités d'inscription en ligne à votre tournoi via Padel Club")
}
} header: {
Text("Inscription en ligne")
} footer: {
Text("Paramétrez les possibilités d'inscription en ligne à votre tournoi via Padel Club")
}
Section {

@ -250,7 +250,7 @@ struct InscriptionManagerView: View {
RowButtonView("Rafraîchir la liste") {
await _refreshList()
}
} else {
} else if tournament.onlineRegistrationCanBeEnabled() {
RowButtonView("Inscription en ligne") {
navigation.path.append(Screen.settings)
}
@ -533,19 +533,19 @@ struct InscriptionManagerView: View {
}
}
private func _fixModel() {
let players = tournament.players()
players.forEach { player in
if player.source == .onlineRegistration {
player.source = .frenchFederation
player.registeredOnline = true
}
}
try? tournamentStore.playerRegistrations.addOrUpdate(contentOfs: players)
}
// private func _fixModel() {
// let players = tournament.players()
//
// players.forEach { player in
// if player.source == .onlineRegistration {
// player.source = .frenchFederation
// player.registeredOnline = true
// }
// }
//
// try? tournamentStore.playerRegistrations.addOrUpdate(contentOfs: players)
// }
//
private func _refreshList() async {
if refreshInProgress { return }
@ -629,7 +629,7 @@ struct InscriptionManagerView: View {
_teamDeleteButtonView(team)
}
}
.listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true, backgroundColor: color, alignment: .trailing)
.listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true, backgroundColor: color, alignment: .leading)
}
} header: {
if filterMode == .all && walkoutTeams.isEmpty == false {
@ -837,9 +837,9 @@ struct InscriptionManagerView: View {
CloseDatePicker(closedRegistrationDate: closedRegistrationDate)
}
Button("bug fix") {
_fixModel()
}
// Button("bug fix") {
// _fixModel()
// }
if tournament.enableOnlineRegistration {
Button {

@ -114,7 +114,7 @@ struct RegistrationSetupView: View {
}
if openingRegistrationDateEnabled {
DatePicker(selection: $openingRegistrationDate, in: tournament.creationDate.truncateMinutesAndSeconds()...tournament.startDate.truncateMinutesAndSeconds()) {
DatePicker(selection: $openingRegistrationDate) {
DateMenuView(date: $openingRegistrationDate)
}
}
@ -130,7 +130,7 @@ struct RegistrationSetupView: View {
}
if registrationDateLimitEnabled {
DatePicker(selection: $registrationDateLimit, in: tournament.creationDate.truncateMinutesAndSeconds()...tournament.startDate.truncateMinutesAndSeconds()) {
DatePicker(selection: $registrationDateLimit) {
DateMenuView(date: $registrationDateLimit)
}
}

@ -63,7 +63,7 @@ struct TournamentView: View {
}
}
case .initial:
if tournament.enableOnlineRegistration == false {
if tournament.enableOnlineRegistration == false, tournament.onlineRegistrationCanBeEnabled() {
TipView(onlineRegistrationTip) { action in
if let actionKey = OnlineRegistrationTip.ActionKey(rawValue: action.id) {
switch actionKey {
@ -84,7 +84,7 @@ struct TournamentView: View {
}
TournamentInitView(tournament: tournament)
case .build:
if tournament.enableOnlineRegistration == false {
if tournament.enableOnlineRegistration == false, tournament.onlineRegistrationCanBeEnabled() {
TipView(onlineRegistrationTip) { action in
if let actionKey = OnlineRegistrationTip.ActionKey(rawValue: action.id) {
switch actionKey {

Loading…
Cancel
Save