Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipad NavigationSplitView v1: pivot tab view to siderbar #17

Merged
merged 1 commit into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 133 additions & 81 deletions MMEX/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,112 +10,107 @@ import SwiftUI
struct ContentView: View {
@State private var isDocumentPickerPresented = false
@State private var selectedTab = 0

@State private var selectedFileURL: URL?

@State private var selectedFileURL: URL?
@State private var isPresentingTransactionAddView = false

init() {
// Load the stored file URL on app start
// if let savedURL = UserDefaults.standard.url(forKey: "selectedFileURL") {
// _selectedFileURL = State(initialValue: savedURL)
// }
}
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Environment(\.verticalSizeClass) var verticalSizeClass

var body: some View {
NavigationStack {
ZStack {
if let url = selectedFileURL {
TabView (selection: $selectedTab) {
// Latest Transactions Tab
NavigationView {
TransactionListView2(databaseURL: url) // Summary and Edit feature
.navigationBarTitle("Latest Transactions", displayMode: .inline)
}
.tabItem {
Image(systemName: "list.bullet")
Text("Checking")
}
.tag(0)

// Insights module
NavigationView {
InsightsView(viewModel: InsightsViewModel(databaseURL: url))
.navigationBarTitle("Reports and Insights", displayMode: .inline)
}
.tabItem {
Image(systemName: "arrow.up.right")
Text("Insights")
}
.tag(1)


// Add Transactions Tab
NavigationView {
TransactionAddView2(databaseURL: url, selectedTab: $selectedTab) // Reuse or new transaction add
.navigationBarTitle("Add Transaction", displayMode: .inline)
}
.tabItem {
Image(systemName: "plus.circle")
Text("Add Transaction")
}
.tag(2)

// Combined Management Tab
NavigationView {
ManagementView(databaseURL: url, isDocumentPickerPresented: $isDocumentPickerPresented)
.navigationBarTitle("Management", displayMode: .inline)
}
.tabItem {
Image(systemName: "folder")
Text("Management")
if horizontalSizeClass == .regular {
// && verticalSizeClass == .compact {
// iPad layout: Tabs on the side
NavigationSplitView {
SidebarView(selectedTab: $selectedTab)
} detail: {
TabContentView(selectedTab: $selectedTab, isDocumentPickerPresented: $isDocumentPickerPresented, databaseURL: url)
}
.tag(3)

// Settings Tab
NavigationView {
SettingsView(databaseURL: url) // Payees, Accounts, Currency
.navigationBarTitle("Settings", displayMode: .inline)
} else {
// iPhone layout: Tabs at the bottom
TabView(selection: $selectedTab) {
// Latest Transactions Tab
NavigationView {
TransactionListView2(databaseURL: url) // Summary and Edit feature
.navigationBarTitle("Latest Transactions", displayMode: .inline)
}
.tabItem {
Image(systemName: "list.bullet")
Text("Checking")
}
.tag(0)

// Insights module
NavigationView {
InsightsView(viewModel: InsightsViewModel(databaseURL: url))
.navigationBarTitle("Reports and Insights", displayMode: .inline)
}
.tabItem {
Image(systemName: "arrow.up.right")
Text("Insights")
}
.tag(1)

// Add Transactions Tab
NavigationView {
TransactionAddView2(databaseURL: url, selectedTab: $selectedTab) // Reuse or new transaction add
.navigationBarTitle("Add Transaction", displayMode: .inline)
}
.tabItem {
Image(systemName: "plus.circle")
Text("Add Transaction")
}
.tag(2)

// Combined Management Tab
NavigationView {
ManagementView(databaseURL: url, isDocumentPickerPresented: $isDocumentPickerPresented)
.navigationBarTitle("Management", displayMode: .inline)
}
.tabItem {
Image(systemName: "folder")
Text("Management")
}
.tag(3)

// Settings Tab
NavigationView {
SettingsView(databaseURL: url) // Payees, Accounts, Currency
.navigationBarTitle("Settings", displayMode: .inline)
}
.tabItem {
Image(systemName: "gearshape")
Text("Settings")
}
.tag(4)
}
.tabItem {
Image(systemName: "gearshape")
Text("Settings")
}
.tag(4)
}
.onChange(of: selectedTab) { tab in
if tab == 2 {
isPresentingTransactionAddView = true
.onChange(of: selectedTab) { tab in
if tab == 2 {
isPresentingTransactionAddView = true
}
}
}
} else {

Button("Open Database") {
// Trigger the file picker
isDocumentPickerPresented = true
}
}
}
.fileImporter(
isPresented: $isDocumentPickerPresented, // Toggle state for presentation
allowedContentTypes: [.item], // Allowed types, you can customize it
allowsMultipleSelection: false // Single file selection
isPresented: $isDocumentPickerPresented,
allowedContentTypes: [.item],
allowsMultipleSelection: false
) { result in
switch result {
case .success(let urls):
if let selectedURL = urls.first {
// Handle security-scoped resource access
if selectedURL.startAccessingSecurityScopedResource() {
selectedFileURL = selectedURL

// Save the file path for later access
UserDefaults.standard.set(selectedURL.path, forKey: "SelectedFilePath")

selectedURL.stopAccessingSecurityScopedResource() // Stop when done
selectedURL.stopAccessingSecurityScopedResource()
} else {
print("Unable to access file at URL: \(selectedURL)")
}

// Navigate back to the first tab with delay to ensure data is loaded
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
selectedTab = 0
}
Expand All @@ -127,6 +122,63 @@ struct ContentView: View {
}
}

struct SidebarView: View {
@Binding var selectedTab: Int

var body: some View {
List {
Button(action: { selectedTab = 0 }) {
Label("Checking", systemImage: "list.bullet")
}
Button(action: { selectedTab = 1 }) {
Label("Insights", systemImage: "arrow.up.right")
}
Button(action: { selectedTab = 2 }) {
Label("Add Transaction", systemImage: "plus.circle")
}
Button(action: { selectedTab = 3 }) {
Label("Management", systemImage: "folder")
}
Button(action: { selectedTab = 4 }) {
Label("Settings", systemImage: "gearshape")
}
}
.listStyle(SidebarListStyle()) // Ensure it's displayed as a proper sidebar
}
}

struct TabContentView: View {
@Binding var selectedTab: Int
@Binding var isDocumentPickerPresented: Bool
var databaseURL: URL

var body: some View {
// Here we ensure that there's no additional NavigationStack or NavigationView
Group {
switch selectedTab {
case 0:
TransactionListView2(databaseURL: databaseURL)
.navigationBarTitle("Latest Transactions", displayMode: .inline)
case 1:
InsightsView(viewModel: InsightsViewModel(databaseURL: databaseURL))
.navigationBarTitle("Reports and Insights", displayMode: .inline)
case 2:
TransactionAddView2(databaseURL: databaseURL, selectedTab: $selectedTab)
.navigationBarTitle("Add Transaction", displayMode: .inline)
case 3:
ManagementView(databaseURL: databaseURL, isDocumentPickerPresented: $isDocumentPickerPresented)
.navigationBarTitle("Management", displayMode: .inline)
case 4:
SettingsView(databaseURL: databaseURL)
.navigationBarTitle("Settings", displayMode: .inline)
default:
EmptyView()
}
}
.navigationBarTitleDisplayMode(.inline) // Ensure that title is inline, preventing stacking
}
}

#Preview {
ContentView()
}
1 change: 0 additions & 1 deletion MMEX/Views/InsightsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ struct InsightsView: View {
.padding(.horizontal)
.padding(.top, 10) // Reduce the top padding for less space at the top
}
.navigationTitle("Reports & Insights")
.navigationBarTitleDisplayMode(.inline) // Ensure title is inline to reduce top space
}
}
Expand Down
1 change: 0 additions & 1 deletion MMEX/Views/ManagementView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ struct ManagementView: View {
defaultAccountID = storedDefaultAccount
}
}
.navigationTitle("Management")
}

func loadAccounts() {
Expand Down
1 change: 0 additions & 1 deletion MMEX/Views/Settings/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ struct SettingsView: View {
.pickerStyle(NavigationLinkPickerStyle())
}
}
.navigationTitle("Settings")
}
}

Expand Down