|
|
|
|
@ -16,6 +16,23 @@ struct PlanningView: View { |
|
|
|
|
@State private var timeSlots: [Date:[Match]] |
|
|
|
|
@State private var days: [Date] |
|
|
|
|
@State private var keys: [Date] |
|
|
|
|
@State private var filterOption: PlanningFilterOption = .byDefault |
|
|
|
|
|
|
|
|
|
enum PlanningFilterOption: Int, CaseIterable, Identifiable { |
|
|
|
|
var id: Int { self.rawValue } |
|
|
|
|
|
|
|
|
|
case byDefault |
|
|
|
|
case byCourt |
|
|
|
|
|
|
|
|
|
func localizedPlanningLabel() -> String { |
|
|
|
|
switch self { |
|
|
|
|
case .byCourt: |
|
|
|
|
return "Par terrain" |
|
|
|
|
case .byDefault: |
|
|
|
|
return "Par défaut" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
init(matches: [Match], selectedScheduleDestination: Binding<ScheduleDestination?>) { |
|
|
|
|
self.matches = matches |
|
|
|
|
@ -30,6 +47,24 @@ struct PlanningView: View { |
|
|
|
|
List { |
|
|
|
|
_bySlotView() |
|
|
|
|
} |
|
|
|
|
.toolbar(content: { |
|
|
|
|
ToolbarItem(placement: .topBarTrailing) { |
|
|
|
|
Menu { |
|
|
|
|
Picker(selection: $filterOption) { |
|
|
|
|
ForEach(PlanningFilterOption.allCases) { |
|
|
|
|
Text($0.localizedPlanningLabel()).tag($0) |
|
|
|
|
} |
|
|
|
|
} label: { |
|
|
|
|
Text("Option de filtrage") |
|
|
|
|
} |
|
|
|
|
.labelsHidden() |
|
|
|
|
.pickerStyle(.inline) |
|
|
|
|
} label: { |
|
|
|
|
Label("Filtrer", systemImage: "line.3.horizontal.decrease.circle") |
|
|
|
|
.symbolVariant(filterOption == .byCourt ? .fill : .none) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
.overlay { |
|
|
|
|
if matches.allSatisfy({ $0.startDate == nil }) { |
|
|
|
|
ContentUnavailableView { |
|
|
|
|
@ -53,7 +88,7 @@ struct PlanningView: View { |
|
|
|
|
ForEach(keys.filter({ $0.dayInt == day.dayInt }), id: \.self) { key in |
|
|
|
|
if let _matches = timeSlots[key] { |
|
|
|
|
DisclosureGroup { |
|
|
|
|
ForEach(_matches) { match in |
|
|
|
|
ForEach(_matches.sorted(by: filterOption == .byDefault ? \.computedOrder : \.courtIndexForSorting)) { match in |
|
|
|
|
NavigationLink { |
|
|
|
|
MatchDetailView(match: match, matchViewStyle: .sectionedStandardStyle) |
|
|
|
|
} label: { |
|
|
|
|
@ -98,7 +133,14 @@ struct PlanningView: View { |
|
|
|
|
Text(self._formattedMatchCount(matches.count)) |
|
|
|
|
} label: { |
|
|
|
|
Text(key.formatted(date: .omitted, time: .shortened)).font(.title).fontWeight(.semibold) |
|
|
|
|
Text(Set(matches.compactMap { $0.roundTitle() }).joined(separator: ", ")) |
|
|
|
|
let names = matches.sorted(by: \.computedOrder) |
|
|
|
|
.compactMap({ $0.roundTitle() }) |
|
|
|
|
.reduce(into: [String]()) { uniqueNames, name in |
|
|
|
|
if !uniqueNames.contains(name) { |
|
|
|
|
uniqueNames.append(name) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Text(names.joined(separator: ", ")) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|