Merge remote-tracking branch 'refs/remotes/origin/main'

#Conflicts:
#	PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
sync2
Raz 8 months ago
commit 76c22c22fe
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 4
      PadelClub/Data/Match.swift
  3. 8
      PadelClub/Data/TeamRegistration.swift
  4. 2
      PadelClub/Views/Match/Components/MatchDateView.swift
  5. 2
      PadelClub/Views/Match/Components/PlayerBlockView.swift
  6. 2
      PadelClub/Views/Match/MatchDetailView.swift
  7. 5
      PadelClub/Views/Score/FollowUpMatchView.swift
  8. 2
      PadelClub/Views/Shared/SelectablePlayerListView.swift
  9. 123
      PadelClub/Views/Team/EditingTeamView.swift
  10. 12
      PadelClub/Views/Team/TeamPickerView.swift
  11. 6
      PadelClub/Views/Team/TeamRowView.swift
  12. 13
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  13. 4
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift
  14. 4
      PadelClub/Views/Tournament/Screen/TableStructureView.swift

@ -3344,7 +3344,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.15;
MARKETING_VERSION = 1.1.16;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3389,7 +3389,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.15;
MARKETING_VERSION = 1.1.16;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

@ -517,7 +517,7 @@ defer {
return (groupStageObject.index + 1) * 100 + groupStageObject.indexOf(index)
}
guard let roundObject else { return index }
return roundObject.isLoserBracket() ? (roundObject.index + 1) * 10000 + indexInRound() : (roundObject.index + 1) * 1000 + indexInRound()
return (300 - (roundObject.theoryCumulativeMatchCount * 10 + roundObject.index * 22)) * 10 + indexInRound()
}
func previousMatches() -> [Match] {
@ -540,8 +540,10 @@ defer {
func setWalkOut(_ teamPosition: TeamPosition) {
let teamScoreWalkout = teamScore(teamPosition) ?? TeamScore(match: id, team: team(teamPosition))
teamScoreWalkout.walkOut = 0
teamScoreWalkout.score = matchFormat.defaultWalkOutScore(true).compactMap({ String($0) }).joined(separator: ",")
let teamScoreWinning = teamScore(teamPosition.otherTeam) ?? TeamScore(match: id, team: team(teamPosition.otherTeam))
teamScoreWinning.walkOut = nil
teamScoreWinning.score = matchFormat.defaultWalkOutScore(false).compactMap({ String($0) }).joined(separator: ",")
do {
try self.tournamentStore.teamScores.addOrUpdate(contentOfs: [teamScoreWalkout, teamScoreWinning])
} catch {

@ -646,6 +646,14 @@ final class TeamRegistration: ModelObject, Storable {
unsortedPlayers().count > 0
}
func bracketMatchTitleAndQualifiedStatus() -> String? {
let values = [qualified ? "Qualifié" : nil, initialMatch()?.roundAndMatchTitle()].compactMap({ $0 })
if values.isEmpty {
return nil
}
return values.joined(separator: " -> ")
}
enum CodingKeys: String, CodingKey {
case _id = "id"
case _tournament = "tournament"

@ -30,7 +30,7 @@ struct MatchDateView: View {
}
var currentDate: Date {
Date().withoutSeconds()
Date()
}
var body: some View {

@ -151,7 +151,7 @@ struct PlayerBlockView: View {
}
}
}
} else if let team {
} else if let team, hasWon == false, isWalkOut == false {
TeamWeightView(team: team, teamPosition: teamPosition)
}
}

@ -495,7 +495,7 @@ struct MatchDetailView: View {
Text("Horaire")
}
.onChange(of: startDateSetup) {
let date = Date().withoutSeconds()
let date = Date()
switch startDateSetup {
case .customDate:
break

@ -217,6 +217,11 @@ struct FollowUpMatchView: View {
}
#if DEBUG
Spacer()
if let roundObject = match.roundObject {
Text(roundObject.index.formatted())
Text(roundObject.theoryCumulativeMatchCount.formatted())
}
Text(match.computedOrder.formatted())
FooterButtonView("copier l'id") {
let pasteboard = UIPasteboard.general
pasteboard.string = match.id

@ -427,7 +427,9 @@ struct MySearchView: View {
searchViewModel.selectedPlayers.insert(player)
} label: {
ImportedPlayerView(player: player, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
.contentShape(Rectangle())
}
.frame(maxWidth: .infinity)
.buttonStyle(.plain)
}
} header: {

@ -20,11 +20,11 @@ struct EditingTeamView: View {
@State private var sentError: ContactManagerError? = nil
@State private var showSubscriptionView: Bool = false
@State private var registrationDate : Date
@State private var walkOut : Bool
@State private var wildCardBracket : Bool
@State private var wildCardGroupStage : Bool
@State private var name: String
@FocusState private var focusedField: TeamRegistration.CodingKeys?
@State private var presentOnlineRegistrationWarning: Bool = false
@State private var currentWaitingList: TeamRegistration?
@State private var presentTeamToWarn: Bool = false
var messageSentFailed: Binding<Bool> {
Binding {
@ -36,6 +36,22 @@ struct EditingTeamView: View {
}
}
var hasChanged: Binding<Bool> {
Binding {
if tournament.enableOnlineRegistration == false {
return false
}
return
registrationDate != team.registrationDate
|| walkOut != team.walkOut
|| wildCardBracket != team.wildCardBracket
|| wildCardGroupStage != team.wildCardGroupStage
} set: { _ in
}
}
var tournamentStore: TournamentStore {
return self.tournament.tournamentStore
}
@ -44,25 +60,18 @@ struct EditingTeamView: View {
self.team = team
_name = .init(wrappedValue: team.name ?? "")
_registrationDate = State(wrappedValue: team.registrationDate ?? Date())
_walkOut = State(wrappedValue: team.walkOut)
_wildCardBracket = State(wrappedValue: team.wildCardBracket)
_wildCardGroupStage = State(wrappedValue: team.wildCardGroupStage)
}
private func _resetTeam() {
let selectedSortedTeams = tournament.selectedSortedTeams()
self.currentWaitingList = tournament.waitingListSortedTeams(selectedSortedTeams: selectedSortedTeams).filter({ $0.hasRegisteredOnline() }).first
team.resetPositions()
team.wildCardGroupStage = false
team.walkOut = false
team.wildCardBracket = false
}
private func _checkOnlineRegistrationWarning() {
guard let currentWaitingList else { return }
let selectedSortedTeams = tournament.selectedSortedTeams().map({ $0.id })
if selectedSortedTeams.contains(currentWaitingList.id) {
presentOnlineRegistrationWarning = true
}
}
var body: some View {
List {
Section {
@ -92,10 +101,6 @@ struct EditingTeamView: View {
.headerProminence(.increased)
Section {
DatePicker(selection: $registrationDate) {
Text("Inscription")
Text(registrationDate.localizedWeekDay().capitalized)
}
if let callDate = team.callDate {
LabeledContent() {
Text(callDate.localizedDate())
@ -117,34 +122,23 @@ struct EditingTeamView: View {
Text("Équipe sur place")
}
}
}
Toggle(isOn: .init(get: {
return team.wildCardBracket
}, set: { value in
_resetTeam()
team.wildCardBracket = value
_save()
})) {
Section {
DatePicker(selection: $registrationDate) {
Text("Inscription")
Text(registrationDate.localizedWeekDay().capitalized)
}
Toggle(isOn: $wildCardBracket) {
Text("Wildcard Tableau")
}
Toggle(isOn: .init(get: {
return team.wildCardGroupStage
}, set: { value in
_resetTeam()
team.wildCardGroupStage = value
_save()
})) {
Toggle(isOn: $wildCardGroupStage) {
Text("Wildcard Poule")
}
}.disabled(tournament.groupStageCount == 0)
Toggle(isOn: .init(get: {
return team.walkOut
}, set: { value in
_resetTeam()
team.walkOut = value
_save()
})) {
Toggle(isOn: $walkOut) {
Text("Forfait")
}
}
@ -216,30 +210,24 @@ struct EditingTeamView: View {
}
}
}
.sheet(isPresented: $presentTeamToWarn) {
if let currentWaitingList {
NavigationStack {
EditingTeamView(team: currentWaitingList)
}
.tint(.master)
.alert("Attention", isPresented: hasChanged, actions: {
Button("Confirmer") {
_resetTeam()
team.registrationDate = registrationDate
team.wildCardBracket = wildCardBracket
team.wildCardGroupStage = wildCardGroupStage
team.walkOut = walkOut
_save()
}
}
.alert("Attention", isPresented: $presentOnlineRegistrationWarning, actions: {
if currentWaitingList != nil {
Button("Voir l'équipe") {
self.presentTeamToWarn = true
}
Button("OK") {
self.currentWaitingList = nil
self.presentOnlineRegistrationWarning = false
}
Button("Annuler", role: .cancel) {
registrationDate = team.registrationDate ?? Date()
walkOut = team.walkOut
wildCardBracket = team.wildCardBracket
wildCardGroupStage = team.wildCardGroupStage
}
}, message: {
if let currentWaitingList {
Text("L'équipe \(currentWaitingList.teamLabel(separator: "/")), inscrite en ligne, rentre dans votre sélection suite à la modification que vous venez de faire, voulez-vous les prévenir ?")
}
Text("Ce changement peut entraîner l'entrée ou la sortie d'une équipe de votre sélection. Padel Club préviendra automatiquement une équipe inscrite en ligne de son nouveau statut.")
})
.navigationBarBackButtonHidden(focusedField != nil)
.toolbar(content: {
@ -327,8 +315,19 @@ struct EditingTeamView: View {
}
}
.onChange(of: registrationDate) {
team.registrationDate = registrationDate
_save()
if tournament.enableOnlineRegistration == false {
team.registrationDate = registrationDate
_save()
}
}
.onChange(of: [walkOut, wildCardBracket, wildCardGroupStage]) {
if tournament.enableOnlineRegistration == false {
_resetTeam()
team.walkOut = walkOut
team.wildCardBracket = wildCardBracket
team.wildCardGroupStage = wildCardGroupStage
_save()
}
}
.toolbarBackground(.visible, for: .navigationBar)
.navigationTitle("Édition de l'équipe")
@ -369,8 +368,6 @@ struct EditingTeamView: View {
} catch {
Logger.error(error)
}
_checkOnlineRegistrationWarning()
}
private var _networkErrorMessage: String {

@ -134,11 +134,19 @@ struct TeamPickerView: View {
// presentTeamPickerView = false
// }
} label: {
TeamRowView(team: team)
.contentShape(Rectangle())
VStack(alignment: .leading) {
if let roundAndMatchTitle = team.bracketMatchTitleAndQualifiedStatus() {
Text(roundAndMatchTitle)
.font(.headline)
.frame(maxWidth: .infinity, alignment: .leading)
}
TeamRowView(team: team)
}
.contentShape(Rectangle())
}
.frame(maxWidth: .infinity)
.buttonStyle(.plain)
.id(team.id)
.listRowView(isActive: matchTypeContext == .loserBracket && round?.teams().map({ $0.id }).contains(team.id) == true, color: .green, hideColorVariation: true)
// .confirmationDialog("Attention", isPresented: confirmationRequest, titleVisibility: .visible) {
// Button("Retirer du tableau", role: .destructive) {

@ -9,6 +9,8 @@ import SwiftUI
struct TeamRowView: View {
@EnvironmentObject var dataStore: DataStore
@Environment(\.isEditingTournamentSeed) private var isEditingTournamentSeed
var team: TeamRegistration
var teamPosition: TeamPosition? = nil
var displayCallDate: Bool = false
@ -20,7 +22,9 @@ struct TeamRowView: View {
TeamWeightView(team: team, teamPosition: teamPosition, teamIndex: teamIndex)
} label: {
VStack(alignment: .leading) {
TeamHeadlineView(team: team)
if isEditingTournamentSeed.wrappedValue == false {
TeamHeadlineView(team: team)
}
TeamView(team: team)
}
if displayCallDate {

@ -247,7 +247,7 @@ struct InscriptionManagerView: View {
if tournament.enableOnlineRegistration {
RowButtonView("Rafraîchir la liste", cornerRadius: 20) {
await _refreshList()
await _refreshList(forced: true)
}
} else if tournament.onlineRegistrationCanBeEnabled() {
RowButtonView("Inscription en ligne") {
@ -259,13 +259,15 @@ struct InscriptionManagerView: View {
}
}
.task {
await _refreshList()
await _refreshList(forced: false)
}
.refreshable {
await _refreshList()
await _refreshList(forced: true)
}
.onAppear {
_setHash(currentSelectedSortedTeams: selectedSortedTeams)
if tournament.enableOnlineRegistration == false || refreshStatus == true {
_setHash(currentSelectedSortedTeams: selectedSortedTeams)
}
}
.onDisappear {
_handleHashDiff(selectedSortedTeams: selectedSortedTeams)
@ -544,7 +546,8 @@ struct InscriptionManagerView: View {
// try? tournamentStore.playerRegistrations.addOrUpdate(contentOfs: players)
// }
//
private func _refreshList() async {
private func _refreshList(forced: Bool) async {
if refreshStatus == true, forced == false { return }
if tournament.enableOnlineRegistration == false { return }
if tournament.hasEnded() { return }
if tournament.refreshInProgress { return }

@ -75,8 +75,8 @@ struct RegistrationSetupView: View {
var body: some View {
List {
if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false {
Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Pour l'instant Padel Club ne saura pas les prévenir automatiquement, vous devrez les contacter via l'écran de gestion des inscriptions.")
if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false, tournament.hasEnded() == false, tournament.hasStarted() == false {
Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.")
.foregroundStyle(.logoRed)
}

@ -60,8 +60,8 @@ struct TableStructureView: View {
@ViewBuilder
var body: some View {
List {
if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false {
Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Pour l'instant Padel Club ne saura pas les prévenir automatiquement, vous devrez les contacter via l'écran de gestion des inscriptions.")
if displayWarning, tournament.enableOnlineRegistration, tournament.onlineTeams().isEmpty == false, tournament.hasEnded() == false, tournament.hasStarted() == false {
Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.")
.foregroundStyle(.logoRed)
}

Loading…
Cancel
Save