Primera build enviada
This commit is contained in:
@@ -10,19 +10,28 @@ struct AddSourceView: View {
|
||||
@State private var initialValue = ""
|
||||
@State private var showingCategoryPicker = false
|
||||
@State private var selectedAccountId: UUID?
|
||||
@State private var duplicateError: String?
|
||||
|
||||
@StateObject private var categoryRepository = CategoryRepository()
|
||||
@StateObject private var sourceRepository = InvestmentSourceRepository()
|
||||
|
||||
private var availableAccounts: [Account] {
|
||||
accountStore.accounts.filter { $0.safeId != nil }
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
if accountStore.accounts.count > 1 {
|
||||
if availableAccounts.count > 1 {
|
||||
Section {
|
||||
Picker("Account", selection: $selectedAccountId) {
|
||||
ForEach(accountStore.accounts) { account in
|
||||
Text(account.name).tag(Optional(account.id))
|
||||
ForEach(availableAccounts, id: \.objectID) { account in
|
||||
Text(account.name).tag(Optional(account.safeId))
|
||||
}
|
||||
}
|
||||
.onChange(of: selectedAccountId) { _, _ in
|
||||
validateSourceName(name)
|
||||
}
|
||||
} header: {
|
||||
Text("Account")
|
||||
}
|
||||
@@ -32,6 +41,9 @@ struct AddSourceView: View {
|
||||
Section {
|
||||
TextField("Source Name", text: $name)
|
||||
.textContentType(.organizationName)
|
||||
.onChange(of: name) { _, newValue in
|
||||
validateSourceName(newValue)
|
||||
}
|
||||
|
||||
Button {
|
||||
showingCategoryPicker = true
|
||||
@@ -61,6 +73,11 @@ struct AddSourceView: View {
|
||||
}
|
||||
} header: {
|
||||
Text("Source Information")
|
||||
} footer: {
|
||||
if let error = duplicateError {
|
||||
Text(error)
|
||||
.foregroundColor(.negativeRed)
|
||||
}
|
||||
}
|
||||
|
||||
// Initial Value (Optional)
|
||||
@@ -107,7 +124,7 @@ struct AddSourceView: View {
|
||||
selectedCategory = categoryRepository.categories.first
|
||||
}
|
||||
if selectedAccountId == nil {
|
||||
selectedAccountId = accountStore.selectedAccount?.id ?? accountStore.accounts.first?.id
|
||||
selectedAccountId = accountStore.selectedAccount?.safeId ?? availableAccounts.first?.safeId
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +133,21 @@ struct AddSourceView: View {
|
||||
// MARK: - Validation
|
||||
|
||||
private var isValid: Bool {
|
||||
!name.trimmingCharacters(in: .whitespaces).isEmpty && selectedCategory != nil
|
||||
!name.trimmingCharacters(in: .whitespaces).isEmpty && selectedCategory != nil && duplicateError == nil
|
||||
}
|
||||
|
||||
private func validateSourceName(_ newName: String) {
|
||||
let trimmed = newName.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmed.isEmpty else {
|
||||
duplicateError = nil
|
||||
return
|
||||
}
|
||||
|
||||
if sourceRepository.sourceExists(name: trimmed, in: selectedAccount) {
|
||||
duplicateError = "A source with this name already exists."
|
||||
} else {
|
||||
duplicateError = nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Save
|
||||
@@ -177,7 +208,7 @@ struct AddSourceView: View {
|
||||
|
||||
private var selectedAccount: Account? {
|
||||
guard let id = selectedAccountId else { return nil }
|
||||
return accountStore.accounts.first { $0.id == id }
|
||||
return availableAccounts.first { $0.safeId == id }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,17 +279,17 @@ struct EditSourceView: View {
|
||||
self.source = source
|
||||
_name = State(initialValue: source.name)
|
||||
_selectedCategory = State(initialValue: source.category)
|
||||
_selectedAccountId = State(initialValue: source.account?.id)
|
||||
_selectedAccountId = State(initialValue: source.account?.safeId)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
if accountStore.accounts.count > 1 {
|
||||
if availableAccounts.count > 1 {
|
||||
Section {
|
||||
Picker("Account", selection: $selectedAccountId) {
|
||||
ForEach(accountStore.accounts) { account in
|
||||
Text(account.name).tag(Optional(account.id))
|
||||
ForEach(availableAccounts, id: \.objectID) { account in
|
||||
Text(account.name).tag(Optional(account.safeId))
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
@@ -320,6 +351,10 @@ struct EditSourceView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var availableAccounts: [Account] {
|
||||
accountStore.accounts.filter { $0.safeId != nil }
|
||||
}
|
||||
|
||||
private var isValid: Bool {
|
||||
!name.trimmingCharacters(in: .whitespaces).isEmpty && selectedCategory != nil
|
||||
}
|
||||
@@ -343,7 +378,7 @@ struct EditSourceView: View {
|
||||
|
||||
private var selectedAccount: Account? {
|
||||
guard let id = selectedAccountId else { return nil }
|
||||
return accountStore.accounts.first { $0.id == id }
|
||||
return availableAccounts.first { $0.safeId == id }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user