add settings view for round and group stage

multistore
Razmig Sarkissian 2 years ago
parent 97e5d641fb
commit 9e4a13246c
  1. 12
      PadelClub.xcodeproj/project.pbxproj
  2. 5
      PadelClub/Data/GroupStage.swift
  3. 6
      PadelClub/Data/Round.swift
  4. 5
      PadelClub/Data/Tournament.swift
  5. 61
      PadelClub/Views/Components/GenericDestinationPickerView.swift
  6. 145
      PadelClub/Views/GroupStage/GroupStageSettingsView.swift
  7. 13
      PadelClub/Views/GroupStage/GroupStageView.swift
  8. 207
      PadelClub/Views/GroupStage/GroupStagesView.swift
  9. 22
      PadelClub/Views/Round/RoundSettingsView.swift
  10. 54
      PadelClub/Views/Round/RoundsView.swift
  11. 2
      PadelClub/Views/Tournament/TournamentView.swift

@ -114,6 +114,9 @@
FF5D0D872BB48AFD005CB568 /* NumberFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */; };
FF5D0D892BB4935C005CB568 /* ClubRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D882BB4935C005CB568 /* ClubRowView.swift */; };
FF5D0D8B2BB4D1E3005CB568 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0D8A2BB4D1E3005CB568 /* CalendarView.swift */; };
FF5DA18F2BB9268800A33061 /* GroupStageSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5DA18E2BB9268800A33061 /* GroupStageSettingsView.swift */; };
FF5DA1932BB9279B00A33061 /* RoundSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5DA1922BB9279B00A33061 /* RoundSettingsView.swift */; };
FF5DA1952BB927E800A33061 /* GenericDestinationPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5DA1942BB927E800A33061 /* GenericDestinationPickerView.swift */; };
FF6EC8F72B94773200EA7F5A /* RowButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6EC8F62B94773100EA7F5A /* RowButtonView.swift */; };
FF6EC8FB2B94788600EA7F5A /* TournamentButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6EC8FA2B94788600EA7F5A /* TournamentButtonView.swift */; };
FF6EC8FE2B94792300EA7F5A /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6EC8FD2B94792300EA7F5A /* Screen.swift */; };
@ -340,6 +343,9 @@
FF5D0D862BB48AFD005CB568 /* NumberFormatter+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NumberFormatter+Extensions.swift"; sourceTree = "<group>"; };
FF5D0D882BB4935C005CB568 /* ClubRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClubRowView.swift; sourceTree = "<group>"; };
FF5D0D8A2BB4D1E3005CB568 /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = "<group>"; };
FF5DA18E2BB9268800A33061 /* GroupStageSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupStageSettingsView.swift; sourceTree = "<group>"; };
FF5DA1922BB9279B00A33061 /* RoundSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundSettingsView.swift; sourceTree = "<group>"; };
FF5DA1942BB927E800A33061 /* GenericDestinationPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericDestinationPickerView.swift; sourceTree = "<group>"; };
FF6EC8F62B94773100EA7F5A /* RowButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RowButtonView.swift; sourceTree = "<group>"; };
FF6EC8FA2B94788600EA7F5A /* TournamentButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentButtonView.swift; sourceTree = "<group>"; };
FF6EC8FD2B94792300EA7F5A /* Screen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screen.swift; sourceTree = "<group>"; };
@ -603,6 +609,7 @@
isa = PBXGroup;
children = (
C4A47D9E2B7D0BCE00ADC637 /* StepperView.swift */,
FF5DA1942BB927E800A33061 /* GenericDestinationPickerView.swift */,
FF6EC8F62B94773100EA7F5A /* RowButtonView.swift */,
FF967CF72BAEDF0000A9A3BD /* Labels.swift */,
);
@ -846,6 +853,7 @@
children = (
FF967CFA2BAEE13800A9A3BD /* GroupStageView.swift */,
FF967CFB2BAEE13900A9A3BD /* GroupStagesView.swift */,
FF5DA18E2BB9268800A33061 /* GroupStageSettingsView.swift */,
);
path = GroupStage;
sourceTree = "<group>";
@ -878,6 +886,7 @@
children = (
FFC83D4E2BB807D100750834 /* RoundsView.swift */,
FFC83D502BB8087E00750834 /* RoundView.swift */,
FF5DA1922BB9279B00A33061 /* RoundSettingsView.swift */,
);
path = Round;
sourceTree = "<group>";
@ -1147,6 +1156,7 @@
FF8F264F2BAE0B9600650388 /* MatchTypeSelectionView.swift in Sources */,
FF967D062BAF3C4200A9A3BD /* MatchSetupView.swift in Sources */,
FF4AB6B52B9248200002987F /* NetworkManager.swift in Sources */,
FF5DA1932BB9279B00A33061 /* RoundSettingsView.swift in Sources */,
FF5D0D742BB41DF8005CB568 /* Color+Extensions.swift in Sources */,
C4A47DB12B86375E00ADC637 /* MainUserView.swift in Sources */,
FF7091682B90F79F00AB08DA /* TournamentCellView.swift in Sources */,
@ -1192,6 +1202,7 @@
C4A47D7D2B73CDC300ADC637 /* ClubV1.swift in Sources */,
FF8F263D2BAD627A00650388 /* TournamentConfiguratorView.swift in Sources */,
FFC1E10C2BAC7FB0008D6F59 /* ClubImportView.swift in Sources */,
FF5DA1952BB927E800A33061 /* GenericDestinationPickerView.swift in Sources */,
FF8F26542BAE1E4400650388 /* TableStructureView.swift in Sources */,
FF6EC8FE2B94792300EA7F5A /* Screen.swift in Sources */,
FF967CEE2BAECBD700A9A3BD /* Round.swift in Sources */,
@ -1234,6 +1245,7 @@
FF8F26452BAE0A3400650388 /* TournamentDurationManagerView.swift in Sources */,
FF1DC5532BAB354A00FD8220 /* MockData.swift in Sources */,
FF967D092BAF3D4000A9A3BD /* TeamDetailView.swift in Sources */,
FF5DA18F2BB9268800A33061 /* GroupStageSettingsView.swift in Sources */,
FF8F26382BAD523300650388 /* PadelRule.swift in Sources */,
FF967CF42BAECC0B00A9A3BD /* TeamRegistration.swift in Sources */,
FFF8ACDB2B923F48008466FA /* Date+Extensions.swift in Sources */,

