@ -15,9 +15,6 @@ struct CourtAvailabilitySettingsView: View {
let event : Event
@ State private var showingPopover : Bool = false
@ State private var courtIndex : Int = 0
@ State private var startDate : Date = Date ( )
@ State private var endDate : Date = Date ( )
@ State private var editingSlot : DateInterval ?
var courtsUnavailability : [ Int : [ DateInterval ] ] {
@ -45,10 +42,6 @@ struct CourtAvailabilitySettingsView: View {
}
Button ( " éditer " ) {
editingSlot = dateInterval
courtIndex = dateInterval . courtIndex
startDate = dateInterval . startDate
endDate = dateInterval . endDate
showingPopover = true
}
Button ( " effacer " , role : . destructive ) {
do {
@ -110,8 +103,6 @@ struct CourtAvailabilitySettingsView: View {
Text ( " Vous pouvez précisez l'indisponibilité d'une ou plusieurs terrains, que ce soit pour une journée entière ou un créneau précis. " )
} actions : {
RowButtonView ( " Ajouter une indisponibilité " , systemImage : " plus.circle.fill " ) {
startDate = tournament . startDate
endDate = tournament . startDate . addingTimeInterval ( 5400 )
showingPopover = true
}
}
@ -120,8 +111,6 @@ struct CourtAvailabilitySettingsView: View {
. toolbar {
ToolbarItem ( placement : . topBarTrailing ) {
BarButtonView ( " Ajouter une indisponibilité " , icon : " plus.circle.fill " ) {
startDate = tournament . startDate
endDate = tournament . startDate . addingTimeInterval ( 5400 )
showingPopover = true
}
}
@ -130,6 +119,58 @@ struct CourtAvailabilitySettingsView: View {
. toolbarBackground ( . visible , for : . navigationBar )
. navigationTitle ( " Créneau indisponible " )
. sheet ( isPresented : $ showingPopover ) {
CourtAvailabilityEditorView ( event : event )
}
. sheet ( item : $ editingSlot ) { editingSlot in
CourtAvailabilityEditorView ( editingSlot : editingSlot , event : event )
}
}
}
struct CourtPicker : View {
@ Environment ( Tournament . self ) var tournament : Tournament
let title : String
@ Binding var selection : Int
let maxCourt : Int
var body : some View {
Picker ( title , selection : $ selection ) {
ForEach ( 0. . < maxCourt , id : \ . self ) {
Text ( tournament . courtName ( atIndex : $0 ) )
}
}
}
}
struct CourtAvailabilityEditorView : View {
@ Environment ( Tournament . self ) var tournament : Tournament
@ EnvironmentObject var dataStore : DataStore
@ Environment ( \ . dismiss ) private var dismiss
var editingSlot : DateInterval ?
let event : Event
@ State private var courtIndex : Int
@ State private var startDate : Date
@ State private var endDate : Date
init ( editingSlot : DateInterval , event : Event ) {
self . editingSlot = editingSlot
self . event = event
_courtIndex = . init ( wrappedValue : editingSlot . courtIndex )
_startDate = . init ( wrappedValue : editingSlot . startDate )
_endDate = . init ( wrappedValue : editingSlot . endDate )
}
init ( event : Event ) {
self . event = event
_courtIndex = . init ( wrappedValue : 0 )
let startDate = event . eventStartDate ( )
_startDate = . init ( wrappedValue : event . eventStartDate ( ) )
_endDate = . init ( wrappedValue : startDate . addingTimeInterval ( 5400 ) )
}
var body : some View {
NavigationStack {
Form {
Section {
@ -153,9 +194,21 @@ struct CourtAvailabilitySettingsView: View {
} footer : {
FooterButtonView ( " jour entier " ) {
startDate = startDate . startOfDay
endDate = startDate . endOfDay ( )
endDate = startDate . tomorrowAtNine . startOfDay
}
}
Section {
DateAdjusterView ( date : $ startDate )
} header : {
Text ( " Modifier rapidement l'horaire de début " )
}
Section {
DateAdjusterView ( date : $ endDate )
} header : {
Text ( " Modifier rapidement l'horaire de fin " )
}
}
. toolbar {
ButtonValidateView {
@ -176,40 +229,49 @@ struct CourtAvailabilitySettingsView: View {
Logger . error ( error )
}
}
showingPopover = false
dismiss ( )
}
ToolbarItem ( placement : . topBarLeading ) {
Button ( " Annuler " , role : . cancel ) {
dismiss ( )
}
}
}
. navigationBarTitleDisplayMode ( . inline )
. toolbarBackground ( . visible , for : . navigationBar )
. navigationTitle ( " Nouveau créneau " )
. navigationTitle ( _navigationTitle ( ) )
. tint ( . master )
}
. onAppear {
UIDatePicker . appearance ( ) . minuteInterval = 5
}
. onDisappear {
UIDatePicker . appearance ( ) . minuteInterval = 1
}
}
private func _navigationTitle ( ) -> String {
editingSlot = = nil ? " Nouveau créneau " : " Édition du créneau "
}
}
struct CourtPicker : View {
@ Environment ( Tournament . self ) var tournament : Tournament
let title : String
@ Binding var selection : Int
let maxCourt : Int
struct DateAdjusterView : View {
@ Binding var date : Date
var body : some View {
Picker ( title , selection : $ selection ) {
ForEach ( 0. . < maxCourt , id : \ . self ) {
Text ( tournament . courtName ( atIndex : $0 ) )
HStack {
_createButton ( label : " -1h " , timeOffset : - 1 , component : . hour )
_createButton ( label : " -30m " , timeOffset : - 30 , component : . minute )
_createButton ( label : " +30m " , timeOffset : 30 , component : . minute )
_createButton ( label : " +1h " , timeOffset : 1 , component : . hour )
}
. font ( . headline )
}
private func _createButton ( label : String , timeOffset : Int , component : Calendar . Component ) -> some View {
Button ( action : {
date = Calendar . current . date ( byAdding : component , value : timeOffset , to : date ) ? ? date
} ) {
Text ( label )
. frame ( maxWidth : . infinity ) // M a k e b u t t o n s t a k e e q u a l s p a c e
}
. buttonStyle ( . borderedProminent )
. tint ( . master )
}
}
// # P r e v i e w {
// C o u r t A v a i l a b i l i t y S e t t i n g s V i e w ( e v e n t : E v e n t . m o c k ( ) )
// }