multistore
Razmig Sarkissian 2 years ago
parent 4fe9743a32
commit 83a2b2a565
  1. 6
      PadelClub.xcodeproj/project.pbxproj
  2. 6
      PadelClub/Data/GroupStage.swift
  3. 2
      PadelClub/Data/Tournament.swift
  4. 0
      PadelClub/Utils/CloudConvert.swift
  5. 0
      PadelClub/Utils/ContactManager.swift
  6. 0
      PadelClub/Utils/DisplayContext.swift
  7. 0
      PadelClub/Utils/FileImportManager.swift
  8. 0
      PadelClub/Utils/LocationManager.swift
  9. 0
      PadelClub/Utils/Network/NetworkFederalService.swift
  10. 0
      PadelClub/Utils/Network/NetworkManager.swift
  11. 0
      PadelClub/Utils/Network/NetworkManagerError.swift
  12. 0
      PadelClub/Utils/NetworkMonitor.swift
  13. 0
      PadelClub/Utils/PadelRule.swift
  14. 0
      PadelClub/Utils/SourceFileManager.swift
  15. 0
      PadelClub/Utils/SwiftParser.swift
  16. 0
      PadelClub/Utils/Tips.swift
  17. 0
      PadelClub/Utils/URLs.swift
  18. 2
      PadelClub/Views/Cashier/CashierDetailView.swift
  19. 6
      PadelClub/Views/Components/GenericDestinationPickerView.swift
  20. 2
      PadelClub/Views/Components/MatchListView.swift
  21. 128
      PadelClub/Views/Match/MatchDetailView.swift
  22. 23
      PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift
  23. 2
      PadelClub/Views/Tournament/TournamentView.swift