@ -114,3 +114,8 @@ extension GroupStage {
}
}
extension GroupStage: Selectable {
func selectionLabel() -> String {
groupStageTitle()
}
}

@ -77,3 +77,9 @@ class Round: ModelObject, Storable {
case _format = "format"
}
}
extension Round: Selectable {
func selectionLabel() -> String {
roundTitle()
}
}

@ -139,6 +139,11 @@ class Tournament : ModelObject, Storable {
Store.main.filter { $0.tournament == self.id }.sorted(by: \.index)
}
func getActiveGroupStage() -> GroupStage? {
let groupStages = groupStages()
return groupStages.filter({ $0.hasStarted() && $0.hasEnded() == false }).sorted(by: \.index).first ?? groupStages.first
}
func getActiveRound() -> Round? {
let rounds = rounds()
return rounds.filter({ $0.hasStarted() && $0.hasEnded() == false }).sorted(by: \.index).reversed().first ?? rounds.first

@ -0,0 +1,61 @@
//
// GenericDestinationPickerView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 31/03/2024.
//
import SwiftUI
protocol Selectable {
func selectionLabel() -> String
}
struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
@Binding var selectedDestination: T?
let destinations: [T]
var body: some View {
ScrollView(.horizontal) {
HStack {
Button {
selectedDestination = nil
} label: {
Image(systemName: "wrench.and.screwdriver")
}
.padding()
.background {
Circle()
.fill(Color.white)
.opacity(selectedDestination == nil ? 1.0 : 0.5)
}
.buttonStyle(.plain)
ForEach(destinations) { destination in
Button {
selectedDestination = destination
} label: {
Text(destination.selectionLabel())
}
.padding()
.background {
Capsule()
.fill(Color.white)
.opacity(selectedDestination?.id == destination.id ? 1.0 : 0.5)
}
.buttonStyle(.plain)
}
}
.fixedSize()
.padding(8)
}
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.background(Material.ultraThinMaterial)
.overlay {
VStack(spacing: 0) {
Spacer()
Divider()
}
}
}
}

