Commit
This commit is contained in:
parent
9f717d83df
commit
bb268cc6ad
44
Schedule ICTIS/LoadingScheduleView.swift
Normal file
44
Schedule ICTIS/LoadingScheduleView.swift
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// LoadingScheduleView.swift
|
||||||
|
// Schedule ICTIS
|
||||||
|
//
|
||||||
|
// Created by G412 on 19.02.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct LoadingScheduleView: View {
|
||||||
|
@State private var isAnimated = false
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
|
VStack(spacing: 20) {
|
||||||
|
ForEach(0..<3, id: \.self) { _ in
|
||||||
|
RoundedRectangle(cornerRadius: 20)
|
||||||
|
.fill(
|
||||||
|
LinearGradient(
|
||||||
|
gradient: Gradient(colors: [
|
||||||
|
isAnimated ? Color.gray.opacity(0.5) : Color.gray.opacity(0.2),
|
||||||
|
isAnimated ? Color.gray.opacity(0.2) : Color.gray.opacity(0.5)
|
||||||
|
]),
|
||||||
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.frame(height: 65)
|
||||||
|
.padding(.horizontal, 20)
|
||||||
|
.animation(.linear(duration: 0.9).repeatForever(autoreverses: true), value: isAnimated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
isAnimated.toggle()
|
||||||
|
}
|
||||||
|
.padding(.top, 30)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
LoadingScheduleView()
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
// LoadingView.swift
|
// LoadingView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 11.12.2024.
|
// Created by Mironov Egor on 11.12.2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
@ -2,7 +2,7 @@
|
|||||||
// CreatedClassView.swift
|
// CreatedClassView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 23.12.2024.
|
// Created by Mironov Egor on 23.12.2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
@ -12,7 +12,7 @@ struct CreatedClassView: View {
|
|||||||
var provider = ClassProvider.shared
|
var provider = ClassProvider.shared
|
||||||
var body: some View {
|
var body: some View {
|
||||||
let existingCopy = try? provider.viewContext.existingObject(with: _class.objectID)
|
let existingCopy = try? provider.viewContext.existingObject(with: _class.objectID)
|
||||||
if let check = existingCopy {
|
if existingCopy != nil {
|
||||||
HStack(spacing: 10) {
|
HStack(spacing: 10) {
|
||||||
VStack {
|
VStack {
|
||||||
Text(getTimeString(_class.starttime))
|
Text(getTimeString(_class.starttime))
|
||||||
@ -20,6 +20,7 @@ struct CreatedClassView: View {
|
|||||||
Text(getTimeString(_class.endtime))
|
Text(getTimeString(_class.endtime))
|
||||||
.font(.custom("Montserrat-Regular", size: 15))
|
.font(.custom("Montserrat-Regular", size: 15))
|
||||||
}
|
}
|
||||||
|
.frame(width: 48)
|
||||||
.padding(.top, 7)
|
.padding(.top, 7)
|
||||||
.padding(.bottom, 7)
|
.padding(.bottom, 7)
|
||||||
.padding(.leading, 10)
|
.padding(.leading, 10)
|
||||||
@ -30,7 +31,7 @@ struct CreatedClassView: View {
|
|||||||
.padding(.bottom, 7)
|
.padding(.bottom, 7)
|
||||||
.foregroundColor(_class.important ? Color("redForImportant") : onlineOrNot(_class.online))
|
.foregroundColor(_class.important ? Color("redForImportant") : onlineOrNot(_class.online))
|
||||||
Text(getSubjectName(_class.subject, _class.professor, _class.auditory))
|
Text(getSubjectName(_class.subject, _class.professor, _class.auditory))
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Medium", size: 15))
|
||||||
.padding(.top, 7)
|
.padding(.top, 7)
|
||||||
.padding(.bottom, 7)
|
.padding(.bottom, 7)
|
||||||
Spacer()
|
Spacer()
|
||||||
|
@ -18,7 +18,7 @@ struct AuditoryFieldView: View {
|
|||||||
.padding(.leading, 12)
|
.padding(.leading, 12)
|
||||||
.padding(.trailing, 14)
|
.padding(.trailing, 14)
|
||||||
TextField(labelForField, text: $text)
|
TextField(labelForField, text: $text)
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Meduim", size: 17))
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
.focused($isFocused)
|
.focused($isFocused)
|
||||||
|
@ -14,7 +14,7 @@ struct CommentFieldView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
TextField("Комментарий", text: $textForComment)
|
TextField("Комментарий", text: $textForComment)
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Medium", size: 17))
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
.multilineTextAlignment(.leading)
|
.multilineTextAlignment(.leading)
|
||||||
.focused($isFocused)
|
.focused($isFocused)
|
||||||
|
@ -18,7 +18,7 @@ struct ProfessorFieldView: View {
|
|||||||
.padding(.leading, 12)
|
.padding(.leading, 12)
|
||||||
.padding(.trailing, 7)
|
.padding(.trailing, 7)
|
||||||
TextField(labelForField, text: $text)
|
TextField(labelForField, text: $text)
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Meduim", size: 17))
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
.focused($isFocused)
|
.focused($isFocused)
|
||||||
|
@ -23,7 +23,7 @@ struct StartEndTimeFieldView: View {
|
|||||||
|
|
||||||
if !isTimeSelected || isIncorrectDate {
|
if !isTimeSelected || isIncorrectDate {
|
||||||
Text(text)
|
Text(text)
|
||||||
.font(.custom("Montserrat-Regular", size: 17))
|
.font(.custom("Montserrat-Meduim", size: 17))
|
||||||
.foregroundColor(.gray.opacity(0.5))
|
.foregroundColor(.gray.opacity(0.5))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -19,7 +19,7 @@ struct SubjectFieldView: View {
|
|||||||
.padding(.leading, 12)
|
.padding(.leading, 12)
|
||||||
.padding(.trailing, 9)
|
.padding(.trailing, 9)
|
||||||
TextField(labelForField, text: $text)
|
TextField(labelForField, text: $text)
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Meduim", size: 17))
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
.focused($isFocused)
|
.focused($isFocused)
|
||||||
@ -33,10 +33,10 @@ struct SubjectFieldView: View {
|
|||||||
Group {
|
Group {
|
||||||
if isShowingSubjectFieldRed {
|
if isShowingSubjectFieldRed {
|
||||||
Text("Поле должно быть заполнено!")
|
Text("Поле должно быть заполнено!")
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Meduim", size: 17))
|
||||||
.foregroundColor(.red)
|
.foregroundColor(.red)
|
||||||
.frame(width: 290)
|
.frame(width: 290)
|
||||||
.padding(.leading, -42)
|
.padding(.leading, -38)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// FirstLaunchScheduleView.swift
|
// FirstLaunchScheduleView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 06.12.2024.
|
// Created by Mironov Egor on 06.12.2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
@ -24,27 +24,25 @@ struct MainView: View {
|
|||||||
}
|
}
|
||||||
CurrentDateView()
|
CurrentDateView()
|
||||||
if vm.isLoading {
|
if vm.isLoading {
|
||||||
LoadingView(isLoading: $vm.isLoading)
|
LoadingScheduleView()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ScheduleView(vm: vm, isScrolling: $isScrolling)
|
ScheduleView(vm: vm, isScrolling: $isScrolling)
|
||||||
|
.onTapGesture {
|
||||||
|
isFocusedSearchBar = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in
|
.alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in
|
||||||
|
Button("ОК") {
|
||||||
|
print("This alert")
|
||||||
|
vm.isShowingAlertForIncorrectGroup = false
|
||||||
|
vm.errorInNetwork = nil
|
||||||
|
}
|
||||||
} message: { error in
|
} message: { error in
|
||||||
Text(error.failureReason)
|
Text(error.failureReason)
|
||||||
}
|
}
|
||||||
.background(Color("background"))
|
.background(Color("background"))
|
||||||
.onTapGesture {
|
|
||||||
isFocusedSearchBar = false
|
|
||||||
}
|
|
||||||
.onAppear {
|
|
||||||
vm.group = UserDefaults.standard.string(forKey: "group") ?? "notSeted"
|
|
||||||
if vm.group != "notSeted" {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
@ -53,14 +51,14 @@ struct MainView: View {
|
|||||||
HStack {
|
HStack {
|
||||||
VStack (alignment: .leading, spacing: 0) {
|
VStack (alignment: .leading, spacing: 0) {
|
||||||
Text(vm.selectedDay.format("EEEE"))
|
Text(vm.selectedDay.format("EEEE"))
|
||||||
.font(.custom("Montserrat-SemiBold", size: 40))
|
.font(.custom("Montserrat-SemiBold", size: 30))
|
||||||
.foregroundStyle(.black)
|
.foregroundStyle(.black)
|
||||||
HStack (spacing: 5) {
|
HStack (spacing: 5) {
|
||||||
Text(vm.selectedDay.format("dd"))
|
Text(vm.selectedDay.format("dd"))
|
||||||
.font(.custom("Montserrat-Bold", size: 20))
|
.font(.custom("Montserrat-Bold", size: 17))
|
||||||
.foregroundStyle(Color("grayForDate"))
|
.foregroundStyle(Color("grayForDate"))
|
||||||
Text(vm.selectedDay.format("MMMM"))
|
Text(vm.selectedDay.format("MMMM"))
|
||||||
.font(.custom("Montserrat-Bold", size: 20))
|
.font(.custom("Montserrat-Bold", size: 17))
|
||||||
.foregroundStyle(Color("grayForDate"))
|
.foregroundStyle(Color("grayForDate"))
|
||||||
Spacer()
|
Spacer()
|
||||||
Button(action: {
|
Button(action: {
|
||||||
@ -70,7 +68,7 @@ struct MainView: View {
|
|||||||
}) {
|
}) {
|
||||||
HStack(spacing: 2) {
|
HStack(spacing: 2) {
|
||||||
Text(isShowingMonthSlider ? "Свернуть" : "Развернуть")
|
Text(isShowingMonthSlider ? "Свернуть" : "Развернуть")
|
||||||
.font(.custom("Montserrat-Light", size: 16))
|
.font(.custom("Montserrat-Regular", size: 15))
|
||||||
.foregroundStyle(Color.blue)
|
.foregroundStyle(Color.blue)
|
||||||
Image(isShowingMonthSlider ? "arrowup" : "arrowdown")
|
Image(isShowingMonthSlider ? "arrowup" : "arrowdown")
|
||||||
.resizable()
|
.resizable()
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// NoScheduleView.swift
|
// NoScheduleView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 12.12.2024.
|
// Created by Mironov Egor on 12.12.2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
@ -11,9 +11,9 @@ struct NoScheduleView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
ScrollView (showsIndicators: false) {
|
ScrollView (showsIndicators: false) {
|
||||||
Text("Пока расписания нет")
|
Text("Пока что расписания нет😪")
|
||||||
.padding(.top, 20)
|
.padding(.top, 100)
|
||||||
.font(.custom("Montserrat-Regular", size: 15))
|
.font(.custom("Montserrat-SemiBold", size: 17))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ struct ScheduleView: View {
|
|||||||
var provider = ClassProvider.shared
|
var provider = ClassProvider.shared
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if vm.isLoading {
|
if vm.isLoading {
|
||||||
LoadingView(isLoading: $vm.isLoading)
|
LoadingScheduleView()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if vm.errorInNetwork != .invalidResponse {
|
if vm.errorInNetwork != .invalidResponse {
|
||||||
@ -33,12 +33,13 @@ struct ScheduleView: View {
|
|||||||
HStack(spacing: 10) {
|
HStack(spacing: 10) {
|
||||||
VStack {
|
VStack {
|
||||||
Text(convertTimeString(vm.classes[1][lessonIndex])[0])
|
Text(convertTimeString(vm.classes[1][lessonIndex])[0])
|
||||||
.font(.custom("Montserrat-Medium", size: 15))
|
.font(.custom("Montserrat-Regular", size: 15))
|
||||||
.padding(.bottom, 1)
|
.padding(.bottom, 1)
|
||||||
Text(convertTimeString(vm.classes[1][lessonIndex])[1])
|
Text(convertTimeString(vm.classes[1][lessonIndex])[1])
|
||||||
.font(.custom("Montserrat-Medium", size: 15))
|
.font(.custom("Montserrat-Regular", size: 15))
|
||||||
.padding(.top, 1)
|
.padding(.top, 1)
|
||||||
}
|
}
|
||||||
|
.frame(width: 48)
|
||||||
.padding(.top, 7)
|
.padding(.top, 7)
|
||||||
.padding(.bottom, 7)
|
.padding(.bottom, 7)
|
||||||
.padding(.leading, 10)
|
.padding(.leading, 10)
|
||||||
@ -49,7 +50,7 @@ struct ScheduleView: View {
|
|||||||
.padding(.bottom, 7)
|
.padding(.bottom, 7)
|
||||||
.foregroundColor(getColorForClass(lesson))
|
.foregroundColor(getColorForClass(lesson))
|
||||||
Text(lesson)
|
Text(lesson)
|
||||||
.font(.custom("Montserrat-Regular", size: 17))
|
.font(.custom("Montserrat-Medium", size: 15))
|
||||||
.lineSpacing(3)
|
.lineSpacing(3)
|
||||||
.padding(.top, 9)
|
.padding(.top, 9)
|
||||||
.padding(.bottom, 9)
|
.padding(.bottom, 9)
|
||||||
|
@ -28,8 +28,8 @@ struct SearchBarView: View {
|
|||||||
.onSubmit {
|
.onSubmit {
|
||||||
self.isFocused = false
|
self.isFocused = false
|
||||||
if (!text.isEmpty) {
|
if (!text.isEmpty) {
|
||||||
|
print(vm.errorInNetwork)
|
||||||
vm.fetchWeekSchedule(group: text)
|
vm.fetchWeekSchedule(group: text)
|
||||||
vm.group = text
|
|
||||||
}
|
}
|
||||||
self.text = ""
|
self.text = ""
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ struct SearchBarView: View {
|
|||||||
RoundedRectangle(cornerRadius: 10)
|
RoundedRectangle(cornerRadius: 10)
|
||||||
.fill(.white)
|
.fill(.white)
|
||||||
)
|
)
|
||||||
if (!vm.isFirstStartOffApp && !isFocused) {
|
if !isFocused {
|
||||||
Button {
|
Button {
|
||||||
isShowingSheet = true
|
isShowingSheet = true
|
||||||
} label: {
|
} label: {
|
||||||
|
@ -76,11 +76,11 @@ struct CreateEditClassView: View {
|
|||||||
.padding(.trailing, 5)
|
.padding(.trailing, 5)
|
||||||
Text("Дата")
|
Text("Дата")
|
||||||
.foregroundColor(Color("grayForFields").opacity(0.5))
|
.foregroundColor(Color("grayForFields").opacity(0.5))
|
||||||
.font(.custom("Montserrat-Regular", size: 18))
|
.font(.custom("Montserrat-Meduim", size: 17))
|
||||||
Spacer()
|
Spacer()
|
||||||
Text("\(vm._class.day, formatter: dateFormatter)")
|
Text("\(vm._class.day, formatter: dateFormatter)")
|
||||||
.foregroundColor(.black)
|
.foregroundColor(.black)
|
||||||
.font(.custom("Montserrat-Medium", size: 18))
|
.font(.custom("Montserrat-Medium", size: 17))
|
||||||
.padding(.trailing, 20)
|
.padding(.trailing, 20)
|
||||||
}
|
}
|
||||||
.frame(height: 40)
|
.frame(height: 40)
|
||||||
|
@ -18,7 +18,7 @@ struct MonthTabView: View {
|
|||||||
HStack (spacing: 34) {
|
HStack (spacing: 34) {
|
||||||
ForEach(MockData.daysOfWeek.indices, id: \.self) { index in
|
ForEach(MockData.daysOfWeek.indices, id: \.self) { index in
|
||||||
Text(MockData.daysOfWeek[index])
|
Text(MockData.daysOfWeek[index])
|
||||||
.font(.custom("Montserrat-SemiBold", size: 15))
|
.font(.custom("Montserrat-SemiBold", size: 14))
|
||||||
.foregroundColor(MockData.daysOfWeek[index] == "Вс" ? Color(.red) : Color("customGray2"))
|
.foregroundColor(MockData.daysOfWeek[index] == "Вс" ? Color(.red) : Color("customGray2"))
|
||||||
.padding(.top, 13)
|
.padding(.top, 13)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
@ -16,7 +16,7 @@ struct WeekViewForMonth: View {
|
|||||||
ForEach(week) { day in
|
ForEach(week) { day in
|
||||||
VStack {
|
VStack {
|
||||||
Text(day.date.format("dd"))
|
Text(day.date.format("dd"))
|
||||||
.font(.custom("Montserrat-Medium", size: 15))
|
.font(.custom("Montserrat-SemiBold", size: 14))
|
||||||
.foregroundStyle(getForegroundColor(day: day))
|
.foregroundStyle(getForegroundColor(day: day))
|
||||||
}
|
}
|
||||||
.frame(width: 30, height: 30, alignment: .center)
|
.frame(width: 30, height: 30, alignment: .center)
|
||||||
|
@ -18,12 +18,12 @@ struct WeekViewForWeek: View {
|
|||||||
ForEach(week) { day in
|
ForEach(week) { day in
|
||||||
VStack (spacing: 1) {
|
VStack (spacing: 1) {
|
||||||
Text(day.date.format("E"))
|
Text(day.date.format("E"))
|
||||||
.font(.custom("Montserrat-Medium", size: 16))
|
.font(.custom("Montserrat-SemiBold", size: 14))
|
||||||
.foregroundColor(day.date.format("E") == "Вс" ? Color(.red) : isSameDate(day.date, vm.selectedDay) ? Color("customGray1") : Color("customGray3"))
|
.foregroundColor(day.date.format("E") == "Вс" ? Color(.red) : isSameDate(day.date, vm.selectedDay) ? Color("customGray1") : Color("customGray3"))
|
||||||
.padding(.top, 13)
|
.padding(.top, 13)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
Text(day.date.format("dd"))
|
Text(day.date.format("dd"))
|
||||||
.font(.custom("Montserrat-Medium", size: 15))
|
.font(.custom("Montserrat-Semibold", size: 14))
|
||||||
.foregroundStyle(isSameDate(day.date, vm.selectedDay) ? .white : .black)
|
.foregroundStyle(isSameDate(day.date, vm.selectedDay) ? .white : .black)
|
||||||
.padding(.bottom, 13)
|
.padding(.bottom, 13)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// MockData.swift
|
// MockData.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 06.12.2024.
|
// Created by Mironov Egor on 06.12.2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@ -19,4 +19,6 @@ struct MockData {
|
|||||||
static let themes = ["Светлая", "Темная", "Системная"]
|
static let themes = ["Светлая", "Темная", "Системная"]
|
||||||
|
|
||||||
static let languages = ["Русский", "Английский", "Китайский", "Испанский"]
|
static let languages = ["Русский", "Английский", "Китайский", "Испанский"]
|
||||||
|
|
||||||
|
static let groups = ["КТбо2-6", "КТбо1-9", "КТбо3-3", "ВУЦ", "КТао1-1", "КТсо2-2"]
|
||||||
}
|
}
|
||||||
|
20
Schedule ICTIS/Model/GroupsModel.swift
Normal file
20
Schedule ICTIS/Model/GroupsModel.swift
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// SubjectsModel.swift
|
||||||
|
// Schedule ICTIS
|
||||||
|
//
|
||||||
|
// Created by Mironov Egor on 19.02.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// MARK: - Welcome
|
||||||
|
struct Welcome: Decodable {
|
||||||
|
let choices: [Choice]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Choice
|
||||||
|
struct Choice: Decodable, Identifiable {
|
||||||
|
let name: String
|
||||||
|
let id: String
|
||||||
|
let group: String
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "arrow.png",
|
"filename" : "arrowdown.svg",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 221 B |
3
Schedule ICTIS/Preview Content/Assets.xcassets/arrowdown.imageset/arrowdown.svg
vendored
Normal file
3
Schedule ICTIS/Preview Content/Assets.xcassets/arrowdown.imageset/arrowdown.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13 1L7 7L1 1" stroke="#007AFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 191 B |
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "Vector.png",
|
"filename" : "arrowup.svg",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 222 B |
3
Schedule ICTIS/Preview Content/Assets.xcassets/arrowup.imageset/arrowup.svg
vendored
Normal file
3
Schedule ICTIS/Preview Content/Assets.xcassets/arrowup.imageset/arrowup.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1 7L7 1L13 7" stroke="#007AFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 191 B |
@ -2,7 +2,7 @@
|
|||||||
// SelectedGroupView.swift
|
// SelectedGroupView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 30.01.2025.
|
// Created by Mironov Egor on 30.01.2025.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
@ -11,7 +11,9 @@ struct SelectingGroupView: View {
|
|||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
@FocusState private var isFocused: Bool
|
@FocusState private var isFocused: Bool
|
||||||
@State private var text: String = ""
|
@State private var text: String = ""
|
||||||
@Binding var group: String
|
@ObservedObject var vm: ScheduleViewModel
|
||||||
|
@State private var isLoading = false
|
||||||
|
@State private var searchTask: DispatchWorkItem?
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
VStack {
|
VStack {
|
||||||
@ -23,14 +25,37 @@ struct SelectingGroupView: View {
|
|||||||
TextField("Поиск группы", text: $text)
|
TextField("Поиск группы", text: $text)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.focused($isFocused)
|
.focused($isFocused)
|
||||||
|
.onChange(of: text) { oldValue, newValue in
|
||||||
|
searchTask?.cancel()
|
||||||
|
let task = DispatchWorkItem {
|
||||||
|
if !text.isEmpty {
|
||||||
|
vm.fetchGroups(group: text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searchTask = task
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: task)
|
||||||
|
}
|
||||||
.onSubmit {
|
.onSubmit {
|
||||||
self.isFocused = false
|
self.isFocused = false
|
||||||
if (!text.isEmpty) {
|
if (!text.isEmpty) {
|
||||||
UserDefaults.standard.set(text, forKey: "group")
|
vm.fetchWeekSchedule(group: text)
|
||||||
group = text
|
self.isLoading = true
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
self.isLoading = false
|
||||||
|
if vm.errorInNetwork == .noError {
|
||||||
|
vm.errorInNetwork = nil
|
||||||
|
print("Зашел")
|
||||||
|
UserDefaults.standard.set(text, forKey: "group")
|
||||||
|
vm.group = text
|
||||||
|
self.text = ""
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vm.isShowingAlertForIncorrectGroup = true
|
||||||
|
vm.errorInNetwork = .invalidResponse
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.text = ""
|
|
||||||
dismiss()
|
|
||||||
}
|
}
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
if isFocused {
|
if isFocused {
|
||||||
@ -52,17 +77,45 @@ struct SelectingGroupView: View {
|
|||||||
RoundedRectangle(cornerRadius: 15)
|
RoundedRectangle(cornerRadius: 15)
|
||||||
.fill(.white)
|
.fill(.white)
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 10)
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
if isLoading {
|
||||||
|
LoadingView(isLoading: $isLoading)
|
||||||
|
}
|
||||||
|
if isFocused {
|
||||||
|
ScrollView(.vertical, showsIndicators: true) {
|
||||||
|
ForEach(vm.groups) { item in
|
||||||
|
VStack {
|
||||||
|
Rectangle()
|
||||||
|
.frame(height: 1)
|
||||||
|
.foregroundColor(Color("customGray1"))
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
HStack {
|
||||||
|
Text(item.name)
|
||||||
|
.foregroundColor(.black)
|
||||||
|
.font(.custom("Montserrat-SemiBold", size: 15))
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.padding(.top, 2)
|
||||||
|
.padding(.bottom, 2)
|
||||||
|
.frame(width: UIScreen.main.bounds.width, height: 30)
|
||||||
|
.background(Color("background"))
|
||||||
|
.onTapGesture {
|
||||||
|
UserDefaults.standard.set(item.name, forKey: "group")
|
||||||
|
vm.group = item.name
|
||||||
|
vm.fetchWeekSchedule(group: item.name)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, 10)
|
||||||
.background(Color("background"))
|
.background(Color("background"))
|
||||||
.onTapGesture {
|
}
|
||||||
self.isFocused = false
|
.onAppear {
|
||||||
}
|
vm.fetchGroups(group: "кт")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
|
||||||
SelectingGroupView(group: .constant("КТбо2-6"))
|
|
||||||
}
|
|
||||||
|
@ -2,14 +2,18 @@
|
|||||||
// SelectedVPKView.swift
|
// SelectedVPKView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 30.01.2025.
|
// Created by Mironov Egor on 30.01.2025.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct SelectingVPKView: View {
|
struct SelectingVPKView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
@FocusState private var isFocused: Bool
|
@FocusState private var isFocused: Bool
|
||||||
@State private var text: String = ""
|
@State private var text: String = ""
|
||||||
|
@ObservedObject var vm: ScheduleViewModel
|
||||||
|
@State private var isLoading = false
|
||||||
|
@State private var searchTask: DispatchWorkItem?
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
VStack {
|
VStack {
|
||||||
@ -21,12 +25,37 @@ struct SelectingVPKView: View {
|
|||||||
TextField("Поиск ВПК", text: $text)
|
TextField("Поиск ВПК", text: $text)
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.focused($isFocused)
|
.focused($isFocused)
|
||||||
|
.onChange(of: text) { oldValue, newValue in
|
||||||
|
searchTask?.cancel()
|
||||||
|
let task = DispatchWorkItem {
|
||||||
|
if !text.isEmpty {
|
||||||
|
vm.fetchGroups(group: text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searchTask = task
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: task)
|
||||||
|
}
|
||||||
.onSubmit {
|
.onSubmit {
|
||||||
self.isFocused = false
|
self.isFocused = false
|
||||||
if (!text.isEmpty) {
|
if (!text.isEmpty) {
|
||||||
UserDefaults.standard.set(text, forKey: "group")
|
vm.fetchWeekSchedule(group: text)
|
||||||
|
self.isLoading = true
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
self.isLoading = false
|
||||||
|
if vm.errorInNetwork == .noError {
|
||||||
|
vm.errorInNetwork = nil
|
||||||
|
print("Зашел")
|
||||||
|
UserDefaults.standard.set(text, forKey: "vpk")
|
||||||
|
vm.group = text
|
||||||
|
self.text = ""
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vm.isShowingAlertForIncorrectGroup = true
|
||||||
|
vm.errorInNetwork = .invalidResponse
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.text = ""
|
|
||||||
}
|
}
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
if isFocused {
|
if isFocused {
|
||||||
@ -48,17 +77,45 @@ struct SelectingVPKView: View {
|
|||||||
RoundedRectangle(cornerRadius: 15)
|
RoundedRectangle(cornerRadius: 15)
|
||||||
.fill(.white)
|
.fill(.white)
|
||||||
)
|
)
|
||||||
.padding(.horizontal, 10)
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
if isLoading {
|
||||||
|
LoadingView(isLoading: $isLoading)
|
||||||
|
}
|
||||||
|
if isFocused {
|
||||||
|
ScrollView(.vertical, showsIndicators: true) {
|
||||||
|
ForEach(vm.groups) { item in
|
||||||
|
VStack {
|
||||||
|
Rectangle()
|
||||||
|
.frame(height: 1)
|
||||||
|
.foregroundColor(Color("customGray1"))
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
HStack {
|
||||||
|
Text(item.name)
|
||||||
|
.foregroundColor(.black)
|
||||||
|
.font(.custom("Montserrat-SemiBold", size: 15))
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.padding(.top, 2)
|
||||||
|
.padding(.bottom, 2)
|
||||||
|
.frame(width: UIScreen.main.bounds.width, height: 30)
|
||||||
|
.background(Color("background"))
|
||||||
|
.onTapGesture {
|
||||||
|
UserDefaults.standard.set(item.name, forKey: "vpk")
|
||||||
|
vm.group = item.name
|
||||||
|
vm.fetchWeekSchedule(group: item.name)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, 10)
|
||||||
.background(Color("background"))
|
.background(Color("background"))
|
||||||
.onTapGesture {
|
}
|
||||||
self.isFocused = false
|
.onAppear {
|
||||||
}
|
vm.fetchGroups(group: "впк")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
|
||||||
SelectingVPKView()
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// SettingsView.swift
|
// SettingsView.swift
|
||||||
// Schedule ICTIS
|
// Schedule ICTIS
|
||||||
//
|
//
|
||||||
// Created by G412 on 30.01.2025.
|
// Created by Mironov Egor on 30.01.2025.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
@ -11,6 +11,8 @@ struct SettingsView: View {
|
|||||||
@ObservedObject var vm: ScheduleViewModel
|
@ObservedObject var vm: ScheduleViewModel
|
||||||
@State private var selectedTheme = "Светлая"
|
@State private var selectedTheme = "Светлая"
|
||||||
@State private var selectedLanguage = "Русский"
|
@State private var selectedLanguage = "Русский"
|
||||||
|
@AppStorage("group") private var favGroup = ""
|
||||||
|
@AppStorage("vpk") private var favVPK = ""
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
VStack {
|
VStack {
|
||||||
@ -28,17 +30,18 @@ struct SettingsView: View {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
Section("Расписание") {
|
Section("Расписание") {
|
||||||
NavigationLink(destination: SelectingGroupView(group: $vm.group)) {
|
NavigationLink(destination: SelectingGroupView(vm: vm)) {
|
||||||
LabeledContent {
|
LabeledContent {
|
||||||
Text(vm.group)
|
Text(favGroup)
|
||||||
} label: {
|
} label: {
|
||||||
Text("Избранное расписание")
|
Text("Избранное расписание")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NavigationLink(destination: SelectingVPKView()) {
|
NavigationLink(destination: SelectingVPKView(vm: vm)) {
|
||||||
LabeledContent {
|
LabeledContent {
|
||||||
|
Text(favVPK)
|
||||||
} label: {
|
} label: {
|
||||||
Text("ВПК")
|
Text("Избранное ВПК")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,9 +185,11 @@ extension WeekViewForWeek {
|
|||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
if weekSlider.indices.contains(currentWeekIndex) {
|
if weekSlider.indices.contains(currentWeekIndex) {
|
||||||
if let firstDate = weekSlider[currentWeekIndex].first?.date,
|
if let firstDate = weekSlider[currentWeekIndex].first?.date,
|
||||||
currentWeekIndex == 0 {
|
currentWeekIndex == 0 {
|
||||||
vm.week -= 1
|
vm.week -= 1
|
||||||
vm.fetchWeekSchedule(isOtherWeek: true)
|
if vm.group != "" {
|
||||||
|
vm.fetchWeekSchedule(isOtherWeek: true)
|
||||||
|
}
|
||||||
weekSlider.insert(firstDate.createPrevioustWeek(), at: 0)
|
weekSlider.insert(firstDate.createPrevioustWeek(), at: 0)
|
||||||
weekSlider.removeLast()
|
weekSlider.removeLast()
|
||||||
currentWeekIndex = 1
|
currentWeekIndex = 1
|
||||||
@ -196,9 +198,11 @@ extension WeekViewForWeek {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let lastDate = weekSlider[currentWeekIndex].last?.date,
|
if let lastDate = weekSlider[currentWeekIndex].last?.date,
|
||||||
currentWeekIndex == (weekSlider.count - 1) {
|
currentWeekIndex == (weekSlider.count - 1) {
|
||||||
vm.week += 1
|
vm.week += 1
|
||||||
vm.fetchWeekSchedule(isOtherWeek: true)
|
if vm.group != "" {
|
||||||
|
vm.fetchWeekSchedule(isOtherWeek: true)
|
||||||
|
}
|
||||||
weekSlider.append(lastDate.createNextWeek())
|
weekSlider.append(lastDate.createNextWeek())
|
||||||
weekSlider.removeFirst()
|
weekSlider.removeFirst()
|
||||||
currentWeekIndex = weekSlider.count - 2
|
currentWeekIndex = weekSlider.count - 2
|
||||||
@ -242,8 +246,10 @@ extension WeekViewForMonth {
|
|||||||
}
|
}
|
||||||
print(difBetweenWeeks)
|
print(difBetweenWeeks)
|
||||||
vm.week += difBetweenWeeks
|
vm.week += difBetweenWeeks
|
||||||
vm.fetchWeekSchedule(isOtherWeek: true)
|
if vm.group != "" {
|
||||||
|
vm.fetchWeekSchedule(isOtherWeek: true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
vm.selectedDay = day.date
|
vm.selectedDay = day.date
|
||||||
vm.updateSelectedDayIndex()
|
vm.updateSelectedDayIndex()
|
||||||
}
|
}
|
||||||
@ -271,25 +277,29 @@ extension MonthTabView {
|
|||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
if monthSlider.indices.contains(currentMonthIndex) {
|
if monthSlider.indices.contains(currentMonthIndex) {
|
||||||
if let firstDate = monthSlider[currentMonthIndex].first?.week[0].date,
|
if let firstDate = monthSlider[currentMonthIndex].first?.week[0].date,
|
||||||
currentMonthIndex == 0 {
|
currentMonthIndex == 0 {
|
||||||
monthSlider.insert(firstDate.createPreviousMonth(), at: 0)
|
monthSlider.insert(firstDate.createPreviousMonth(), at: 0)
|
||||||
monthSlider.removeLast()
|
monthSlider.removeLast()
|
||||||
currentMonthIndex = 1
|
currentMonthIndex = 1
|
||||||
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: -5, to: vm.selectedDay) ?? Date.init()
|
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: -5, to: vm.selectedDay) ?? Date.init()
|
||||||
vm.updateSelectedDayIndex()
|
vm.updateSelectedDayIndex()
|
||||||
vm.week -= 5
|
vm.week -= 5
|
||||||
vm.fetchWeekSchedule(isOtherWeek: true)
|
if vm.group != "" {
|
||||||
|
vm.fetchWeekSchedule(isOtherWeek: true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let lastDate = monthSlider[currentMonthIndex].last?.week[6].date,
|
if let lastDate = monthSlider[currentMonthIndex].last?.week[6].date,
|
||||||
currentMonthIndex == (monthSlider.count - 1) {
|
currentMonthIndex == (monthSlider.count - 1) {
|
||||||
monthSlider.append(lastDate.createNextMonth())
|
monthSlider.append(lastDate.createNextMonth())
|
||||||
monthSlider.removeFirst()
|
monthSlider.removeFirst()
|
||||||
currentMonthIndex = monthSlider.count - 2
|
currentMonthIndex = monthSlider.count - 2
|
||||||
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: 5, to: vm.selectedDay) ?? Date.init()
|
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: 5, to: vm.selectedDay) ?? Date.init()
|
||||||
vm.updateSelectedDayIndex()
|
vm.updateSelectedDayIndex()
|
||||||
vm.week += 5
|
vm.week += 5
|
||||||
vm.fetchWeekSchedule(isOtherWeek: true)
|
if vm.group != "" {
|
||||||
|
vm.fetchWeekSchedule(isOtherWeek: true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,9 @@ final class NetworkManager {
|
|||||||
|
|
||||||
func getSchedule(_ group: String) async throws -> Schedule {
|
func getSchedule(_ group: String) async throws -> Schedule {
|
||||||
let newUrlForGroup = makeUrlForGroup(group)
|
let newUrlForGroup = makeUrlForGroup(group)
|
||||||
guard let url = URL(string: newUrlForGroup) else {throw NetworkError.invalidUrl}
|
guard let url = URL(string: newUrlForGroup) else { throw NetworkError.invalidUrl }
|
||||||
let (data, response) = try await URLSession.shared.data(from: url)
|
let (data, response) = try await URLSession.shared.data(from: url)
|
||||||
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {throw NetworkError.invalidResponse}
|
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { throw NetworkError.invalidResponse }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
return try decoder.decode(Schedule.self, from: data)
|
return try decoder.decode(Schedule.self, from: data)
|
||||||
@ -46,9 +46,9 @@ final class NetworkManager {
|
|||||||
func getScheduleForOtherWeek(_ numOfWeek: Int, _ htmlNameOfGroup: String) async throws -> Schedule {
|
func getScheduleForOtherWeek(_ numOfWeek: Int, _ htmlNameOfGroup: String) async throws -> Schedule {
|
||||||
let newUrlForWeek = makeUrlForWeek(numOfWeek, htmlNameOfGroup)
|
let newUrlForWeek = makeUrlForWeek(numOfWeek, htmlNameOfGroup)
|
||||||
print(newUrlForWeek)
|
print(newUrlForWeek)
|
||||||
guard let url = URL(string: newUrlForWeek) else {throw NetworkError.invalidUrl}
|
guard let url = URL(string: newUrlForWeek) else { throw NetworkError.invalidUrl }
|
||||||
let (data, response) = try await URLSession.shared.data(from: url)
|
let (data, response) = try await URLSession.shared.data(from: url)
|
||||||
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {throw NetworkError.invalidResponse}
|
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { throw NetworkError.invalidResponse }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
return try decoder.decode(Schedule.self, from: data)
|
return try decoder.decode(Schedule.self, from: data)
|
||||||
@ -57,4 +57,18 @@ final class NetworkManager {
|
|||||||
throw NetworkError.invalidData
|
throw NetworkError.invalidData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGroups(group: String) async throws -> Welcome {
|
||||||
|
let newUrlForGroups = makeUrlForGroup(group)
|
||||||
|
guard let url = URL(string: newUrlForGroups) else { throw NetworkError.invalidUrl }
|
||||||
|
let (data, response) = try await URLSession.shared.data(from: url)
|
||||||
|
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { throw NetworkError.invalidResponse }
|
||||||
|
|
||||||
|
do {
|
||||||
|
return try decoder.decode(Welcome.self, from: data)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw NetworkError.invalidData
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import Foundation
|
|||||||
@MainActor
|
@MainActor
|
||||||
final class ScheduleViewModel: ObservableObject {
|
final class ScheduleViewModel: ObservableObject {
|
||||||
//MARK: Properties
|
//MARK: Properties
|
||||||
|
//Schedule
|
||||||
@Published var weekSchedule: Table = Table(
|
@Published var weekSchedule: Table = Table(
|
||||||
type: "",
|
type: "",
|
||||||
name: "",
|
name: "",
|
||||||
@ -30,6 +31,12 @@ final class ScheduleViewModel: ObservableObject {
|
|||||||
@Published var group: String = ""
|
@Published var group: String = ""
|
||||||
@Published var isNewGroup: Bool = false
|
@Published var isNewGroup: Bool = false
|
||||||
|
|
||||||
|
//Groups
|
||||||
|
@Published var groups: [Choice] = []
|
||||||
|
//VPK
|
||||||
|
@Published var vpk: [[String]] = []
|
||||||
|
|
||||||
|
|
||||||
//MARK: Methods
|
//MARK: Methods
|
||||||
func fetchWeekSchedule(group: String = "default", isOtherWeek: Bool = false) {
|
func fetchWeekSchedule(group: String = "default", isOtherWeek: Bool = false) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
@ -42,10 +49,11 @@ final class ScheduleViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
// В else мы заходим в том случае, если не знаем номер недели, которую нужно отобразить и номер группы(в html формате)
|
// В else мы заходим в том случае, если не знаем номер недели, которую нужно отобразить и номер группы(в html формате)
|
||||||
else {
|
else {
|
||||||
|
print("Отладка 1")
|
||||||
schedule = try await NetworkManager.shared.getSchedule(group)
|
schedule = try await NetworkManager.shared.getSchedule(group)
|
||||||
if (!self.isFirstStartOffApp) {
|
print("Отладка 2")
|
||||||
self.isNewGroup = true
|
self.group = group
|
||||||
}
|
self.isNewGroup = true
|
||||||
self.selectedDay = .init()
|
self.selectedDay = .init()
|
||||||
}
|
}
|
||||||
self.weekSchedule = schedule.table
|
self.weekSchedule = schedule.table
|
||||||
@ -56,7 +64,7 @@ final class ScheduleViewModel: ObservableObject {
|
|||||||
self.isShowingAlertForIncorrectGroup = false
|
self.isShowingAlertForIncorrectGroup = false
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
self.errorInNetwork = .noError
|
self.errorInNetwork = .noError
|
||||||
|
print("Отладка 4")
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
if let error = error as? NetworkError {
|
if let error = error as? NetworkError {
|
||||||
@ -67,10 +75,33 @@ final class ScheduleViewModel: ObservableObject {
|
|||||||
errorInNetwork = .invalidData
|
errorInNetwork = .invalidData
|
||||||
self.isShowingAlertForIncorrectGroup = true
|
self.isShowingAlertForIncorrectGroup = true
|
||||||
default:
|
default:
|
||||||
print(2)
|
print("Неизвестная ошибка: \(error)")
|
||||||
}
|
}
|
||||||
isLoading = false
|
isLoading = false
|
||||||
print(error)
|
print("Есть ошибка: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchGroups(group: String) {
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
var groups: Welcome
|
||||||
|
groups = try await NetworkManager.shared.getGroups(group: group)
|
||||||
|
self.groups = groups.choices
|
||||||
|
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
if let error = error as? NetworkError {
|
||||||
|
switch (error) {
|
||||||
|
case .invalidData:
|
||||||
|
self.groups.removeAll()
|
||||||
|
default:
|
||||||
|
self.groups.removeAll()
|
||||||
|
print("Неизвестная ошибка: \(error)")
|
||||||
|
}
|
||||||
|
print("Есть ошибка: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user