127 lines
5.0 KiB
Swift
127 lines
5.0 KiB
Swift
import SwiftUI
|
|
|
|
struct AccountsView: View {
|
|
@EnvironmentObject private var iapService: IAPService
|
|
@EnvironmentObject private var accountStore: AccountStore
|
|
@StateObject private var accountRepository = AccountRepository()
|
|
@State private var showingAddAccount = false
|
|
@State private var selectedAccount: Account?
|
|
@State private var showingPaywall = false
|
|
@State private var accountToDelete: Account?
|
|
@State private var showingDeleteBlocked = false
|
|
|
|
private var availableAccounts: [Account] {
|
|
accountRepository.accounts.filter { $0.safeId != nil }
|
|
}
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
AppBackground()
|
|
|
|
List {
|
|
Section {
|
|
ForEach(availableAccounts, id: \.objectID) { account in
|
|
let canDelete = accountRepository.canDeleteAccount(account)
|
|
Button {
|
|
selectedAccount = account
|
|
} label: {
|
|
HStack {
|
|
VStack(alignment: .leading) {
|
|
HStack(spacing: 4) {
|
|
Text(account.name)
|
|
.font(.headline)
|
|
if account.isDefaultAccount {
|
|
Image(systemName: "star.fill")
|
|
.font(.caption2)
|
|
.foregroundColor(.appWarning)
|
|
}
|
|
}
|
|
Text(account.currencyCode ?? AppSettings.getOrCreate(in: CoreDataStack.shared.viewContext).currency)
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
Spacer()
|
|
if accountStore.selectedAccount?.safeId == account.safeId && !accountStore.showAllAccounts {
|
|
Image(systemName: "checkmark.circle.fill")
|
|
.foregroundColor(.appPrimary)
|
|
}
|
|
}
|
|
}
|
|
.swipeActions(edge: .trailing) {
|
|
if canDelete {
|
|
Button(role: .destructive) {
|
|
accountToDelete = account
|
|
} label: {
|
|
Label("Delete", systemImage: "trash")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Accounts")
|
|
} footer: {
|
|
Text(iapService.isPremium ? "Create multiple accounts for business, family, or goals. The Default account cannot be deleted." : "Free users can create one account.")
|
|
}
|
|
}
|
|
.scrollContentBackground(.hidden)
|
|
}
|
|
.navigationTitle("Accounts")
|
|
.confirmationDialog(
|
|
"Delete Account",
|
|
isPresented: Binding(
|
|
get: { accountToDelete != nil },
|
|
set: { if !$0 { accountToDelete = nil } }
|
|
),
|
|
titleVisibility: .visible
|
|
) {
|
|
Button("Delete", role: .destructive) {
|
|
guard let accountToDelete else { return }
|
|
if accountRepository.canDeleteAccount(accountToDelete) {
|
|
accountRepository.deleteAccount(accountToDelete)
|
|
} else {
|
|
showingDeleteBlocked = true
|
|
}
|
|
self.accountToDelete = nil
|
|
}
|
|
} message: {
|
|
Text("This will remove the account and all its sources and snapshots.")
|
|
}
|
|
.alert("Cannot Delete Account", isPresented: $showingDeleteBlocked) {
|
|
Button("OK") {}
|
|
} message: {
|
|
Text("The Default account cannot be deleted. You must keep at least one account.")
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
Button {
|
|
if accountStore.canAddAccount() {
|
|
showingAddAccount = true
|
|
} else {
|
|
showingPaywall = true
|
|
}
|
|
} label: {
|
|
Image(systemName: "plus")
|
|
}
|
|
}
|
|
}
|
|
.sheet(isPresented: $showingAddAccount) {
|
|
AccountEditorView(account: nil)
|
|
}
|
|
.sheet(isPresented: $showingPaywall) {
|
|
PaywallView()
|
|
}
|
|
.sheet(item: $selectedAccount) { account in
|
|
AccountEditorView(account: account)
|
|
}
|
|
.onAppear {
|
|
accountRepository.fetchAccounts()
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
AccountsView()
|
|
.environmentObject(IAPService())
|
|
.environmentObject(AccountStore(iapService: IAPService()))
|
|
}
|