fix issue with scheduler fix issue on seeding add the ability to export / import quickly a list of players from padel club exportmultistore
parent
b9f2048546
commit
df56b384e0
@ -0,0 +1,32 @@ |
|||||||
|
// |
||||||
|
// DateInterval.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Razmig Sarkissian on 19/04/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import Foundation |
||||||
|
import LeStorage |
||||||
|
|
||||||
|
struct DateInterval: Identifiable, Codable { |
||||||
|
var id: String = Store.randomId() |
||||||
|
|
||||||
|
let startDate: Date |
||||||
|
let endDate: Date |
||||||
|
|
||||||
|
var range: Range<Date> { |
||||||
|
startDate..<endDate |
||||||
|
} |
||||||
|
|
||||||
|
func isSingleDay() -> Bool { |
||||||
|
Calendar.current.isDate(startDate, inSameDayAs: endDate) |
||||||
|
} |
||||||
|
|
||||||
|
func isDateInside(_ date: Date) -> Bool { |
||||||
|
date >= startDate && date <= endDate |
||||||
|
} |
||||||
|
|
||||||
|
func isDateOutside(_ date: Date) -> Bool { |
||||||
|
date <= startDate && date <= endDate && date >= startDate && date >= endDate |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,157 @@ |
|||||||
|
// |
||||||
|
// CourtAvailabilitySettingsView.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Razmig Sarkissian on 19/04/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
|
||||||
|
struct CourtAvailabilitySettingsView: View { |
||||||
|
@Environment(Tournament.self) var tournament: Tournament |
||||||
|
@State private var courtsUnavailability: [Int: [DateInterval]] = [Int:[DateInterval]]() |
||||||
|
@State private var showingPopover: Bool = false |
||||||
|
@State private var courtIndex: Int = 0 |
||||||
|
@State private var startDate: Date = Date() |
||||||
|
@State private var endDate: Date = Date() |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
List { |
||||||
|
let keys = courtsUnavailability.keys.sorted(by: \.self) |
||||||
|
ForEach(keys, id: \.self) { key in |
||||||
|
if let dates = courtsUnavailability[key] { |
||||||
|
Section { |
||||||
|
ForEach(dates) { dateInterval in |
||||||
|
HStack { |
||||||
|
VStack(alignment: .leading, spacing: 0) { |
||||||
|
Text(dateInterval.startDate.localizedTime()).font(.largeTitle) |
||||||
|
Text(dateInterval.startDate.localizedDay()).font(.caption) |
||||||
|
} |
||||||
|
Spacer() |
||||||
|
Image(systemName: "arrowshape.forward.fill") |
||||||
|
.tint(.master) |
||||||
|
Spacer() |
||||||
|
VStack(alignment: .trailing, spacing: 0) { |
||||||
|
Text(dateInterval.endDate.localizedTime()).font(.largeTitle) |
||||||
|
Text(dateInterval.endDate.localizedDay()).font(.caption) |
||||||
|
} |
||||||
|
} |
||||||
|
.contextMenu(menuItems: { |
||||||
|
Button("dupliquer") { |
||||||
|
|
||||||
|
} |
||||||
|
Button("éditer") { |
||||||
|
|
||||||
|
} |
||||||
|
Button("effacer") { |
||||||
|
|
||||||
|
} |
||||||
|
}) |
||||||
|
.swipeActions { |
||||||
|
Button(role: .destructive) { |
||||||
|
courtsUnavailability[key]?.removeAll(where: { $0.id == dateInterval.id }) |
||||||
|
} label: { |
||||||
|
LabelDelete() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} header: { |
||||||
|
Text("Terrain #\(key + 1)") |
||||||
|
} |
||||||
|
.headerProminence(.increased) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.toolbar { |
||||||
|
ToolbarItem(placement: .topBarTrailing) { |
||||||
|
Button { |
||||||
|
showingPopover = true |
||||||
|
} label: { |
||||||
|
Image(systemName: "plus.circle.fill") |
||||||
|
.resizable() |
||||||
|
.scaledToFit() |
||||||
|
.frame(minHeight: 28) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.onDisappear { |
||||||
|
tournament.courtsUnavailability = courtsUnavailability |
||||||
|
} |
||||||
|
.navigationBarTitleDisplayMode(.inline) |
||||||
|
.toolbarBackground(.visible, for: .navigationBar) |
||||||
|
.navigationTitle("Créneaux") |
||||||
|
.popover(isPresented: $showingPopover) { |
||||||
|
NavigationStack { |
||||||
|
Form { |
||||||
|
Section { |
||||||
|
CourtPicker(title: "Terrain", selection: $courtIndex, maxCourt: 3) |
||||||
|
} |
||||||
|
|
||||||
|
Section { |
||||||
|
DatePicker("Début", selection: $startDate) |
||||||
|
DatePicker("Fin", selection: $endDate) |
||||||
|
} footer: { |
||||||
|
Button("jour entier") { |
||||||
|
startDate = startDate.startOfDay |
||||||
|
endDate = endDate.endOfDay() |
||||||
|
} |
||||||
|
.buttonStyle(.borderless) |
||||||
|
.underline() |
||||||
|
} |
||||||
|
} |
||||||
|
.toolbar { |
||||||
|
Button("Valider") { |
||||||
|
let dateInterval = DateInterval(startDate: startDate, endDate: endDate) |
||||||
|
var courtUnavailability = courtsUnavailability[courtIndex] ?? [DateInterval]() |
||||||
|
courtUnavailability.append(dateInterval) |
||||||
|
courtsUnavailability[courtIndex] = courtUnavailability |
||||||
|
showingPopover = false |
||||||
|
} |
||||||
|
} |
||||||
|
.navigationBarTitleDisplayMode(.inline) |
||||||
|
.toolbarBackground(.visible, for: .navigationBar) |
||||||
|
.navigationTitle("Nouveau créneau") |
||||||
|
} |
||||||
|
.onAppear { |
||||||
|
UIDatePicker.appearance().minuteInterval = 5 |
||||||
|
} |
||||||
|
.onDisappear { |
||||||
|
UIDatePicker.appearance().minuteInterval = 1 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
struct CourtPicker: View { |
||||||
|
let title: String |
||||||
|
@Binding var selection: Int |
||||||
|
let maxCourt: Int |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
Picker(title, selection: $selection) { |
||||||
|
ForEach(0..<maxCourt, id: \.self) { |
||||||
|
Text("Terrain #\($0 + 1)") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#Preview { |
||||||
|
CourtAvailabilitySettingsView() |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
LabeledContent { |
||||||
|
// switch dayIndex { |
||||||
|
// case 1: |
||||||
|
// StepperView(count: $dayTwo, maximum: tournament.courtCount) |
||||||
|
// case 2: |
||||||
|
// StepperView(count: $dayThree, maximum: tournament.courtCount) |
||||||
|
// default: |
||||||
|
// StepperView(count: $dayOne, maximum: tournament.courtCount) |
||||||
|
// } |
||||||
|
// } label: { |
||||||
|
// Text("Terrains maximum") |
||||||
|
// Text(tournament.startDate.formatted(.dateTime.weekday(.wide)) + " + \(dayIndex)") |
||||||
|
// } |
||||||
|
*/ |
||||||
Loading…
Reference in new issue