import SwiftUI struct AddTransactionView: View { @Environment(\.dismiss) private var dismiss let onSave: (TransactionType, Date, Decimal?, Decimal?, Decimal?, String?) -> Void @State private var type: TransactionType = .buy @State private var date = Date() @State private var shares = "" @State private var price = "" @State private var amount = "" @State private var notes = "" var body: some View { NavigationStack { Form { Section { Picker("Type", selection: $type) { ForEach(TransactionType.allCases) { transactionType in Text(transactionType.displayName).tag(transactionType) } } DatePicker("Date", selection: $date, displayedComponents: .date) } header: { Text("Transaction") } Section { TextField("Shares", text: $shares) .keyboardType(.decimalPad) TextField("Price per share", text: $price) .keyboardType(.decimalPad) TextField("Total amount", text: $amount) .keyboardType(.decimalPad) } header: { Text("Amounts") } footer: { Text("Enter shares and price or just a total amount.") } Section { TextField("Notes", text: $notes, axis: .vertical) .lineLimit(2...4) } header: { Text("Notes (Optional)") } } .navigationTitle("Add Transaction") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Cancel") { dismiss() } } ToolbarItem(placement: .navigationBarTrailing) { Button("Save") { save() } .disabled(!isValid) } } } .presentationDetents([.medium, .large]) } private var isValid: Bool { parseDecimal(shares) != nil || parseDecimal(amount) != nil } private func save() { onSave( type, date, parseDecimal(shares), parseDecimal(price), parseDecimal(amount), notes.isEmpty ? nil : notes ) dismiss() } private func parseDecimal(_ value: String) -> Decimal? { let cleaned = value .replacingOccurrences(of: ",", with: ".") .trimmingCharacters(in: .whitespaces) guard !cleaned.isEmpty else { return nil } return Decimal(string: cleaned) } } #Preview { AddTransactionView { _, _, _, _, _, _ in } }