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.
265 lines
9.5 KiB
265 lines
9.5 KiB
//
|
|
// ActivityView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 29/02/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct ActivityView: View {
|
|
@EnvironmentObject var dataStore: DataStore
|
|
|
|
@State private var searchText: String = ""
|
|
@State private var agendaDestination: AgendaDestination = .activity
|
|
|
|
@State private var filterEnabled: Bool = false
|
|
@State private var presentToolbar: Bool = false
|
|
@State private var newTournament: Tournament?
|
|
@State private var viewStyle: AgendaDestination.ViewStyle = .list
|
|
@State private var federalTournaments: [FederalTournament] = []
|
|
@State private var isGatheringFederalTournaments: Bool = false
|
|
@Binding var selectedTab: TabDestination?
|
|
|
|
var runningTournaments: [FederalTournamentHolder] {
|
|
dataStore.tournaments.filter({ $0.endDate == nil })
|
|
}
|
|
|
|
var endedTournaments: [Tournament] {
|
|
dataStore.tournaments.filter({ $0.endDate != nil }).sorted(using: SortDescriptor(\.startDate, order: .reverse))
|
|
}
|
|
|
|
func _activityStatus() -> String? {
|
|
let tournaments = tournaments
|
|
if tournaments.isEmpty && filterEnabled == false {
|
|
return nil
|
|
} else {
|
|
let count = tournaments.map { $0.tournaments.count }.reduce(0,+)
|
|
return "\(count) tournoi" + count.pluralSuffix
|
|
}
|
|
}
|
|
|
|
var tournaments: [FederalTournamentHolder] {
|
|
switch agendaDestination {
|
|
case .activity:
|
|
runningTournaments
|
|
case .history:
|
|
endedTournaments
|
|
case .tenup:
|
|
federalTournaments
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
List {
|
|
Section {
|
|
AgendaDestinationPickerView(agendaDestination: $agendaDestination)
|
|
}
|
|
|
|
switch agendaDestination {
|
|
case .activity:
|
|
EventListView(tournaments: runningTournaments, viewStyle: viewStyle)
|
|
case .history:
|
|
EventListView(tournaments: endedTournaments, viewStyle: viewStyle)
|
|
case .tenup:
|
|
EventListView(tournaments: federalTournaments, viewStyle: viewStyle)
|
|
}
|
|
}
|
|
.overlay {
|
|
if isGatheringFederalTournaments {
|
|
ProgressView()
|
|
} else {
|
|
if tournaments.isEmpty {
|
|
if searchText.isEmpty == false {
|
|
ContentUnavailableView.search(text: searchText)
|
|
} else if filterEnabled {
|
|
ContentUnavailableView {
|
|
Text("Aucun résultat")
|
|
} description: {
|
|
Text("Description du filtre")
|
|
} actions: {
|
|
RowButtonView(title: "supprimer le filtre") {
|
|
filterEnabled.toggle()
|
|
}
|
|
}
|
|
} else {
|
|
_dataEmptyView()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//.searchable(text: $searchText)
|
|
.onAppear { presentToolbar = true }
|
|
.onDisappear { presentToolbar = false }
|
|
.sheet(item: $newTournament) { tournament in
|
|
EventCreationView(tournaments: [tournament])
|
|
}
|
|
.refreshable {
|
|
if agendaDestination == .tenup {
|
|
federalTournaments.removeAll()
|
|
_gatherFederalTournaments()
|
|
}
|
|
}
|
|
.task {
|
|
if agendaDestination == .tenup
|
|
&& dataStore.clubs.isEmpty == false
|
|
&& federalTournaments.isEmpty {
|
|
_gatherFederalTournaments()
|
|
}
|
|
}
|
|
.onChange(of: agendaDestination) {
|
|
if agendaDestination == .tenup
|
|
&& dataStore.clubs.isEmpty == false
|
|
&& federalTournaments.isEmpty {
|
|
_gatherFederalTournaments()
|
|
}
|
|
}
|
|
.toolbar {
|
|
if presentToolbar {
|
|
ToolbarItem(placement: .status) {
|
|
VStack(spacing: -2) {
|
|
if filterEnabled {
|
|
Text("filtre actif")
|
|
}
|
|
if let _activityStatus = _activityStatus() {
|
|
Text(_activityStatus)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
.font(.footnote)
|
|
}
|
|
|
|
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
Button {
|
|
switch viewStyle {
|
|
case .list:
|
|
viewStyle = .calendar
|
|
case .calendar:
|
|
viewStyle = .list
|
|
}
|
|
} label: {
|
|
Image(systemName: "calendar.circle")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(minHeight: 28)
|
|
}
|
|
.symbolVariant(viewStyle == .calendar ? .fill : .none)
|
|
|
|
//
|
|
// Button {
|
|
// filterEnabled.toggle()
|
|
// } label: {
|
|
// Image(systemName: "line.3.horizontal.decrease.circle")
|
|
// .resizable()
|
|
// .scaledToFit()
|
|
// .frame(minHeight: 28)
|
|
// }
|
|
// .symbolVariant(filterEnabled ? .fill : .none)
|
|
}
|
|
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
Button {
|
|
newTournament = Tournament.newEmptyInstance()
|
|
|
|
} label: {
|
|
Image(systemName: "plus.circle.fill")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(minHeight: 28)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle(TabDestination.activity.title)
|
|
.navigationDestination(for: Tournament.self) { tournament in
|
|
TournamentView()
|
|
.environment(tournament)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func _gatherFederalTournaments() {
|
|
isGatheringFederalTournaments = true
|
|
Task {
|
|
await dataStore.clubs.filter { $0.code != nil }.concurrentForEach { club in
|
|
federalTournaments += await NetworkFederalService.shared.getClubFederalTournaments(page: 0, tournaments: [], club: club.name, codeClub: club.code!, startDate: .now.startOfMonth)
|
|
}
|
|
isGatheringFederalTournaments = false
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func _dataEmptyView() -> some View {
|
|
switch agendaDestination {
|
|
case .activity:
|
|
_runningEmptyView()
|
|
case .history:
|
|
_endedEmptyView()
|
|
case .tenup:
|
|
_tenupEmptyView()
|
|
}
|
|
}
|
|
|
|
private func _runningEmptyView() -> some View {
|
|
ContentUnavailableView {
|
|
Label {
|
|
Text("Bienvenue sur Padel Club")
|
|
.font(.largeTitle)
|
|
} icon: {
|
|
Image(.padelClubLogoFondclairTransparent)
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(width: 128)
|
|
}
|
|
} description: {
|
|
Text("Aucun événement en cours ou à venir dans votre agenda.")
|
|
} actions: {
|
|
RowButtonView(title: "Créer un nouvel événement") {
|
|
newTournament = Tournament.newEmptyInstance()
|
|
}
|
|
RowButtonView(title: "Importer via Tenup") {
|
|
agendaDestination = .tenup
|
|
}
|
|
}
|
|
}
|
|
|
|
private func _endedEmptyView() -> some View {
|
|
ContentUnavailableView {
|
|
Label("Aucun tournoi terminé", systemImage: "shield.slash")
|
|
} description: {
|
|
Text("Vos tournois terminés seront listés ici.")
|
|
}
|
|
}
|
|
|
|
private func _tenupEmptyView() -> some View {
|
|
if dataStore.clubs.isEmpty {
|
|
ContentUnavailableView {
|
|
Label("Aucun tournoi", systemImage: "shield.slash")
|
|
} description: {
|
|
Text("Pour voir vos tournois tenup ici, indiquez vos clubs préférés.")
|
|
} actions: {
|
|
RowButtonView(title: "Choisir mes clubs préférés") {
|
|
selectedTab = .umpire
|
|
}
|
|
}
|
|
} else {
|
|
ContentUnavailableView {
|
|
Label("Aucun tournoi", systemImage: "shield.slash")
|
|
} description: {
|
|
Text("Aucun tournoi n'a pu être récupéré via tenup.")
|
|
} actions: {
|
|
RowButtonView(title: "Rafraîchir") {
|
|
_gatherFederalTournaments()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#Preview {
|
|
ActivityView(selectedTab: .constant(.activity))
|
|
.environmentObject(DataStore.shared)
|
|
}
|
|
|