@ -0,0 +1,145 @@
//
// GroupStageSettingsView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 31/03/2024.
//
import SwiftUI
struct GroupStageSettingsView: View {
@Environment(Tournament.self) var tournament: Tournament
var body: some View {
List {
if tournament.missingQualifiedFromGroupStages().isEmpty == false && tournament.qualifiedTeams().count >= tournament.qualifiedFromGroupStage() && tournament.groupStageAdditionalQualified > 0 {
NavigationLink {
//DrawView(tournament: tournament)
} label: {
LabeledContent {
Text(tournament.moreQualifiedToDraw().formatted() + "/" + tournament.groupStageAdditionalQualified.formatted())
} label: {
Text("Qualifié\(tournament.groupStageAdditionalQualified.pluralSuffix) supplémentaire\(tournament.groupStageAdditionalQualified.pluralSuffix)")
let message = [tournament.groupStageAdditionalQualified.formatted(), " meilleur", tournament.groupStageAdditionalQualified.pluralSuffix, " ", (tournament.qualifiedPerGroupStage + 1).ordinalFormatted()].joined()
Text(message)
}
}
}
// if (tournament.groupStagesAreWrong || (tournament.emptySlotInGroupStages > 0 && tournament.entriesCount >= tournament.teamsFromGroupStages)) {
// Section {
// RowButtonView(title: "Reconstruire les poules") {
// confirmGroupStageRebuild = true
// }
// .modify {
// if UIDevice.current.userInterfaceIdiom == .pad {
// $0.alert("Êtes-vous sûr ?", isPresented: $confirmGroupStageRebuild) {
//
// Button(role: .destructive) {
// tournament.refreshGroupStages()
// save()
// } label: {
// Text("Reconstruire")
// }
//
//
// Button(role: .cancel) {
//
// } label: {
// Text("Annuler")
// }
// } message: {
// Text("Attention, cela peut modifier les poules existants.")
//
// }
// } else {
// $0.confirmationDialog("Êtes-vous sûr ?", isPresented: $confirmGroupStageRebuild) {
// Button(role: .destructive) {
// tournament.refreshGroupStages()
// save()
// } label: {
// Text("Reconstruire")
// }
// } message: {
// Text("Attention, cela peut modifier les poules existants.")
// }
// }
// }
// } header: {
// Text("Erreur détectée")
// }
// }
//
// if tournament.isRoundSwissTournament() == false && (tournament.orderedGroupStages.allSatisfy({ $0.orderedMatches.count > 0 }) == false && tournament.groupStagesAreOver == false && tournament.groupStagesCount > 0) {
// Section {
// RowButtonView(title: "Générer les matchs de poules") {
// startAllGroupStageConfirmation = true
// }
// .modify {
// if UIDevice.current.userInterfaceIdiom == .pad {
// $0.alert("Êtes-vous sûr ?", isPresented: $startAllGroupStageConfirmation) {
// Button("Générer") {
// tournament.orderedGroupStages.forEach {
// if $0.orderedMatches.isEmpty {
// $0.startGroupStage()
// }
// }
// save()
// }
// Button(role: .cancel) {
//
// } label: {
// Text("Annuler")
// }
// }
//
// } else {
// $0.confirmationDialog("Êtes-vous sûr ?", isPresented: $startAllGroupStageConfirmation) {
// Button("Générer") {
// tournament.orderedGroupStages.forEach {
// if $0.orderedMatches.isEmpty {
// $0.startGroupStage()
// }
// }
// save()
// }
// }
// }
// }
// }
// }
//
if tournament.groupStagesAreOver() == false {
// Section {
// GroupStageMatchAvailableToStartView(tournament: tournament, groupStageIndex: selectedGroupStageIndex)
// } header: {
// if selectedGroupStageIndex == -1 {
// Text("Matchs de poules prêt à démarrer")
// } else {
// Text("Matchs de la poule \(selectedGroupStageIndex) prêt à démarrer")
// }
// } footer: {
// Text("présence d'au moins 2 équipes d'une même poule ayant réglé.")
// }
}
// if tournament.teamsPerGroupStage == 3 && tournament.qualifiedPerGroupStage == 1 && tournament.numberOfGroupStages%2 == 0 && tournament.moreQualifiedFromGroupStages == 0 {
// Section {
// NavigationLink {
// GroupStageMissingMatchView(tournament: tournament)
// } label: {
// Text("Matchs de classement de poules")
// }
// }
// }
}
}
}
#Preview {
GroupStageSettingsView()
.environment(Tournament.mock())
}

