diff --git a/Schedule ICTIS/Main/Views/Fields/ProfessorAuditoryClassFieldView.swift b/Schedule ICTIS/Main/Views/Fields/AuditoryFieldView.swift similarity index 89% rename from Schedule ICTIS/Main/Views/Fields/ProfessorAuditoryClassFieldView.swift rename to Schedule ICTIS/Main/Views/Fields/AuditoryFieldView.swift index 7961b7f..053abe0 100644 --- a/Schedule ICTIS/Main/Views/Fields/ProfessorAuditoryClassFieldView.swift +++ b/Schedule ICTIS/Main/Views/Fields/AuditoryFieldView.swift @@ -1,17 +1,17 @@ // -// Field.swift +// AuditoryFieldView.swift // Schedule ICTIS // -// Created by G412 on 16.12.2024. +// Created by G412 on 23.01.2025. // import SwiftUI -struct ProfessorAuditoryClassFieldView: View { +struct AuditoryFieldView: View { @Binding var text: String var nameOfImage: String var labelForField: String - @FocusState private var isFocused: Bool + @FocusState var isFocused: Bool var body: some View { HStack(spacing: 0) { Image(systemName: nameOfImage) diff --git a/Schedule ICTIS/Main/Views/Fields/CommentFieldView.swift b/Schedule ICTIS/Main/Views/Fields/CommentFieldView.swift index 333ae5d..2c0a4a2 100644 --- a/Schedule ICTIS/Main/Views/Fields/CommentFieldView.swift +++ b/Schedule ICTIS/Main/Views/Fields/CommentFieldView.swift @@ -9,7 +9,7 @@ import SwiftUI struct CommentFieldView: View { @Binding var textForComment: String - @FocusState private var isFocused: Bool + @FocusState var isFocused: Bool var body: some View { HStack { diff --git a/Schedule ICTIS/Main/Views/Fields/ProfessorFieldView.swift b/Schedule ICTIS/Main/Views/Fields/ProfessorFieldView.swift new file mode 100644 index 0000000..312425d --- /dev/null +++ b/Schedule ICTIS/Main/Views/Fields/ProfessorFieldView.swift @@ -0,0 +1,48 @@ +// +// ProfessorFieldView.swift +// Schedule ICTIS +// +// Created by G412 on 23.01.2025. +// + +import SwiftUI + +struct ProfessorFieldView: View { + @Binding var text: String + var nameOfImage: String + var labelForField: String + @FocusState var isFocused: Bool + var body: some View { + HStack(spacing: 0) { + Image(systemName: nameOfImage) + .foregroundColor(Color.gray) + .padding(.leading, 12) + .padding(.trailing, 7) + TextField(labelForField, text: $text) + .font(.system(size: 18, weight: .regular)) + .disableAutocorrection(true) + .submitLabel(.done) + .focused($isFocused) + if isFocused { + Button { + self.text = "" + self.isFocused = false + } label: { + Image(systemName: "xmark.circle.fill") + .padding(.trailing, 20) + .offset(x: 10) + .foregroundColor(.gray) + } + } + } + .frame(height: 40) + .background( + RoundedRectangle(cornerRadius: 10) + .fill(.white) + ) + } +} + +#Preview { + ContentView() +} diff --git a/Schedule ICTIS/Main/Views/Fields/StartEndTimeFieldView.swift b/Schedule ICTIS/Main/Views/Fields/StartEndTimeFieldView.swift index 7ec4063..9b70a98 100644 --- a/Schedule ICTIS/Main/Views/Fields/StartEndTimeFieldView.swift +++ b/Schedule ICTIS/Main/Views/Fields/StartEndTimeFieldView.swift @@ -13,20 +13,19 @@ struct StartEndTimeFieldView: View { @Binding var selectedTime: Date var imageName: String var text: String - @State private var isTimeSelected: Bool = false + @Binding var isTimeSelected: Bool var body: some View { HStack { Image(systemName: imageName) .foregroundColor(isIncorrectDate ? .red : Color("grayForFields")) .padding(.leading, 12) - if !isTimeSelected { + if !isTimeSelected || isIncorrectDate { Text(text) .font(.system(size: 17, weight: .regular)) .foregroundColor(.gray.opacity(0.5)) } - - if isTimeSelected { + else { Text("\(selectedTime, formatter: timeFormatter)") .foregroundColor(isIncorrectDate ? .red : .black) .font(.system(size: 17, weight: .medium)) @@ -40,7 +39,7 @@ struct StartEndTimeFieldView: View { .fill(.white) ) .overlay { - if isSameDate(selectedTime, selectedDay) { + if selectedDay.isToday { DatePicker("", selection: $selectedTime, in: Date()..., displayedComponents: .hourAndMinute) .padding(.trailing, 35) .blendMode(.destinationOver) diff --git a/Schedule ICTIS/Main/Views/Fields/SubjectFieldView.swift b/Schedule ICTIS/Main/Views/Fields/SubjectFieldView.swift new file mode 100644 index 0000000..d1d862d --- /dev/null +++ b/Schedule ICTIS/Main/Views/Fields/SubjectFieldView.swift @@ -0,0 +1,66 @@ +// +// Field.swift +// Schedule ICTIS +// +// Created by G412 on 16.12.2024. +// + +import SwiftUI + +struct SubjectFieldView: View { + @Binding var text: String + @Binding var isShowingSubjectFieldRed: Bool + var nameOfImage: String + @Binding var labelForField: String + @FocusState var isFocused: Bool + var body: some View { + HStack(spacing: 0) { + Image(systemName: nameOfImage) + .foregroundColor(Color.gray) + .padding(.leading, 12) + .padding(.trailing, 7) + TextField(labelForField, text: $text) + .font(.system(size: 18, weight: .regular)) + .disableAutocorrection(true) + .submitLabel(.done) + .focused($isFocused) + .onChange(of: isFocused, initial: false) { oldValue, newValue in + if newValue { + self.isShowingSubjectFieldRed = false + self.labelForField = "Предмет" + } + } + .background { + Group { + if isShowingSubjectFieldRed { + Text("Поле должно быть заполнено!") + .font(.system(size: 18, weight: .regular)) + .foregroundColor(.red) + .frame(width: 290) + .padding(.leading, -42) + } + } + } + if isFocused { + Button { + self.text = "" + self.isFocused = false + } label: { + Image(systemName: "xmark.circle.fill") + .padding(.trailing, 20) + .offset(x: 10) + .foregroundColor(.gray) + } + } + } + .frame(height: 40) + .background( + RoundedRectangle(cornerRadius: 10) + .fill(.white) + ) + } +} + +#Preview { + ContentView() +} diff --git a/Schedule ICTIS/Main/Views/ScheduleView.swift b/Schedule ICTIS/Main/Views/ScheduleView.swift index ccc6f72..318bc63 100644 --- a/Schedule ICTIS/Main/Views/ScheduleView.swift +++ b/Schedule ICTIS/Main/Views/ScheduleView.swift @@ -81,7 +81,7 @@ struct ScheduleView: View { selectedClass = nil }, content: { _class in - CreateEditClassView(vm: .init(provider: provider, _class: _class)) + CreateEditClassView(vm: .init(provider: provider, _class: _class), day: vm.selectedDay) }) } else { diff --git a/Schedule ICTIS/Main/Views/SearchBarView.swift b/Schedule ICTIS/Main/Views/SearchBarView.swift index 0eb3a9c..ae2bbd5 100644 --- a/Schedule ICTIS/Main/Views/SearchBarView.swift +++ b/Schedule ICTIS/Main/Views/SearchBarView.swift @@ -77,7 +77,7 @@ struct SearchBarView: View { .frame(height: 40) .accentColor(.blue) .sheet(isPresented: $isShowingSheet) { - CreateEditClassView(vm: .init(provider: provider)) + CreateEditClassView(vm: .init(provider: provider), day: vm.selectedDay) } } } diff --git a/Schedule ICTIS/Main/Views/Sheets/CreateEditClassView.swift b/Schedule ICTIS/Main/Views/Sheets/CreateEditClassView.swift index ec6d1f3..6f7086c 100644 --- a/Schedule ICTIS/Main/Views/Sheets/CreateEditClassView.swift +++ b/Schedule ICTIS/Main/Views/Sheets/CreateEditClassView.swift @@ -11,19 +11,63 @@ struct CreateEditClassView: View { @Environment(\.dismiss) private var dismiss @State private var isShowingDatePickerForDate: Bool = false @ObservedObject var vm: EditClassViewModel + var day: Date @State private var isIncorrectDate1: Bool = false @State private var isIncorrectDate2: Bool = false + @State private var isShowingSubjectFieldRed: Bool = false + @State private var isSelectedTime1 = false + @State private var isSelectedTime2 = false + @State private var textForLabelInSubjectField: String = "Предмет" + @FocusState private var isFocusedSubject: Bool + @FocusState private var isFocusedAuditory: Bool + @FocusState private var isFocusedProfessor: Bool + @FocusState private var isFocusedComment: Bool var provider = ClassProvider.shared var body: some View { NavigationView { ScrollView(.vertical, showsIndicators: false) { VStack { - ProfessorAuditoryClassFieldView(text: $vm._class.subject, nameOfImage: "book", labelForField: "Предмет") + SubjectFieldView(text: $vm._class.subject, isShowingSubjectFieldRed: $isShowingSubjectFieldRed, nameOfImage: "book", labelForField: $textForLabelInSubjectField, isFocused: _isFocusedSubject) .padding(.bottom, 10) - ProfessorAuditoryClassFieldView(text: $vm._class.auditory, nameOfImage: "mappin.and.ellipse", labelForField: "Корпус-аудитория") - .padding(.bottom, 10) - ProfessorAuditoryClassFieldView(text: $vm._class.professor, nameOfImage: "book", labelForField: "Преподаватель") + HStack { + Text("Тип") + Spacer() + Picker("Тип", selection: $vm._class.online, content: { + ForEach(MockData.onlineOrOffline, id: \.self) { + Text($0) + } + }) + .accentColor(Color("grayForFields")) + } + .frame(height: 40) + .padding(.horizontal) + .background( + RoundedRectangle(cornerRadius: 10) + .fill(.white) + ) + .padding(.bottom, 10) + + + ZStack { + if vm._class.online == "Оффлайн" { + AuditoryFieldView(text: $vm._class.auditory, nameOfImage: "mappin.and.ellipse", labelForField: "Корпус-аудитория", isFocused: _isFocusedAuditory) + .padding(.bottom, 10) + .transition(.asymmetric( + insertion: .offset(y: -50).combined(with: .identity), + removal: .offset(y: -50).combined(with: .opacity) + )) + } + } + .animation( + vm._class.online == "Оффлайн" ? + .linear(duration: 0.3) : // Анимация для появления + .linear(duration: 0.2), // Анимация для исчезновения + value: vm._class.online + ) + + ProfessorFieldView(text: $vm._class.professor, nameOfImage: "book", labelForField: "Преподаватель", isFocused: _isFocusedProfessor) .padding(.bottom, 10) + HStack { Image(systemName: "calendar") .foregroundColor(Color.gray) @@ -46,46 +90,55 @@ struct CreateEditClassView: View { .overlay { DatePicker("", selection: $vm._class.day, in: Date()..., displayedComponents: .date) .blendMode(.destinationOver) + } .padding(.bottom, 10) HStack { - StartEndTimeFieldView(isIncorrectDate: $isIncorrectDate1, selectedDay: $vm._class.day, selectedTime: $vm._class.starttime, imageName: "clock", text: "Начало") + StartEndTimeFieldView(isIncorrectDate: $isIncorrectDate1, selectedDay: $vm._class.day, selectedTime: $vm._class.starttime, imageName: "clock", text: "Начало", isTimeSelected: $isSelectedTime1) .onChange(of: vm._class.starttime) { oldValue, newValue in if !checkStartTimeLessThenEndTime(vm._class.starttime, vm._class.endtime) { self.isIncorrectDate1 = true + self.isSelectedTime1 = false + print("Первый") + print(self.isSelectedTime1) + print(self.isSelectedTime2) } else { self.isIncorrectDate1 = false self.isIncorrectDate2 = false } } - .overlay { - if isIncorrectDate1 { - Rectangle() - .frame(maxWidth: 300, maxHeight: 1) - .foregroundColor(.red) - .padding(.horizontal) - } - } +// .overlay { +// if isIncorrectDate1 { +// Rectangle() +// .frame(maxWidth: 300, maxHeight: 1) +// .foregroundColor(.red) +// .padding(.horizontal) +// } +// } Spacer() - StartEndTimeFieldView(isIncorrectDate: $isIncorrectDate2, selectedDay: $vm._class.day, selectedTime: $vm._class.endtime, imageName: "clock.badge.xmark", text: "Конец") + StartEndTimeFieldView(isIncorrectDate: $isIncorrectDate2, selectedDay: $vm._class.day, selectedTime: $vm._class.endtime, imageName: "clock.badge.xmark", text: "Конец", isTimeSelected: $isSelectedTime2) .onChange(of: vm._class.endtime) { oldValue, newValue in if !checkStartTimeLessThenEndTime(vm._class.starttime, vm._class.endtime) { self.isIncorrectDate2 = true + self.isSelectedTime2 = false + print("Второй") + print(self.isSelectedTime1) + print(self.isSelectedTime2) } else { self.isIncorrectDate1 = false self.isIncorrectDate2 = false } } - .overlay { - if isIncorrectDate2 { - Rectangle() - .frame(maxWidth: 300, maxHeight: 1) - .foregroundColor(.red) - .padding(.horizontal) - } - } +// .overlay { +// if isIncorrectDate2 { +// Rectangle() +// .frame(maxWidth: 300, maxHeight: 1) +// .foregroundColor(.red) +// .padding(.horizontal) +// } +// } } .frame(height: 40) .padding(.bottom, 10) @@ -115,25 +168,8 @@ struct CreateEditClassView: View { .fill(.white) ) .padding(.bottom, 10) - HStack { - Text("Тип") - Spacer() - Picker("Тип", selection: $vm._class.online, content: { - ForEach(MockData.onlineOrOffline, id: \.self) { - Text($0) - } - }) - .accentColor(Color("grayForFields")) - } - .frame(height: 40) - .padding(.horizontal) - .background( - RoundedRectangle(cornerRadius: 10) - .fill(.white) - ) - .padding(.bottom, 10) - CommentFieldView(textForComment: $vm._class.comment) + CommentFieldView(textForComment: $vm._class.comment, isFocused: _isFocusedComment) .padding(.bottom, 20) @@ -172,21 +208,51 @@ struct CreateEditClassView: View { } ToolbarItem(placement: .navigationBarTrailing) { Button("Сохранить") { - do { - try vm.save() - dismiss() - } catch { - print(error) + isFocusedSubject = false + isFocusedProfessor = false + isFocusedAuditory = false + isFocusedComment = false + if (vm._class.subject.isEmpty || (isIncorrectDate1 || isIncorrectDate2) || (!isSelectedTime1 || !isSelectedTime2)) { + if (vm._class.subject.isEmpty) { + self.isShowingSubjectFieldRed = true + self.textForLabelInSubjectField = "" + } + if !isSelectedTime1 { + self.isIncorrectDate1 = true + } + if !isSelectedTime2 { + self.isIncorrectDate2 = true + } + } + else { + do { + try vm.save() + dismiss() + } catch { + print(error) + } } } } } .navigationTitle(vm.isNew ? "Новая пара" : "Изменить данные") .background(Color("background")) + .onAppear { + if day >= Calendar.current.startOfDay(for: Date()) { + vm._class.day = day + } + } + .onTapGesture { + isFocusedSubject = false + isFocusedProfessor = false + isFocusedAuditory = false + isFocusedComment = false + } } } } #Preview { - CreateEditClassView(vm: .init(provider: .shared)) + let day: Date = .init() + CreateEditClassView(vm: .init(provider: .shared), day: day) }