You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
7.4 KiB
205 lines
7.4 KiB
//
|
|
// TournamentCashierView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 17/04/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import Combine
|
|
import PadelClubData
|
|
|
|
enum CashierDestination: Identifiable, Selectable, Equatable {
|
|
|
|
static func == (lhs: CashierDestination, rhs: CashierDestination) -> Bool {
|
|
return lhs.id == rhs.id
|
|
}
|
|
|
|
case summary
|
|
case groupStage(GroupStage)
|
|
case bracket(Round)
|
|
case all(Tournament)
|
|
|
|
var id: String {
|
|
switch self {
|
|
case .summary:
|
|
return String(describing: self)
|
|
case .all(let tournament):
|
|
return tournament.id
|
|
case .groupStage(let groupStage):
|
|
return groupStage.id
|
|
case .bracket(let round):
|
|
return round.id
|
|
}
|
|
}
|
|
|
|
func selectionLabel(index: Int) -> String {
|
|
switch self {
|
|
case .summary:
|
|
return "Bilan"
|
|
case .groupStage(let groupStage):
|
|
return groupStage.selectionLabel(index: index)
|
|
case .bracket(let round):
|
|
return round.selectionLabel(index: index)
|
|
case .all:
|
|
return "Tous"
|
|
}
|
|
}
|
|
|
|
func displayImageIfValueZero() -> Bool {
|
|
return true
|
|
}
|
|
|
|
func badgeValue() -> Int? {
|
|
switch self {
|
|
case .summary:
|
|
return nil
|
|
case .groupStage(let groupStage):
|
|
if groupStage.tournamentObject()?.isFree() == true {
|
|
return groupStage.unsortedPlayers().filter({ $0.hasArrived == false }).count
|
|
}
|
|
return groupStage.unsortedPlayers().filter({ $0.hasPaid() == false }).count
|
|
case .bracket(let round):
|
|
let playerRegistrations: [PlayerRegistration] = round.seeds().flatMap { $0.unsortedPlayers() }
|
|
if round.tournamentObject()?.isFree() == true {
|
|
return playerRegistrations.filter({ $0.hasArrived == false }).count
|
|
}
|
|
return playerRegistrations.filter({ $0.hasPaid() == false }).count
|
|
case .all(_):
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func badgeValueColor() -> Color? {
|
|
return nil
|
|
}
|
|
|
|
func badgeImage() -> Badge? {
|
|
switch self {
|
|
case .summary:
|
|
return nil
|
|
case .all:
|
|
return nil
|
|
default:
|
|
return .checkmark
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
struct TournamentCashierView: View {
|
|
var tournament: Tournament
|
|
@State private var selectedDestination: CashierDestination?
|
|
@StateObject private var cashierViewModel: CashierViewModel = CashierViewModel()
|
|
var allDestinations: [CashierDestination]
|
|
|
|
init(tournament: Tournament) {
|
|
self.tournament = tournament
|
|
|
|
var allDestinations : [CashierDestination] = []
|
|
let tournamentHasEnded = tournament.hasEnded()
|
|
if tournamentHasEnded {
|
|
allDestinations.append(.summary)
|
|
}
|
|
|
|
let all = CashierDestination.all(tournament)
|
|
allDestinations.append(all)
|
|
|
|
let destinations: [CashierDestination] = tournament.groupStages().map { CashierDestination.groupStage($0) }
|
|
allDestinations.append(contentsOf: destinations)
|
|
tournament.rounds().forEach { round in
|
|
if round.seeds().isEmpty == false {
|
|
allDestinations.append(CashierDestination.bracket(round))
|
|
}
|
|
}
|
|
|
|
if tournamentHasEnded == false {
|
|
allDestinations.append(.summary)
|
|
}
|
|
|
|
self.allDestinations = allDestinations
|
|
|
|
_selectedDestination = .init(wrappedValue: all)
|
|
|
|
// if tournament.hasEnded() {
|
|
// if tournament.players().anySatisfy({ $0.hasPaid() == false }) == false {
|
|
// _selectedDestination = .init(wrappedValue: .summary)
|
|
// } else {
|
|
// _selectedDestination = .init(wrappedValue: all)
|
|
// }
|
|
// } else {
|
|
// let gs = tournament.getActiveGroupStage()
|
|
// if let gs, let destination = allDestinations.first(where: { $0.id == gs.id }) {
|
|
// _selectedDestination = State(wrappedValue: destination)
|
|
// } else if let rs = tournament.getActiveRound(withSeeds: true), let destination = allDestinations.first(where: { $0.id == rs.id }) {
|
|
// _selectedDestination = State(wrappedValue: destination)
|
|
// }
|
|
// }
|
|
}
|
|
|
|
var body: some View {
|
|
if let store = self.tournament.tournamentStore {
|
|
VStack(spacing: 0) {
|
|
GenericDestinationPickerView(selectedDestination: $selectedDestination, destinations: allDestinations, nilDestinationIsValid: true)
|
|
switch selectedDestination {
|
|
case .none:
|
|
CashierSettingsView(tournament: tournament)
|
|
case .some(let selectedCall):
|
|
switch selectedCall {
|
|
case .summary:
|
|
CashierDetailView(tournament: tournament).id(selectedCall.id)
|
|
case .groupStage(let groupStage):
|
|
CashierView(tournament: tournament, teams: groupStage.teams()).id(selectedCall.id)
|
|
.searchable(text: $cashierViewModel.searchText, isPresented: $cashierViewModel.isSearching, placement: .navigationBarDrawer(displayMode: .always), prompt: Text("Chercher un joueur"))
|
|
case .bracket(let round):
|
|
CashierView(tournament: tournament, teams: round.seeds()).id(selectedCall.id)
|
|
.searchable(text: $cashierViewModel.searchText, isPresented: $cashierViewModel.isSearching, placement: .navigationBarDrawer(displayMode: .always), prompt: Text("Chercher un joueur"))
|
|
case .all(let tournament):
|
|
CashierView(tournament: tournament, teams: tournament.selectedSortedTeams()).id(selectedCall.id)
|
|
.searchable(text: $cashierViewModel.searchText, isPresented: $cashierViewModel.isSearching, placement: .navigationBarDrawer(displayMode: .always), prompt: Text("Chercher un joueur"))
|
|
}
|
|
}
|
|
}
|
|
.environment(tournament)
|
|
.environmentObject(store)
|
|
.environmentObject(cashierViewModel)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbarBackground(.visible, for: .navigationBar)
|
|
.navigationTitle(tournament.isFree() ? "Présence" : "Encaissement")
|
|
.ifAvailableiOS26 {
|
|
if #available(iOS 26.0, *) {
|
|
$0.navigationSubtitle(tournament.tournamentTitle())
|
|
}
|
|
}
|
|
} else {
|
|
Text("no store")
|
|
}
|
|
}
|
|
}
|
|
|
|
//#Preview {
|
|
// TournamentCashierView(tournament: Tournament.mock())
|
|
//}
|
|
|
|
//class DebouncedObject: ObservableObject {
|
|
// @Published var searchText: String = "" {
|
|
// didSet {
|
|
// debounceSearchTextPublisher.send(searchText)
|
|
// }
|
|
// }
|
|
//
|
|
// private var debounceSearchTextPublisher = PassthroughSubject<String, Never>()
|
|
// private var cancellables = Set<AnyCancellable>()
|
|
//
|
|
// init() {
|
|
// debounceSearchTextPublisher
|
|
// .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
|
|
// .sink { [weak self] in self?.performSearch(with: $0) }
|
|
// .store(in: &cancellables)
|
|
// }
|
|
//
|
|
// private func performSearch(with text: String) {
|
|
// // Perform the search with the debounced text
|
|
// print("Performing search with text: \(text)")
|
|
// }
|
|
//}
|
|
|