@ -54,6 +54,7 @@ struct GroupStageView: View {
}
var body: some View {
List {
Section {
groupStageView
// .disabled(canUpdateTournament == false)
@ -191,6 +192,18 @@ struct GroupStageView: View {
.buttonStyle(.borderless)
}
}
if groupStage.matches.isEmpty == false {
Section {
ForEach(groupStage.matches) { match in
MatchRowView(match: match, setupSeedContext: false, matchViewStyle: .sectionedStandardStyle)
}
} header: {
Text("Matchs de la " + groupStage.groupStageTitle())
}
}
}
// .onAppear {
// if let tournament = groupStage.tournament {
// canUpdateTournament = PersistenceController.shared.container.canUpdateRecord(forManagedObjectWith: tournament.objectID)

@ -8,206 +8,29 @@
import SwiftUI
struct GroupStagesView: View {
@Environment(Tournament.self) var tournament: Tournament
@State private var selectedGroupStageIndex: Int = -1
@State private var startAllGroupStageConfirmation: Bool = false
@State private var confirmGroupStageRebuild: Bool = false
var tournament: Tournament
@State private var selectedGroupStage: GroupStage?
func displayGroupStage(_ groupStage: GroupStage) -> Bool {
selectedGroupStageIndex == groupStage.index || selectedGroupStageIndex == -1
init(tournament: Tournament) {
self.tournament = tournament
_selectedGroupStage = State(wrappedValue: tournament.getActiveGroupStage())
}
var dynamicTitle: String {
switch selectedGroupStageIndex {
case -1:
return "Toutes les poules"
default:
return tournament.groupStages()[selectedGroupStageIndex].groupStageTitle()
}
}
//
// init(tournament: Tournament) {
// _tournament = ObservedObject(wrappedValue: tournament)
// if let index = tournament.orderedGroupStages.firstIndex(where: { $0.isRunning }) {
// _selectedGroupStageIndex = State(wrappedValue: index.int64Value + 1)
// }
// }
var body: some View {
List {
if tournament.missingQualifiedFromGroupStages().isEmpty == false && tournament.qualifiedTeams().count >= tournament.qualifiedFromGroupStage() && tournament.groupStageAdditionalQualified > 0 {
NavigationLink {
//DrawView(tournament: tournament)
} label: {
LabeledContent {
Text(tournament.moreQualifiedToDraw().formatted() + "/" + tournament.groupStageAdditionalQualified.formatted())
} label: {
Text("Qualifié\(tournament.groupStageAdditionalQualified.pluralSuffix) supplémentaire\(tournament.groupStageAdditionalQualified.pluralSuffix)")
let message = [tournament.groupStageAdditionalQualified.formatted(), " meilleur", tournament.groupStageAdditionalQualified.pluralSuffix, " ", (tournament.qualifiedPerGroupStage + 1).ordinalFormatted()].joined()
Text(message)
}
}
}
// if (tournament.groupStagesAreWrong || (tournament.emptySlotInGroupStages > 0 && tournament.entriesCount >= tournament.teamsFromGroupStages)) {
// Section {
// RowButtonView(title: "Reconstruire les poules") {
// confirmGroupStageRebuild = true
// }
// .modify {
// if UIDevice.current.userInterfaceIdiom == .pad {
// $0.alert("Êtes-vous sûr ?", isPresented: $confirmGroupStageRebuild) {
//
// Button(role: .destructive) {
// tournament.refreshGroupStages()
// save()
// } label: {
// Text("Reconstruire")
// }
//
//
// Button(role: .cancel) {
//
// } label: {
// Text("Annuler")
// }
// } message: {
// Text("Attention, cela peut modifier les poules existants.")
//
// }
// } else {
// $0.confirmationDialog("Êtes-vous sûr ?", isPresented: $confirmGroupStageRebuild) {
// Button(role: .destructive) {
// tournament.refreshGroupStages()
// save()
// } label: {
// Text("Reconstruire")
// }
// } message: {
// Text("Attention, cela peut modifier les poules existants.")
// }
// }
// }
// } header: {
// Text("Erreur détectée")
// }
// }
//
// if tournament.isRoundSwissTournament() == false && (tournament.orderedGroupStages.allSatisfy({ $0.orderedMatches.count > 0 }) == false && tournament.groupStagesAreOver == false && tournament.groupStagesCount > 0) {
// Section {
// RowButtonView(title: "Générer les matchs de poules") {
// startAllGroupStageConfirmation = true
// }
// .modify {
// if UIDevice.current.userInterfaceIdiom == .pad {
// $0.alert("Êtes-vous sûr ?", isPresented: $startAllGroupStageConfirmation) {
// Button("Générer") {
// tournament.orderedGroupStages.forEach {
// if $0.orderedMatches.isEmpty {
// $0.startGroupStage()
// }
// }
// save()
// }
// Button(role: .cancel) {
//
// } label: {
// Text("Annuler")
// }
// }
//
// } else {
// $0.confirmationDialog("Êtes-vous sûr ?", isPresented: $startAllGroupStageConfirmation) {
// Button("Générer") {
// tournament.orderedGroupStages.forEach {
// if $0.orderedMatches.isEmpty {
// $0.startGroupStage()
// }
// }
// save()
// }
// }
// }
// }
// }
// }
//
if tournament.groupStagesAreOver() == false {
// Section {
// GroupStageMatchAvailableToStartView(tournament: tournament, groupStageIndex: selectedGroupStageIndex)
// } header: {
// if selectedGroupStageIndex == -1 {
// Text("Matchs de poules prêt à démarrer")
// } else {
// Text("Matchs de la poule \(selectedGroupStageIndex) prêt à démarrer")
// }
// } footer: {
// Text("présence d'au moins 2 équipes d'une même poule ayant réglé.")
// }
}
// if tournament.teamsPerGroupStage == 3 && tournament.qualifiedPerGroupStage == 1 && tournament.numberOfGroupStages%2 == 0 && tournament.moreQualifiedFromGroupStages == 0 {
// Section {
// NavigationLink {
// GroupStageMissingMatchView(tournament: tournament)
// } label: {
// Text("Matchs de classement de poules")
// }
// }
// }
ForEach(tournament.groupStages()) { groupStage in
if displayGroupStage(groupStage) && groupStage.hasEnded() == false {
VStack(spacing: 0) {
GenericDestinationPickerView(selectedDestination: $selectedGroupStage, destinations: tournament.groupStages())
switch selectedGroupStage {
case .none:
GroupStageSettingsView()
.navigationTitle("Réglages")
case .some(let groupStage):
GroupStageView(groupStage: groupStage)
if groupStage.matches.isEmpty == false {
Section {
ForEach(groupStage.matches) { match in
MatchRowView(match: match, setupSeedContext: false, matchViewStyle: .sectionedStandardStyle)
}
} header: {
Text("Matchs de la " + groupStage.groupStageTitle())
}
}
}
.navigationTitle(groupStage.groupStageTitle())
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
.toolbar {
ToolbarItem(placement: .principal) {
if tournament.groupStages().count < 6 {
Picker(selection: $selectedGroupStageIndex) {
Text("Toutes").tag(-1)
ForEach(tournament.groupStages()) { groupStage in
Text(groupStage.groupStageTitle(.short)).tag(groupStage.index)
}
} label: {
}
.labelsHidden()
.pickerStyle(.segmented)
} else if tournament.groupStages().count < 8 {
Picker(selection: $selectedGroupStageIndex) {
Image(systemName: "square.stack").tag(-1)
ForEach(tournament.groupStages()) { groupStage in
Text(groupStage.groupStageTitle(.short)).tag(groupStage.index)
}
} label: {
}
.labelsHidden()
.pickerStyle(.segmented)
} else {
Picker(selection: $selectedGroupStageIndex) {
Text("Voir toutes les poules").tag(-1)
ForEach(tournament.groupStages()) { groupStage in
Text(groupStage.groupStageTitle()).tag(groupStage.index)
}
} label: {
Text("\(tournament.groupStages().count.formatted()) poules")
}
}
}
ToolbarItem(placement: .topBarTrailing) {
Menu {
// menuAddGroupStage

@ -0,0 +1,22 @@
//
// RoundSettingsView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 31/03/2024.
//
import SwiftUI
struct RoundSettingsView: View {
@Environment(Tournament.self) var tournament: Tournament
var body: some View {
List {
}
}
}
#Preview {
RoundSettingsView()
.environment(Tournament.mock())
}

@ -7,52 +7,6 @@
import SwiftUI
protocol Selectable {
func selectionLabel() -> String
}
extension Round: Selectable {
func selectionLabel() -> String {
roundTitle()
}
}
struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
@Binding var selectedDestination: T?
let destinations: [T]
var body: some View {
ScrollView(.horizontal) {
HStack {
ForEach(destinations) { destination in
Button {
selectedDestination = destination
} label: {
Text(destination.selectionLabel())
}
.padding()
.background {
Capsule()
.fill(Color.white)
.opacity(selectedDestination?.id == destination.id ? 1.0 : 0.5)
}
.buttonStyle(.plain)
}
}
.fixedSize()
.padding(8)
}
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.background(Material.ultraThinMaterial)
.overlay {
VStack(spacing: 0) {
Spacer()
Divider()
}
}
}
}
struct RoundsView: View {
var tournament: Tournament
@State private var selectedRound: Round?
@ -65,11 +19,15 @@ struct RoundsView: View {
var body: some View {
VStack(spacing: 0) {
GenericDestinationPickerView(selectedDestination: $selectedRound, destinations: tournament.rounds())
if let selectedRound {
switch selectedRound {
case .none:
RoundSettingsView()
.navigationTitle("Réglages")
case .some(let selectedRound):
RoundView(round: selectedRound)
.navigationTitle(selectedRound.roundTitle())
}
}
.navigationTitle(selectedRound?.roundTitle() ?? "")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
}

@ -75,7 +75,7 @@ struct TournamentView: View {
case .inscription:
InscriptionManagerView(tournament: tournament)
case .groupStage:
GroupStagesView()
GroupStagesView(tournament: tournament)
case .round:
RoundsView(tournament: tournament)
}

Loading…
Cancel
Save