@ -613,7 +613,7 @@
C4A47D722B72881500ADC637 /* Views */,
FF3F74FD2B91A087004CFE0E /* ViewModel */,
C4A47D5F2B6D3B2D00ADC637 /* Data */,
FFF8ACD02B9238A2008466FA /* Manager */,
FFF8ACD02B9238A2008466FA /* Utils */,
FFF8ACD72B923F26008466FA /* Extensions */,
C425D4042B6D249E002A7B48 /* Assets.xcassets */,
FF0EC54D2BB195CA0056B6D1 /* CSV */,
@ -1166,7 +1166,7 @@
path = Components;
sourceTree = "<group>";
};
FFF8ACD02B9238A2008466FA /* Manager */ = {
FFF8ACD02B9238A2008466FA /* Utils */ = {
isa = PBXGroup;
children = (
FFA6D7862BB0B7A2003A31F3 /* CloudConvert.swift */,
@ -1182,7 +1182,7 @@
C49EF01A2BD6A1E80077B5AA /* URLs.swift */,
FF6EC9072B947A1E00EA7F5A /* Network */,
);
path = Manager;
path = Utils;
sourceTree = "<group>";
};
FFF8ACD72B923F26008466FA /* Extensions */ = {

@ -95,7 +95,7 @@ class GroupStage: ModelObject, Storable {
}
func scoreLabel(forGroupStagePosition groupStagePosition: Int) -> (wins: String, losses: String, setsDifference: String?, gamesDifference: String?)? {
if let scoreData = _score(forGroupStagePosition: groupStagePosition) {
if let scoreData = _score(forGroupStagePosition: groupStagePosition, nilIfEmpty: true) {
let hideSetDifference = matchFormat.setsToWin == 1
let setDifference = scoreData.setDifference.formatted(.number.sign(strategy: .always(includingZero: false)))
let gameDifference = scoreData.gameDifference.formatted(.number.sign(strategy: .always(includingZero: false)))
@ -106,10 +106,10 @@ class GroupStage: ModelObject, Storable {
}
}
fileprivate func _score(forGroupStagePosition groupStagePosition: Int) -> TeamGroupStageScore? {
fileprivate func _score(forGroupStagePosition groupStagePosition: Int, nilIfEmpty: Bool = false) -> TeamGroupStageScore? {
guard let team = teamAt(groupStagePosition: groupStagePosition) else { return nil }
let matches = matches(forGroupStagePosition: groupStagePosition).filter({ $0.hasEnded() })
if matches.isEmpty { return nil }
if matches.isEmpty && nilIfEmpty { return nil }
let wins = matches.filter { $0.winningTeamId == team.id }.count
let loses = matches.filter { $0.losingTeamId == team.id }.count
let differences = matches.compactMap { $0.scoreDifference(groupStagePosition) }

@ -550,7 +550,7 @@ class Tournament : ModelObject, Storable {
func registrationIssues() -> Int {
let players : [PlayerRegistration] = unsortedPlayers()
let selectedTeams : [TeamRegistration] = selectedSortedTeams()
let callDateIssue : [TeamRegistration] = selectedTeams.filter { isStartDateIsDifferentThanCallDate($0) }
let callDateIssue : [TeamRegistration] = selectedTeams.filter { $0.callDate != nil && isStartDateIsDifferentThanCallDate($0) }
let duplicates : [PlayerRegistration] = duplicates(in: players)
let problematicPlayers : [PlayerRegistration] = players.filter({ $0.sex == -1 })
let inadequatePlayers : [PlayerRegistration] = inadequatePlayers(in: players)

@ -54,7 +54,7 @@ struct CashierDetailView: View {
Text(count.formatted())
}
}
} label: {
} label: {
Text("Voir le détail")
}

@ -26,8 +26,7 @@ struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
.padding()
.background {
Circle()
.fill(Color.master)
.opacity(selectedDestination == nil ? 1.0 : 0.2)
.fill(selectedDestination == nil ? .master : .beige)
}
.buttonStyle(.plain)
}
@ -42,8 +41,7 @@ struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
.padding()
.background {
Capsule()
.fill(Color.master)
.opacity(selectedDestination?.id == destination.id ? 1.0 : 0.2)
.fill(selectedDestination?.id == destination.id ? .master : .beige)
}
.buttonStyle(.plain)
.overlay(alignment: .bottomTrailing) {

@ -22,7 +22,7 @@ struct MatchListView: View {
DisclosureGroup(isExpanded: $isExpanded) {
ForEach(matches) { match in
MatchRowView(match: match, matchViewStyle: matchViewStyle)
.listRowInsets(EdgeInsets())
.listRowInsets(EdgeInsets(top: 0, leading: -2, bottom: 0, trailing: 8))
}
} label: {
LabeledContent {

@ -382,68 +382,67 @@ struct MatchDetailView: View {
}
}
@ViewBuilder
var startingOptionView: some View {
Section {
if match.hasEnded() == false {
let rotationDuration = match.getDuration()
Picker(selection: $startDateSetup) {
if match.isReady() {
Text("Dans 5 minutes").tag(MatchDateSetup.inMinutes(5))
Text("Dans 15 minutes").tag(MatchDateSetup.inMinutes(15))
Text("Tout de suite").tag(MatchDateSetup.now)
}
Text("Précédente rotation").tag(MatchDateSetup.inMinutes(-rotationDuration))
Text("Prochaine rotation").tag(MatchDateSetup.inMinutes(rotationDuration))
Text("À").tag(MatchDateSetup.customDate)
} label: {
Text("Horaire")
if match.hasEnded() == false {
let rotationDuration = match.getDuration()
Picker(selection: $startDateSetup) {
if match.isReady() {
Text("Dans 5 minutes").tag(MatchDateSetup.inMinutes(5))
Text("Dans 15 minutes").tag(MatchDateSetup.inMinutes(15))
Text("Tout de suite").tag(MatchDateSetup.now)
}
.onChange(of: startDateSetup, perform: { value in
switch startDateSetup {
case .customDate:
break
case .now:
startDate = Date()
case .inMinutes(let minutes):
startDate = Date().addingTimeInterval(Double(minutes) * 60)
}
})
Text("Précédente rotation").tag(MatchDateSetup.inMinutes(-rotationDuration))
Text("Prochaine rotation").tag(MatchDateSetup.inMinutes(rotationDuration))
Text("À").tag(MatchDateSetup.customDate)
} label: {
Text("Horaire")
}
if match.startDate != nil || startDateSetup == .customDate {
DatePicker(selection: $startDate) {
Label("Début", systemImage: "calendar").labelStyle(.titleOnly)
.onChange(of: startDateSetup, perform: { value in
switch startDateSetup {
case .customDate:
break
case .now:
startDate = Date()
case .inMinutes(let minutes):
startDate = Date().addingTimeInterval(Double(minutes) * 60)
}
.datePickerStyle(.compact)
})
}
if match.startDate != nil || startDateSetup == .customDate {
DatePicker(selection: $startDate) {
Label("Début", systemImage: "calendar").labelStyle(.titleOnly)
}
if match.endDate != nil {
DatePicker(selection: $endDate) {
Label("Fin", systemImage: "calendar").labelStyle(.titleOnly)
}
.datePickerStyle(.compact)
.datePickerStyle(.compact)
}
if match.endDate != nil {
DatePicker(selection: $endDate) {
Label("Fin", systemImage: "calendar").labelStyle(.titleOnly)
}
.datePickerStyle(.compact)
}
Picker(selection: $fieldSetup) {
Text("Au hasard").tag(MatchFieldSetup.random)
//Text("Premier disponible").tag(MatchFieldSetup.firstAvailable)
if let tournament = match.currentTournament() {
ForEach(0..<tournament.courtCount, id: \.self) { courtIndex in
Text(tournament.courtName(atIndex: courtIndex)) .tag(MatchFieldSetup.field(courtIndex))
}
Picker(selection: $fieldSetup) {
Text("Au hasard").tag(MatchFieldSetup.random)
//Text("Premier disponible").tag(MatchFieldSetup.firstAvailable)
if let tournament = match.currentTournament() {
ForEach(0..<tournament.courtCount, id: \.self) { courtIndex in
Text(tournament.courtName(atIndex: courtIndex)) .tag(MatchFieldSetup.field(courtIndex))
}
} label: {
Text("Choix du terrain")
}
.contextMenu {
NavigationLink {
//FieldDrawView(match: match)
} label: {
Text("Tirage au sort visuel")
}
} label: {
Text("Choix du terrain")
}
.contextMenu {
NavigationLink {
//FieldDrawView(match: match)
} label: {
Text("Tirage au sort visuel")
}
}
// if match.canBroadcast() == true {
// Picker(selection: $broadcasted) {
@ -453,21 +452,20 @@ struct MatchDetailView: View {
// Text("Diffuser automatiquement")
// }
// }
RowButtonView("Valider") {
match.validateMatch(fromStartDate: startDateSetup == .now ? Date() : startDate, toEndDate: endDate, fieldSetup: fieldSetup)
RowButtonView("Valider") {
match.validateMatch(fromStartDate: startDateSetup == .now ? Date() : startDate, toEndDate: endDate, fieldSetup: fieldSetup)
if broadcasted {
broadcastAndSave()
} else {
save()
}
isEditing.toggle()
if match.hasStarted() == false {
dismiss()
}
if broadcasted {
broadcastAndSave()
} else {
save()
}
isEditing.toggle()
if match.hasStarted() == false {
dismiss()
}
}
}

@ -18,6 +18,26 @@ struct TournamentGeneralSettingsView: View {
var body: some View {
@Bindable var tournament = tournament
Form {
Section {
if tournament.hasEnded() == false {
if tournament.isCanceled == false {
RowButtonView("Annuler le tournoi", role: .destructive) {
tournament.isCanceled.toggle()
}
} else {
RowButtonView("Reprendre le tournoi", role: .destructive) {
tournament.isCanceled.toggle()
}
}
}
Toggle(isOn: $tournament.isPrivate) {
Text("Tournoi privée")
}
} footer: {
Text("Le tournoi sera masqué sur le site padelclub.app")
}
Section {
TournamentDatePickerView()
TournamentDurationManagerView()
@ -101,6 +121,9 @@ struct TournamentGeneralSettingsView: View {
]) {
_save()
}
.onChange(of: [tournament.isDeleted, tournament.isCanceled, tournament.isPrivate]) {
_save()
}
}
private func _save() {

@ -45,7 +45,7 @@ struct TournamentView: View {
}
}
} footer: {
if tournament.inscriptionClosed() == false {
if tournament.inscriptionClosed() == false && tournament.state() == .build && tournament.unsortedTeams().isEmpty == false {
Button {
tournament.lockRegistration()
_save()

Loading…
Cancel
Save