Laurent 2 years ago
commit b8a62f079e
  1. 2
      PadelClub/Views/Event/EventCreationView.swift
  2. 2
      PadelClub/Views/Navigation/Agenda/ActivityView.swift
  3. 97
      PadelClub/Views/Navigation/Agenda/CalendarView.swift
  4. 33
      PadelClub/Views/Navigation/Agenda/EventListView.swift

@ -14,7 +14,7 @@ struct EventCreationView: View {
@Environment(NavigationViewModel.self) private var navigation: NavigationViewModel
@State private var eventType: EventType = .approvedTournament
@State private var animationType: AnimationType = .upAndDown
@State private var startingDate: Date = Date().tomorrowAtNine
@State var startingDate: Date = Date().tomorrowAtNine
@State private var duration: Int = 3
@State private var eventName: String = ""
@State var tournaments: [Tournament] = []

@ -80,7 +80,7 @@ struct ActivityView: View {
} else if isGatheringFederalTournaments {
ProgressView()
} else {
if tournaments.isEmpty {
if tournaments.isEmpty && viewStyle == .list {
if searchText.isEmpty == false {
ContentUnavailableView.search(text: searchText)
} else if filterEnabled {

@ -13,20 +13,19 @@
import SwiftUI
struct CalendarView: View {
@Environment(NavigationViewModel.self) var navigation: NavigationViewModel
let date: Date
let tournaments: [FederalTournamentHolder]
let daysOfWeek = Date.capitalizedFirstLettersOfWeekdays
let columns = Array(repeating: GridItem(.flexible()), count: 7)
let color = Color.master
@State private var days: [Date] = []
@State private var counts = [Int : Int]()
// Extension properties to display selected day's workouts
@State private var selectedDay: Date?
@State private var tournamentsByDay: [FederalTournamentHolder] = []
@State private var newTournament: Tournament?
@ViewBuilder
var body: some View {
let color = Color.blue
VStack {
HStack {
ForEach(daysOfWeek.indices, id: \.self) { index in
@ -38,18 +37,55 @@ struct CalendarView: View {
}
LazyVGrid(columns: columns) {
ForEach(days, id: \.self) { day in
_dayView(day)
}
}
}
.sheet(item: $newTournament) { tournament in
EventCreationView(startingDate: tournament.startDate, tournaments: [tournament])
.environment(navigation)
.tint(.master)
}
.onAppear {
days = date.calendarDisplayDays
setupCounts()
}
.onChange(of: date) {
days = date.calendarDisplayDays
setupCounts()
}
}
@ViewBuilder
private func _dayView(_ day: Date) -> some View {
if day.monthInt != date.monthInt {
Text("")
} else {
Menu {
Button("Créer un tournoi") {
let tournament = Tournament.newEmptyInstance()
tournament.startDate = day.atNine()
newTournament = tournament
}
let tournamentsByDay = tournaments.filter { $0.startDate.dayInt == day.dayInt }
ForEach(tournamentsByDay, id: \.holderId) { tournamentHolder in
if let tournament = tournamentHolder as? Tournament {
Button(tournament.tournamentTitle()) {
navigation.path.append(tournament)
}
}
}
} label: {
Text(day.formatted(.dateTime.day()))
.fontWeight(.bold)
.foregroundStyle(.secondary)
.foregroundStyle(.white)
.frame(maxWidth: .infinity, minHeight: 40)
.background(
Circle()
.foregroundStyle(
Date.now.startOfDay == day.startOfDay
? .red.opacity(counts[day.dayInt] != nil ? 0.8 : 0.3)
? .green.opacity(counts[day.dayInt] != nil ? 0.8 : 0.3)
: color.opacity(counts[day.dayInt] != nil ? 0.8 : 0.3)
)
)
@ -65,52 +101,19 @@ struct CalendarView: View {
.offset(x: 5, y: 5)
}
}
.onTapGesture {
// Used in the ExtendedProject branch
if let count = counts[day.dayInt], count > 0 {
selectedDay = day
} else {
selectedDay = nil
}
}
}
}
}
}
.onAppear {
days = date.calendarDisplayDays
setupCounts()
selectedDay = nil // Used to present list of workouts when tapped
}
.onChange(of: date) {
days = date.calendarDisplayDays
setupCounts()
selectedDay = nil // Used to present list of workouts when tapped
}
.onChange(of: selectedDay) {
// Will filter the workouts for the specific day and activity is selected
if let selectedDay {
tournamentsByDay = tournaments.filter {$0.startDate.dayInt == selectedDay.dayInt}
}
.buttonStyle(.plain)
}
//
// if let selectedDay {
// // Presents the list of workouts for the selected day and activity
// ForEach(tournamentsByDay) { tournament in
// NavigationLink(value: tournament) {
// HStack {
// Text(tournament.tournamentTitle())
// Spacer()
// Text(tournament.sortedTeams().count.formatted())
// }
// }
// }
// }
}
func setupCounts() {
let filteredTournaments = tournaments
let mappedItems = filteredTournaments.map{($0.startDate.dayInt, $0.tournaments.count)}
let mappedItems = filteredTournaments.flatMap { tournamentHolder in
(0..<tournamentHolder.dayDuration).map({ dayDuration in
(tournamentHolder.startDate.dayInt + dayDuration, tournamentHolder.tournaments.count)
})
}
counts = Dictionary(mappedItems, uniquingKeysWith: +)
}
}

@ -15,7 +15,8 @@ struct EventListView: View {
var body: some View {
let groupedTournamentsByDate = Dictionary(grouping: tournaments) { $0.startDate.startOfMonth }
switch viewStyle {
case .list:
ForEach(groupedTournamentsByDate.keys.sorted(by: <), id: \.self) { section in
if let _tournaments = groupedTournamentsByDate[section]?.sorted(by: \.startDate) {
Section {
@ -36,7 +37,37 @@ struct EventListView: View {
.headerProminence(.increased)
}
}
case .calendar:
ForEach(_nextMonths(), id: \.self) { section in
let _tournaments = groupedTournamentsByDate[section]?.sorted(by: \.startDate) ?? []
Section {
CalendarView(date: section, tournaments: _tournaments)
} header: {
HStack {
Text(section.monthYearFormatted)
Spacer()
let count = _tournaments.map { $0.tournaments.count }.reduce(0,+)
Text("\(count.formatted()) tournoi" + count.pluralSuffix)
}
}
.headerProminence(.increased)
}
}
}
private func _nextMonths() -> [Date] {
var result: [Date] = []
var currentDate = Date().startOfMonth
// Generate 100 future months
for _ in 0..<12 {
result.append(currentDate)
currentDate = Calendar.current.date(byAdding: .month, value: 1, to: currentDate)!
}
return result
}
private func _listView(_ tournaments: [FederalTournamentHolder]) -> some View {
ForEach(tournaments, id: \.holderId) { tournamentHolder in

Loading…
Cancel
Save