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.
 
 
PadelClub/PadelClub/Views/Planning/SchedulerView.swift

197 lines
7.9 KiB

//
// SchedulerView.swift
// PadelClub
//
// Created by Razmig Sarkissian on 07/04/2024.
//
import SwiftUI
import LeStorage
import PadelClubData
extension GroupStage: Schedulable {
func titleLabel() -> String {
self.groupStageTitle()
}
}
extension Round: Schedulable {
func titleLabel() -> String {
self.roundTitle()
}
}
struct SchedulerView: View {
@EnvironmentObject var dataStore: DataStore
var tournament: Tournament
var destination: ScheduleDestination
var tournamentStore: TournamentStore? {
return self.tournament.tournamentStore
}
var body: some View {
@Bindable var tournament = tournament
List {
switch destination {
case .scheduleGroupStage:
Section {
MatchFormatPickingView(matchFormat: $tournament.groupStageMatchFormat) {
Task {
tournament.matchScheduler()?.updateSchedule(tournament: tournament)
}
}
.onChange(of: tournament.groupStageMatchFormat) {
let groupStages = tournament.allGroupStages()
groupStages.forEach { groupStage in
groupStage.updateMatchFormat(tournament.groupStageMatchFormat)
}
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
try self.tournamentStore?.groupStages.addOrUpdate(contentOfs: groupStages)
} catch {
Logger.error(error)
}
}
} footer: {
if tournament.isAnimation() == false {
if tournament.groupStageMatchFormat.weight > tournament.groupStageSmartMatchFormat().weight {
Button {
tournament.groupStageMatchFormat = tournament.groupStageSmartMatchFormat()
} label: {
Text("devrait être joué au moins en " + tournament.groupStageSmartMatchFormat().format + ", ") + Text("modifier ?").underline().foregroundStyle(.master)
}
.buttonStyle(.plain)
}
}
}
ForEach(tournament.allGroupStages()) {
GroupStageScheduleEditorView(groupStage: $0, tournament: tournament)
.id(UUID())
}
case .scheduleBracket:
ForEach(tournament.rounds()) { round in
_roundView(round)
}
default:
EmptyView()
}
}
.headerProminence(.increased)
.monospacedDigit()
.onChange(of: tournament.groupStageMatchFormat) {
let groupStages = tournament.groupStages()
tournament.groupStages().forEach { groupStage in
groupStage.updateMatchFormat(tournament.groupStageMatchFormat)
}
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
try self.tournamentStore?.groupStages.addOrUpdate(contentOfs: groupStages)
} catch {
Logger.error(error)
}
}
}
@ViewBuilder
func _roundView(_ round: Round) -> some View {
Section {
NavigationLink {
RoundScheduleEditorView(round: round, tournament: tournament)
.navigationTitle(round.titleLabel())
.environment(tournament)
} label: {
LabeledContent {
Text(round.matchFormat.format)//.font(.title2)
} label: {
if let startDate = round.getStartDate() {
HStack {
Text(startDate.formattedAsHourMinute()).font(.title2).fontWeight(.semibold)
if let estimatedEndDate = round.estimatedEndDate(tournament.additionalEstimationDuration) {
Image(systemName: "arrowshape.forward.fill")
Text(estimatedEndDate.formattedAsHourMinute()).font(.title2).fontWeight(.semibold)
}
}
Text(startDate.formattedAsDate())
} else {
Text("Aucun horaire")
}
}
}
} header: {
Text(round.titleLabel())
} footer: {
if tournament.isAnimation() == false {
let federalFormat = tournament.roundSmartMatchFormat(round.index)
if round.matchFormat.weight > federalFormat.weight {
Button {
round.updateMatchFormatAndAllMatches(federalFormat)
do {
try self.tournamentStore?.rounds.addOrUpdate(instance: round)
} catch {
Logger.error(error)
}
} label: {
Text("devrait être joué au moins en " + federalFormat.format + ", ") + Text("modifier ?").underline().foregroundStyle(.master)
}
.buttonStyle(.plain)
}
}
}
if round.index != 0 {
Section {
NavigationLink {
LoserRoundScheduleEditorView(upperRound: round, tournament: tournament)
.environment(tournament)
} label: {
LabeledContent {
let count = round.loserRounds().filter({ $0.isDisabled() == false }).count
Text(count.formatted() + " tour" + count.pluralSuffix)
} label: {
if let startDate = round.getLoserRoundStartDate() {
HStack {
Text(startDate.formattedAsHourMinute()).font(.title3)
if let estimatedEndDate = round.estimatedLoserRoundEndDate(tournament.additionalEstimationDuration) {
Image(systemName: "arrowshape.forward.fill")
Text(estimatedEndDate.formattedAsHourMinute()).font(.title3)
}
}
Text(startDate.formattedAsDate())
} else {
Text("Aucun horaire")
}
}
}
} header: {
Text("Match de classement \(round.roundTitle(.short))")
} footer: {
if tournament.isAnimation() == false, round.index == 1, let semi = round.loserRounds().first {
let federalFormat = tournament.loserBracketSmartMatchFormat(1)
if semi.matchFormat.weight > federalFormat.weight {
Button {
round.updateMatchFormatAndAllMatches(federalFormat)
do {
try self.tournamentStore?.rounds.addOrUpdate(instance: round)
} catch {
Logger.error(error)
}
} label: {
Text("devrait être joué au moins en " + federalFormat.format + ", ") + Text("modifier ?").underline().foregroundStyle(.master)
}
.buttonStyle(.plain)
}
}
}
}
}
}
//#Preview {
// SchedulerView(tournament: Tournament.mock(), destination: .scheduleBracket)
//}