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.

150 lines
5.3 KiB

import SwiftUI
// MARK: - Calendar Event Input Component
struct CalendarInputView: View {
@Binding var eventTitle: String
@Binding var eventDescription: String
@Binding var startDate: Date
@Binding var endDate: Date
@Binding var location: String
@FocusState var focusedField: CalendarField?
// Calendar field enum
enum CalendarField: Hashable {
case title, description, location
}
var body: some View {
VStack(spacing: 16) {
// Event title
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("event_title".localized)
.font(.subheadline)
.foregroundColor(.primary)
Text("*")
.foregroundColor(.red)
Spacer()
}
TextField("event_title_placeholder".localized, text: $eventTitle)
.textFieldStyle(RoundedBorderTextFieldStyle())
.focused($focusedField, equals: .title)
}
// Event description
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("event_description".localized)
.font(.subheadline)
.foregroundColor(.primary)
Spacer()
}
TextField("event_description_placeholder".localized, text: $eventDescription)
.textFieldStyle(RoundedBorderTextFieldStyle())
.focused($focusedField, equals: .description)
}
// Start time
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("start_time".localized)
.font(.subheadline)
.foregroundColor(.primary)
Text("*")
.foregroundColor(.red)
Spacer()
}
DatePicker("start_time".localized, selection: $startDate, displayedComponents: [.date, .hourAndMinute])
.datePickerStyle(CompactDatePickerStyle())
.labelsHidden()
}
// End time
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("end_time".localized)
.font(.subheadline)
.foregroundColor(.primary)
Text("*")
.foregroundColor(.red)
Spacer()
}
DatePicker("end_time".localized, selection: $endDate, displayedComponents: [.date, .hourAndMinute])
.datePickerStyle(CompactDatePickerStyle())
.labelsHidden()
}
// Location
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("event_location".localized)
.font(.subheadline)
.foregroundColor(.primary)
Spacer()
}
TextField("event_location_placeholder".localized, text: $location)
.textFieldStyle(RoundedBorderTextFieldStyle())
.focused($focusedField, equals: .location)
}
// Time validation hint
if endDate <= startDate {
VStack(alignment: .leading, spacing: 8) {
HStack {
Image(systemName: "exclamationmark.triangle")
.font(.caption)
.foregroundColor(.orange)
Text("time_setting_hint".localized)
.font(.caption)
.foregroundColor(.primary)
Spacer()
}
Text("end_time_must_be_after_start_time".localized)
.font(.caption)
.foregroundColor(.orange)
}
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.orange.opacity(0.1))
)
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("complete".localized) {
focusedField = nil
}
.foregroundColor(.blue)
.font(.system(size: 16, weight: .medium))
}
}
.onAppear {
//
if startDate == Date() {
startDate = Date()
endDate = Calendar.current.date(byAdding: .hour, value: 1, to: startDate) ?? startDate
}
}
}
}
#Preview {
CalendarInputView(
eventTitle: .constant(""),
eventDescription: .constant(""),
startDate: .constant(Date()),
endDate: .constant(Calendar.current.date(byAdding: .hour, value: 1, to: Date()) ?? Date()),
location: .constant("")
)
}