Primera build enviada

This commit is contained in:
2026-01-19 14:40:43 +01:00
parent c6be398e5a
commit b03d35194f
36 changed files with 1641 additions and 561 deletions
@@ -8,6 +8,11 @@ struct AccountsView: View {
@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 {
@@ -15,37 +20,47 @@ struct AccountsView: View {
List {
Section {
ForEach(accountRepository.accounts) { account in
ForEach(availableAccounts, id: \.objectID) { account in
let canDelete = accountRepository.canDeleteAccount(account)
Button {
selectedAccount = account
} label: {
HStack {
VStack(alignment: .leading) {
Text(account.name)
.font(.headline)
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?.id == account.id && !accountStore.showAllAccounts {
if accountStore.selectedAccount?.safeId == account.safeId && !accountStore.showAllAccounts {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.appPrimary)
}
}
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
accountToDelete = account
} label: {
Label("Delete", systemImage: "trash")
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." : "Free users can create one account.")
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)
@@ -61,14 +76,20 @@ struct AccountsView: View {
) {
Button("Delete", role: .destructive) {
guard let accountToDelete else { return }
if accountStore.selectedAccount?.id == accountToDelete.id {
accountStore.selectAllAccounts()
if accountRepository.canDeleteAccount(accountToDelete) {
accountRepository.deleteAccount(accountToDelete)
} else {
showingDeleteBlocked = true
}
accountRepository.deleteAccount(accountToDelete)
self.accountToDelete = nil
}
} message: {
Text("This will remove the account and unlink its sources.")
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) {