diff --git a/Schedule-ICTIS.xcodeproj/project.xcworkspace/xcuserdata/g412.xcuserdatad/IDEFindNavigatorScopes.plist b/Schedule-ICTIS.xcodeproj/project.xcworkspace/xcuserdata/g412.xcuserdatad/IDEFindNavigatorScopes.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/Schedule-ICTIS.xcodeproj/project.xcworkspace/xcuserdata/g412.xcuserdatad/IDEFindNavigatorScopes.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/Contents.json index 2305880..529cf81 100644 --- a/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,6 +1,7 @@ { "images" : [ { + "filename" : "ICTIS_logo.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/ICTIS_logo.png b/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/ICTIS_logo.png new file mode 100644 index 0000000..44b05e5 Binary files /dev/null and b/Schedule-ICTIS/Assets.xcassets/AppIcon.appiconset/ICTIS_logo.png differ diff --git a/Schedule-ICTIS/Assets.xcassets/ICTIS_logo.imageset/Contents.json b/Schedule-ICTIS/Assets.xcassets/ICTIS_logo.imageset/Contents.json new file mode 100644 index 0000000..4cd4b61 --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/ICTIS_logo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ICTIS_logo.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule-ICTIS/Assets.xcassets/ICTIS_logo.imageset/ICTIS_logo.png b/Schedule-ICTIS/Assets.xcassets/ICTIS_logo.imageset/ICTIS_logo.png new file mode 100644 index 0000000..44b05e5 Binary files /dev/null and b/Schedule-ICTIS/Assets.xcassets/ICTIS_logo.imageset/ICTIS_logo.png differ diff --git a/Schedule-ICTIS/Assets.xcassets/arrowRight.imageset/Contents.json b/Schedule-ICTIS/Assets.xcassets/arrowRight.imageset/Contents.json new file mode 100644 index 0000000..985ff81 --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/arrowRight.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "arrowRight.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule-ICTIS/Assets.xcassets/arrowRight.imageset/arrowRight.svg b/Schedule-ICTIS/Assets.xcassets/arrowRight.imageset/arrowRight.svg new file mode 100644 index 0000000..394cec0 --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/arrowRight.imageset/arrowRight.svg @@ -0,0 +1,3 @@ + + + diff --git a/Schedule-ICTIS/Assets.xcassets/arrowdown.imageset/Contents.json b/Schedule-ICTIS/Assets.xcassets/arrowdown.imageset/Contents.json new file mode 100644 index 0000000..cfd47c3 --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/arrowdown.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "arrowdown.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule-ICTIS/Assets.xcassets/arrowdown.imageset/arrowdown.svg b/Schedule-ICTIS/Assets.xcassets/arrowdown.imageset/arrowdown.svg new file mode 100644 index 0000000..702229d --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/arrowdown.imageset/arrowdown.svg @@ -0,0 +1,3 @@ + + + diff --git a/Schedule-ICTIS/Assets.xcassets/arrowup.imageset/Contents.json b/Schedule-ICTIS/Assets.xcassets/arrowup.imageset/Contents.json new file mode 100644 index 0000000..c50124f --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/arrowup.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "arrowup.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule-ICTIS/Assets.xcassets/arrowup.imageset/arrowup.svg b/Schedule-ICTIS/Assets.xcassets/arrowup.imageset/arrowup.svg new file mode 100644 index 0000000..4c077ab --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/arrowup.imageset/arrowup.svg @@ -0,0 +1,3 @@ + + + diff --git a/Schedule-ICTIS/Assets.xcassets/upDownArrows.imageset/Contents.json b/Schedule-ICTIS/Assets.xcassets/upDownArrows.imageset/Contents.json new file mode 100644 index 0000000..0e744ce --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/upDownArrows.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "upDownArrows.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule-ICTIS/Assets.xcassets/upDownArrows.imageset/upDownArrows.svg b/Schedule-ICTIS/Assets.xcassets/upDownArrows.imageset/upDownArrows.svg new file mode 100644 index 0000000..5c4964b --- /dev/null +++ b/Schedule-ICTIS/Assets.xcassets/upDownArrows.imageset/upDownArrows.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Schedule-ICTIS/ContentView.swift b/Schedule-ICTIS/ContentView.swift index 67410f1..0a28402 100644 --- a/Schedule-ICTIS/ContentView.swift +++ b/Schedule-ICTIS/ContentView.swift @@ -34,6 +34,18 @@ struct ContentView: View { } TabBarView(selectedTab: $selectedTab) } + .alert(isPresented: $vm.isShowingAlertForIncorrectSingleGroup, error: vm.errorInNetworkForSingleGroup) { error in + Button("ОК") { + print("This alert") + vm.isShowingAlertForIncorrectSingleGroup = false + vm.errorInNetworkForSingleGroup = nil + } + } message: { error in + Text(error.failureReason) + } + .onAppear { + vm.fillFilteringGroups() + } } } diff --git a/Schedule-ICTIS/Info.plist b/Schedule-ICTIS/Info.plist index 85932e1..a176597 100644 --- a/Schedule-ICTIS/Info.plist +++ b/Schedule-ICTIS/Info.plist @@ -8,7 +8,7 @@ Montserrat-BlackItalic.ttf Montserrat-Bold.ttf Montserrat-BoldItalic.ttf - Monsterrat-ExtraBold.ttf + Montserrat-ExtraBold.ttf Montserrat-ExtraBoldItalic.ttf Montserrat-ExtraLight.ttf Montserrat-ExtraLightItalic.ttf diff --git a/Schedule-ICTIS/Main/Views/FilterGroupsView.swift b/Schedule-ICTIS/Main/Views/FilterGroupsView.swift index de03064..455a1f2 100644 --- a/Schedule-ICTIS/Main/Views/FilterGroupsView.swift +++ b/Schedule-ICTIS/Main/Views/FilterGroupsView.swift @@ -9,43 +9,69 @@ import SwiftUI struct FilterGroupsView: View { @ObservedObject var vm: ScheduleViewModel + @ObservedObject var networkMonitor: NetworkMonitor + var body: some View { ScrollView(.horizontal, showsIndicators: false) { LazyHStack(spacing: 12) { - ForEach(vm.filteringGroups, id: \.self) { group in - VStack { - Text(group) + // Кнопка добавления новой группы + NavigationLink(destination: SelectingGroupView(vm: vm, networkMonitor: networkMonitor)) { + ZStack { + Rectangle() + .frame(width: 28, height: 28) + .foregroundStyle(.white) + .cornerRadius(20) + Image(systemName: "plus") .foregroundColor(Color("customGray3")) - .font(.custom("Montserrat-Medium", fixedSize: 14)) - .padding(.horizontal, 15) - .padding(.vertical, 7) + .font(.system(size: 12)) } - .background(Color.white) - .overlay ( - Group { - if vm.showOnlyChoosenGroup == group { - RoundedRectangle(cornerRadius: 20) - .stroke(Color("blueColor"), lineWidth: 3) - } + } + + if vm.filteringGroups.count == 2 { + ForEach(vm.filteringGroups.dropFirst(), id: \.self) { group in + GroupItem(group: group, isSelected: vm.showOnlyChoosenGroup == group) { + vm.showOnlyChoosenGroup = group + } + } + } else if vm.filteringGroups.count > 2 { + ForEach(vm.filteringGroups, id: \.self) { group in + GroupItem(group: group, isSelected: vm.showOnlyChoosenGroup == group) { + vm.showOnlyChoosenGroup = group } - ) - .cornerRadius(20) - .onTapGesture { - vm.showOnlyChoosenGroup = group } } } .padding(.horizontal) } .frame(height: 40) - .onAppear { - vm.updateFilteringGroups() - } .padding(.bottom, 4) } } +// Вынесенный компонент для элемента группы +struct GroupItem: View { + let group: String + let isSelected: Bool + let action: () -> Void + + var body: some View { + Text(group) + .foregroundColor(Color("customGray3")) + .font(.custom("Montserrat-Medium", fixedSize: 14)) + .padding(.horizontal, 15) + .padding(.vertical, 7) + .background(Color.white) + .overlay( + RoundedRectangle(cornerRadius: 20) + .stroke(isSelected ? Color("blueColor") : Color.clear, lineWidth: 3) + ) + .cornerRadius(20) + .onTapGesture(perform: action) + } +} + #Preview { @Previewable @ObservedObject var vm = ScheduleViewModel() - FilterGroupsView(vm: vm) + @Previewable @ObservedObject var networkMonitor = NetworkMonitor() + FilterGroupsView(vm: vm, networkMonitor: networkMonitor) } diff --git a/Schedule-ICTIS/Main/Views/MainView.swift b/Schedule-ICTIS/Main/Views/MainView.swift index bf70521..177450e 100644 --- a/Schedule-ICTIS/Main/Views/MainView.swift +++ b/Schedule-ICTIS/Main/Views/MainView.swift @@ -14,32 +14,34 @@ struct MainView: View { @FocusState private var isFocusedSearchBar: Bool @State private var isScrolling: Bool = false var body: some View { - VStack { - SearchBarView(isFocused: _isFocusedSearchBar, vm: vm, isShowingMonthSlider: $isShowingMonthSlider) - .onChange(of: isScrolling, initial: false) { oldValue, newValue in - if newValue && isScrolling { - isFocusedSearchBar = false + NavigationStack { + VStack { + SearchBarView(isFocused: _isFocusedSearchBar, vm: vm, isShowingMonthSlider: $isShowingMonthSlider) + .onChange(of: isScrolling, initial: false) { oldValue, newValue in + if newValue && isScrolling { + isFocusedSearchBar = false + } } + CurrentDateView() + FilterGroupsView(vm: vm, networkMonitor: networkMonitor) + if vm.isLoading { + LoadingScheduleView() + } + else { + ScheduleView(vm: vm, networkMonitor: networkMonitor, isScrolling: $isScrolling) } - CurrentDateView() - FilterGroupsView(vm: vm) - if vm.isLoading { - LoadingScheduleView() } - else { - ScheduleView(vm: vm, networkMonitor: networkMonitor, isScrolling: $isScrolling) + .alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in + Button("ОК") { + print("This alert") + vm.isShowingAlertForIncorrectGroup = false + vm.errorInNetwork = nil + } + } message: { error in + Text(error.failureReason) } + .background(Color("background")) } - .alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in - Button("ОК") { - print("This alert") - vm.isShowingAlertForIncorrectGroup = false - vm.errorInNetwork = nil - } - } message: { error in - Text(error.failureReason) - } - .background(Color("background")) } @ViewBuilder diff --git a/Schedule-ICTIS/Main/Views/SearchBarView.swift b/Schedule-ICTIS/Main/Views/SearchBarView.swift index ee2c445..fb856fc 100644 --- a/Schedule-ICTIS/Main/Views/SearchBarView.swift +++ b/Schedule-ICTIS/Main/Views/SearchBarView.swift @@ -31,8 +31,9 @@ struct SearchBarView: View { if (!text.isEmpty) { vm.fetchWeekForSingleGroup(groupName: text) DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - guard vm.errorInNetwork == .noError else { - vm.isShowingAlertForIncorrectGroup = true + guard vm.errorInNetworkForSingleGroup == .noError else { + vm.isShowingAlertForIncorrectSingleGroup = true + self.text = "" return } vm.removeFromSchedule(group: vm.searchingGroup) @@ -40,7 +41,7 @@ struct SearchBarView: View { vm.searchingGroup = text vm.nameToHtml[text] = "" print("Ключи: \(vm.nameToHtml.keys)") - vm.updateFilteringGroups() + vm.addGroupToFilteringArray(group: text) vm.fetchWeekSchedule() self.text = "" } @@ -77,12 +78,10 @@ struct SearchBarView: View { Rectangle() .frame(width: 40, height: 40) .foregroundStyle(Color("blueColor")) - .cornerRadius(15) + .cornerRadius(10) Image(systemName: "plus") - .resizable() - .foregroundStyle(.white) - .scaledToFit() - .frame(width: 16) + .foregroundColor(.white) + .font(.system(size: 22)) } } } diff --git a/Schedule-ICTIS/Model/JsonClassModel.swift b/Schedule-ICTIS/Model/JsonClassModel.swift index f0ee6ec..756504d 100644 --- a/Schedule-ICTIS/Model/JsonClassModel.swift +++ b/Schedule-ICTIS/Model/JsonClassModel.swift @@ -51,8 +51,6 @@ extension JsonClassModel { let groupsToDelete = try context.fetch(fetchRequest) - print("Пары для удаления: \(groupsToDelete)") - for group in groupsToDelete { do { try ClassProvider.shared.delete(group, in: context) diff --git a/Schedule-ICTIS/Settings/FavGroupsView.swift b/Schedule-ICTIS/Settings/FavGroupsView.swift index 6d2dca6..b7af5cd 100644 --- a/Schedule-ICTIS/Settings/FavGroupsView.swift +++ b/Schedule-ICTIS/Settings/FavGroupsView.swift @@ -9,6 +9,7 @@ import SwiftUI import CoreData struct FavGroupsView: View { + @Environment(\.dismiss) private var dismiss @ObservedObject var vm: ScheduleViewModel @ObservedObject var networkMonitor: NetworkMonitor @FetchRequest(fetchRequest: FavouriteGroupModel.all()) private var favGroups // Список групп сохраненных в CoreData @@ -39,28 +40,39 @@ struct FavGroupsView: View { } } } - - Spacer() - - HStack { - Spacer() + } + .navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад" + .background(Color("background")) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button(action: { + dismiss() + }) { + HStack { + Image(systemName: "chevron.left") + Text("Настройки") + } + .foregroundColor(.blue) + } + } + // Кнопка в правой части + ToolbarItem(placement: .topBarTrailing) { if favGroups.count < 10 { NavigationLink(destination: SelectingGroupView(vm: vm, networkMonitor: networkMonitor)) { - HStack { + ZStack { + Rectangle() + .frame(width: 40, height: 40) + .foregroundStyle(Color("blueColor")) + .cornerRadius(10) Image(systemName: "plus") .foregroundColor(.white) - .font(.system(size: 22)) - .padding(EdgeInsets(top: 12, leading: 12, bottom: 12, trailing: 12)) + .font(.system(size: 18)) } - .background(Color("blueColor")) - .cornerRadius(10) - .padding(.trailing, 20) } } } - .padding(.bottom, 90) } - .background(Color("background")) + .navigationBarTitleDisplayMode(.inline) } } diff --git a/Schedule-ICTIS/Settings/FavVPKView.swift b/Schedule-ICTIS/Settings/FavVPKView.swift index 4bd2840..66083fd 100644 --- a/Schedule-ICTIS/Settings/FavVPKView.swift +++ b/Schedule-ICTIS/Settings/FavVPKView.swift @@ -8,6 +8,7 @@ import SwiftUI struct FavVPKView: View { + @Environment(\.dismiss) private var dismiss @ObservedObject var vm: ScheduleViewModel @ObservedObject var networkMonitor: NetworkMonitor @FetchRequest(fetchRequest: FavouriteVpkModel.all()) private var favVpk // Список ВПК сохраненных в CoreData @@ -38,28 +39,39 @@ struct FavVPKView: View { } } } - - Spacer() - - HStack { - Spacer() + } + .navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад" + .background(Color("background")) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button(action: { + dismiss() + }) { + HStack { + Image(systemName: "chevron.left") + Text("Настройки") + } + .foregroundColor(.blue) + } + } + // Кнопка в правой части + ToolbarItem(placement: .topBarTrailing) { if favVpk.count < 5 { NavigationLink(destination: SelectingVPKView(vm: vm, networkMonitor: networkMonitor)) { - HStack { + ZStack { + Rectangle() + .frame(width: 40, height: 40) + .foregroundStyle(Color("blueColor")) + .cornerRadius(10) Image(systemName: "plus") .foregroundColor(.white) - .font(.system(size: 22)) - .padding(EdgeInsets(top: 12, leading: 12, bottom: 12, trailing: 12)) + .font(.system(size: 18)) } - .background(Color("blueColor")) - .cornerRadius(10) - .padding(.trailing, 20) } } } - .padding(.bottom, 90) } - .background(Color("background")) + .navigationBarTitleDisplayMode(.inline) } } diff --git a/Schedule-ICTIS/Settings/ListOfGroupsView.swift b/Schedule-ICTIS/Settings/ListOfGroupsView.swift index 2f27c77..cf70496 100644 --- a/Schedule-ICTIS/Settings/ListOfGroupsView.swift +++ b/Schedule-ICTIS/Settings/ListOfGroupsView.swift @@ -38,7 +38,7 @@ struct ListOfGroupsView: View { try saveGroup(name: item.name) saveScheduleForVpkToMemory(withName: item.name) vm.nameToHtml[item.name] = "" - vm.updateFilteringGroups() + vm.addGroupToFilteringArray(group: item.name) vm.fetchWeekSchedule() dismiss() } catch { diff --git a/Schedule-ICTIS/Settings/SelectingGroupView.swift b/Schedule-ICTIS/Settings/SelectingGroupView.swift index 5311de8..4ff7f91 100644 --- a/Schedule-ICTIS/Settings/SelectingGroupView.swift +++ b/Schedule-ICTIS/Settings/SelectingGroupView.swift @@ -45,30 +45,29 @@ struct SelectingGroupView: View { self.isFocused = false guard !text.isEmpty else { return } - vm.fetchWeekForSingleGroup(groupName: text) self.isLoading = true + vm.fetchWeekForSingleGroup(groupName: text) DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - guard vm.errorInNetwork == .noError else { - vm.isShowingAlertForIncorrectGroup = true + if vm.errorInNetworkForSingleGroup != .noError { return } - vm.errorInNetwork = nil + vm.errorInNetworkForSingleGroup = nil let formattedText = transformStringToFormat(text) do { try saveGroup(name: formattedText) saveScheduleForGroupToMemory(withName: formattedText) vm.nameToHtml[formattedText] = "" - vm.updateFilteringGroups() + vm.addGroupToFilteringArray(group: formattedText) vm.fetchWeekSchedule() self.isLoading = false self.text = "" dismiss() } catch { print("Ошибка сохранения: \(error.localizedDescription)") - vm.isShowingAlertForIncorrectGroup = true + vm.isShowingAlertForIncorrectSingleGroup = true } } } @@ -88,10 +87,10 @@ struct SelectingGroupView: View { } } .frame(height: 40) - .background( - RoundedRectangle(cornerRadius: 15) + .background ( + RoundedRectangle(cornerRadius: 10) .fill(.white) - ) + ) Spacer() if isLoading { LoadingView() @@ -121,7 +120,7 @@ struct SelectingGroupView: View { try saveGroup(name: item.name) saveScheduleForGroupToMemory(withName: item.name) vm.nameToHtml[item.name] = "" - vm.updateFilteringGroups() + vm.addGroupToFilteringArray(group: item.name) vm.fetchWeekSchedule() self.isLoading = false self.text = "" @@ -144,6 +143,21 @@ struct SelectingGroupView: View { .onAppear { serchGroupsVM.fetchGroups(group: "кт") } + .navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад" + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button(action: { + dismiss() + }) { + HStack { + Image(systemName: "chevron.left") + Text("Назад") + } + .foregroundColor(.blue) + } + } + } + .navigationBarTitleDisplayMode(.inline) } } diff --git a/Schedule-ICTIS/Settings/SelectingVPKView.swift b/Schedule-ICTIS/Settings/SelectingVPKView.swift index 1173a3d..a13358e 100644 --- a/Schedule-ICTIS/Settings/SelectingVPKView.swift +++ b/Schedule-ICTIS/Settings/SelectingVPKView.swift @@ -45,30 +45,29 @@ struct SelectingVPKView: View { self.isFocused = false guard !text.isEmpty else { return } - vm.fetchWeekForSingleGroup(groupName: text) self.isLoading = true + vm.fetchWeekForSingleGroup(groupName: text) DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - guard vm.errorInNetwork == .noError else { - vm.isShowingAlertForIncorrectGroup = true + guard vm.errorInNetworkForSingleGroup == .noError else { return } - vm.errorInNetwork = nil + vm.errorInNetworkForSingleGroup = nil let formattedText = transformStringToFormat(text) do { try saveGroup(name: formattedText) saveScheduleForVpkToMemory(withName: formattedText) vm.nameToHtml[formattedText] = "" - vm.updateFilteringGroups() + vm.addGroupToFilteringArray(group: formattedText) vm.fetchWeekSchedule() self.isLoading = false self.text = "" dismiss() } catch { print("Ошибка сохранения: \(error.localizedDescription)") - vm.isShowingAlertForIncorrectGroup = true + vm.isShowingAlertForIncorrectSingleGroup = true } } } @@ -107,6 +106,21 @@ struct SelectingVPKView: View { .onAppear { serchGroupsVM.fetchGroups(group: "ВПК") } + .navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад" + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button(action: { + dismiss() + }) { + HStack { + Image(systemName: "chevron.left") + Text("Назад") + } + .foregroundColor(.blue) + } + } + } + .navigationBarTitleDisplayMode(.inline) } } diff --git a/Schedule-ICTIS/Settings/SettingsView.swift b/Schedule-ICTIS/Settings/SettingsView.swift index 115dbec..08f1feb 100644 --- a/Schedule-ICTIS/Settings/SettingsView.swift +++ b/Schedule-ICTIS/Settings/SettingsView.swift @@ -13,7 +13,7 @@ struct SettingsView: View { @State private var selectedTheme = "Светлая" @State private var selectedLanguage = "Русский" var body: some View { - NavigationView { + NavigationStack { VStack { ScrollView (.vertical, showsIndicators: false) { VStack (alignment: .leading) { diff --git a/Schedule-ICTIS/Model/Utilities/Extensions/Date+Extensions.swift b/Schedule-ICTIS/Utilities/Extensions/Date+Extensions.swift similarity index 100% rename from Schedule-ICTIS/Model/Utilities/Extensions/Date+Extensions.swift rename to Schedule-ICTIS/Utilities/Extensions/Date+Extensions.swift diff --git a/Schedule-ICTIS/Model/Utilities/Extensions/OffsetKey.swift b/Schedule-ICTIS/Utilities/Extensions/OffsetKey.swift similarity index 100% rename from Schedule-ICTIS/Model/Utilities/Extensions/OffsetKey.swift rename to Schedule-ICTIS/Utilities/Extensions/OffsetKey.swift diff --git a/Schedule-ICTIS/Model/Utilities/Extensions/ScheduleView+Extensions.swift b/Schedule-ICTIS/Utilities/Extensions/ScheduleView+Extensions.swift similarity index 100% rename from Schedule-ICTIS/Model/Utilities/Extensions/ScheduleView+Extensions.swift rename to Schedule-ICTIS/Utilities/Extensions/ScheduleView+Extensions.swift diff --git a/Schedule-ICTIS/Model/Utilities/Extensions/View+Extensions.swift b/Schedule-ICTIS/Utilities/Extensions/View+Extensions.swift similarity index 100% rename from Schedule-ICTIS/Model/Utilities/Extensions/View+Extensions.swift rename to Schedule-ICTIS/Utilities/Extensions/View+Extensions.swift diff --git a/Schedule-ICTIS/Model/Utilities/Network/NetworkError.swift b/Schedule-ICTIS/Utilities/Network/NetworkError.swift similarity index 95% rename from Schedule-ICTIS/Model/Utilities/Network/NetworkError.swift rename to Schedule-ICTIS/Utilities/Network/NetworkError.swift index bfaba72..bc15b96 100644 --- a/Schedule-ICTIS/Model/Utilities/Network/NetworkError.swift +++ b/Schedule-ICTIS/Utilities/Network/NetworkError.swift @@ -21,7 +21,7 @@ enum NetworkError: String, Error, LocalizedError { case .invalidResponse: "InvalidResponse" case .invalidData: - "Проверьте номер группы" + "Проверьте имя группы" case .timeout: "Ошибка сети" case .noError: diff --git a/Schedule-ICTIS/Model/Utilities/Network/NetworkManager.swift b/Schedule-ICTIS/Utilities/Network/NetworkManager.swift similarity index 100% rename from Schedule-ICTIS/Model/Utilities/Network/NetworkManager.swift rename to Schedule-ICTIS/Utilities/Network/NetworkManager.swift diff --git a/Schedule-ICTIS/Model/Utilities/Network/NetworkMonitor.swift b/Schedule-ICTIS/Utilities/Network/NetworkMonitor.swift similarity index 100% rename from Schedule-ICTIS/Model/Utilities/Network/NetworkMonitor.swift rename to Schedule-ICTIS/Utilities/Network/NetworkMonitor.swift diff --git a/Schedule-ICTIS/ViewModel/ScheduleViewModel.swift b/Schedule-ICTIS/ViewModel/ScheduleViewModel.swift index 02485fe..d35bce1 100644 --- a/Schedule-ICTIS/ViewModel/ScheduleViewModel.swift +++ b/Schedule-ICTIS/ViewModel/ScheduleViewModel.swift @@ -17,7 +17,7 @@ final class ScheduleViewModel: ObservableObject { @Published var classesGroups: [[ClassInfo]] = [] @Published var searchingGroup = "" @Published var filteringGroups: [String] = ["Все"] - @Published var showOnlyChoosenGroup: String = "Все" + @Published var showOnlyChoosenGroup: String = "" //Schedule @Published var weekScheduleGroup: Table = Table( @@ -34,7 +34,9 @@ final class ScheduleViewModel: ObservableObject { @Published var isFirstStartOffApp = true @Published var isShowingAlertForIncorrectGroup: Bool = false + @Published var isShowingAlertForIncorrectSingleGroup: Bool = false @Published var errorInNetwork: NetworkError? + @Published var errorInNetworkForSingleGroup: NetworkError? @Published var isLoading: Bool = false @Published var isNewGroup: Bool = false @@ -141,25 +143,25 @@ final class ScheduleViewModel: ObservableObject { // Обновляем данные self.classesForSingleGroup = singleSchedule - self.isShowingAlertForIncorrectGroup = false + self.isShowingAlertForIncorrectSingleGroup = false self.isLoading = false - self.errorInNetwork = .noError + self.errorInNetworkForSingleGroup = .noError } catch { if let urlError = error as? URLError, urlError.code == .timedOut { - errorInNetwork = .timeout + errorInNetworkForSingleGroup = .timeout print("Ошибка: превышено время ожидания ответа от сервера") } else if let error = error as? NetworkError { switch error { case .invalidResponse: - errorInNetwork = .invalidResponse + errorInNetworkForSingleGroup = .invalidResponse case .invalidData: - errorInNetwork = .invalidData + errorInNetworkForSingleGroup = .invalidData print("FetchSingle: InvalidData") - self.isShowingAlertForIncorrectGroup = true default: print("Неизвестная ошибка: \(error)") } + self.isShowingAlertForIncorrectSingleGroup = true print("Есть ошибка: \(error)") } isLoading = false @@ -229,12 +231,34 @@ final class ScheduleViewModel: ObservableObject { classesGroups[i].remove(at: j) } } + + self.filteringGroups = self.filteringGroups.filter {$0 != group} + + if group == self.showOnlyChoosenGroup || self.filteringGroups.count == 2 { + selectShowingGroup() + } } - func updateFilteringGroups() { - self.filteringGroups = ["Все"] + func selectShowingGroup() { + if self.filteringGroups.count == 2 { + self.showOnlyChoosenGroup = self.filteringGroups[1] + } else if self.filteringGroups.count < 2 { + self.showOnlyChoosenGroup = "" + } + else { + self.showOnlyChoosenGroup = "Все" + } + } + + func addGroupToFilteringArray(group: String) { + self.filteringGroups.append(group) + } + + func fillFilteringGroups() { let keys = self.nameToHtml.keys print(keys) self.filteringGroups.append(contentsOf: keys) + + selectShowingGroup() } }