diff --git a/Basic-Car-Maintenance/Shared/Localizable.xcstrings b/Basic-Car-Maintenance/Shared/Localizable.xcstrings index c2eb8885..8088470c 100644 --- a/Basic-Car-Maintenance/Shared/Localizable.xcstrings +++ b/Basic-Car-Maintenance/Shared/Localizable.xcstrings @@ -730,6 +730,9 @@ } } } + }, + "Basic Car" : { + }, "Can't Delete Last Vehicle" : { "localizations" : { @@ -3686,6 +3689,17 @@ } } }, + "Sidebar" : { + "extractionState" : "stale", + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Боковая панель" + } + } + } + }, "Sign Out" : { "localizations" : { "be" : { @@ -4301,6 +4315,17 @@ } } }, + "Unexpected error occured." : { + "extractionState" : "stale", + "localizations" : { + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Произошла ошибка." + } + } + } + }, "Update" : { "comment" : "Label for submit button on form to update an existing entry", "localizations" : { diff --git a/Basic-Car-Maintenance/Shared/MainView/Views/MainTabView.swift b/Basic-Car-Maintenance/Shared/MainView/Views/MainTabView.swift index 9194f3bb..786d3333 100644 --- a/Basic-Car-Maintenance/Shared/MainView/Views/MainTabView.swift +++ b/Basic-Car-Maintenance/Shared/MainView/Views/MainTabView.swift @@ -8,12 +8,38 @@ import SwiftUI import SwiftData -enum TabSelection: Int { +enum TabSelection: Int, Identifiable, CaseIterable { + var id: Self { self } + case dashboard = 0 case odometer = 1 case settings = 2 } +extension TabSelection { + var label: LocalizedStringKey { + switch self { + case .dashboard: + return "Dashboard" + case .odometer: + return "Odometer" + case .settings: + return "Settings" + } + } + + var image: String { + switch self { + case .dashboard: + return SFSymbol.dashboard + case .odometer: + return SFSymbol.gauge + case .settings: + return SFSymbol.gear + } + } +} + @MainActor struct MainTabView: View { @Query var acknowledgedAlerts: [AcknowledgedAlert] @@ -24,28 +50,27 @@ struct MainTabView: View { @AppStorage("lastTabOpen") var selectedTab = TabSelection.dashboard + @State private var selectedTabId: TabSelection.ID? = .dashboard + @State private var columnVisibility = NavigationSplitViewVisibility.automatic + @State var authenticationViewModel = AuthenticationViewModel() @State var viewModel = MainTabViewModel() + init() { + _selectedTabId = State(initialValue: selectedTab) + } + var body: some View { - TabView(selection: $selectedTab) { - DashboardView(userUID: authenticationViewModel.user?.uid) - .tag(TabSelection.dashboard) - .tabItem { - Label("Dashboard", systemImage: SFSymbol.dashboard) - } - - OdometerView(userUID: authenticationViewModel.user?.uid) - .tag(TabSelection.odometer) - .tabItem { - Label("Odometer", systemImage: SFSymbol.gauge) - } - - SettingsView(authenticationViewModel: authenticationViewModel) - .tag(TabSelection.settings) - .tabItem { - Label("Settings", systemImage: SFSymbol.gear) - } + Group { + #if os(iOS) + if UIDevice.current.userInterfaceIdiom == .pad { + navigationSplitView() + } else { + tabView() + } + #else + navigationSplitView() + #endif } .sheet(item: $viewModel.alert) { alert in AlertView(alert: alert) @@ -73,6 +98,9 @@ struct MainTabView: View { guard let id = newValue?.id else { return } saveNewAlert(id) } + .onChange(of: selectedTabId ?? TabSelection.dashboard) { _, newValue in + selectedTab = newValue + } } /// Save newly acknowledged alert to DB @@ -81,6 +109,51 @@ struct MainTabView: View { let acknowledgedAlert = AcknowledgedAlert(id: id) context.insert(acknowledgedAlert) } + + /// Save screen content for specific selection + /// - Parameter selection: tab selection enum value + @ViewBuilder + private func selectionContent(for selection: TabSelection) -> some View { + switch selection { + case .dashboard: + DashboardView(userUID: authenticationViewModel.user?.uid) + case .odometer: + OdometerView(userUID: authenticationViewModel.user?.uid) + case .settings: + SettingsView(authenticationViewModel: authenticationViewModel) + } + } + + /// Primarily used on iPad and Mac devices + /// - Returns: `NavigationSplitView` navigation + @ViewBuilder + private func navigationSplitView() -> some View { + NavigationSplitView(columnVisibility: $columnVisibility) { + List(TabSelection.allCases, selection: $selectedTabId) { tabSelection in + Label(tabSelection.label, systemImage: tabSelection.image) + } + .navigationTitle("Basic Car") + } detail: { + if let tabSelection = selectedTabId { + selectionContent(for: tabSelection) + .tag(tabSelection) + } + } + } + + /// Primarily used on iPhone devices + /// - Returns: `TabView` navigation + @ViewBuilder func tabView() -> some View { + TabView(selection: $selectedTab) { + ForEach(TabSelection.allCases) { tabSelection in + selectionContent(for: tabSelection) + .tag(tabSelection) + .tabItem { + Label(tabSelection.label, systemImage: tabSelection.image) + } + } + } + } } #Preview {