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