Files
NearFuture/MacNearFuture/Views/Events/AddEventView.swift
neon443 6e7bc6c2d1 add viewmodifiers.siwft to conditionally do viewmodifiers
replaced all the .apply s everywhere
colorcodable into its own file
add icon changing for mac
2025-06-13 18:30:07 +01:00

196 lines
4.4 KiB
Swift

//
// AddEventView.swift
// MacNearFuture
//
// Created by neon443 on 11/06/2025.
//
import SwiftUI
import SFSymbolsPicker
struct AddEventView: View {
@ObservedObject var viewModel: EventViewModel
@Binding var event: Event
@State var adding: Bool
@State var showNeedsNameAlert: Bool = false
@State var isSymbolPickerPresented: Bool = false
@State private var bye: Bool = false
@FocusState private var focusedField: Field?
private enum Field {
case Name, Notes
}
@Environment(\.dismiss) var dismiss
var body: some View {
ZStack {
if !adding {
backgroundGradient
}
List {
Section(
header:
Text("Event Details")
.font(.headline)
.foregroundColor(.accentColor)
) {
// name & symbol
HStack(spacing: 5) {
Button() {
isSymbolPickerPresented.toggle()
} label: {
Image(systemName: event.symbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.foregroundStyle(event.color.color)
}
.frame(width: 20)
.buttonStyle(.borderless)
.sheet(isPresented: $isSymbolPickerPresented) {
SymbolsPicker(
selection: $event.symbol,
title: "Choose a Symbol",
searchLabel: "Search...",
autoDismiss: true)
.presentationDetents([.medium])
}
// dscription
ZStack {
TextField("Event Notes", text: $event.notes)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.trailing, event.notes.isEmpty ? 0 : 30)
.animation(.spring, value: event.notes)
.focused($focusedField, equals: Field.Notes)
.submitLabel(.done)
.onSubmit {
focusedField = nil
}
// MagicClearButton(text: $eventNotes)
}
// date picker
HStack {
Spacer()
DatePicker("", selection: $event.date, displayedComponents: .date)
Spacer()
Button() {
event.date = Date()
} label: {
Image(systemName: "arrow.uturn.left")
.resizable()
.scaledToFit()
}
.buttonStyle(BorderlessButtonStyle())
.frame(width: 20)
}
DatePicker(
"",
selection: $event.date,
displayedComponents: .hourAndMinute
)
// re-ocurrence Picker
Picker("Recurrence", selection: $event.recurrence) {
ForEach(Event.RecurrenceType.allCases, id: \.self) { recurrence in
Text(recurrence.rawValue.capitalized)
}
}
.pickerStyle(SegmentedPickerStyle())
Text(
describeOccurrence(
date: event.date,
recurrence: event.recurrence
)
)
}
}
.scrollContentBackground(.hidden)
.navigationTitle("\(adding ? "Add Event" : "")")
.toolbar {
ToolbarItem() {
if adding {
Button() {
resetAddEventView()
dismiss()
} label: {
Image(systemName: "xmark")
.resizable()
.scaledToFit()
.frame(width: 30)
}
}
}
ToolbarItem/*(placement: .topBarTrailing)*/ {
if adding {
Button {
viewModel.addEvent(
newEvent: event
)
bye.toggle()
resetAddEventView()
} label: {
Text("Save")
.font(.headline)
.cornerRadius(10)
.buttonStyle(BorderedProminentButtonStyle())
}
.tint(.accent)
.modifier(hapticSuccess(trigger: bye))
.disabled(event.name.isEmpty)
.onTapGesture {
if event.name.isEmpty {
showNeedsNameAlert.toggle()
}
}
.alert("Missing Name", isPresented: $showNeedsNameAlert) {
Button("OK", role: .cancel) {
showNeedsNameAlert.toggle()
focusedField = .Name
}
} message: {
Text("Give your Event a name before saving.")
}
if event.name.isEmpty {
HStack {
Image(systemName: "exclamationmark")
.foregroundStyle(.red)
Text("Give your event a name.")
}
}
}
}
}
}
.scrollContentBackground(.hidden)
.presentationDragIndicator(.visible)
}
}
func resetAddEventView() {
//reset addeventView
event = viewModel.template
dismiss()
}
}
#Preview {
let vm = dummyEventViewModel()
Color.orange
.ignoresSafeArea(.all)
.sheet(isPresented: .constant(true)) {
AddEventView(
viewModel: vm,
event: .constant(vm.template),
adding: true
)
}
}