import { useEffect, useState, type FormEvent } from 'react' import { createTransaction, getAccount, type Account, type TxnType, } from '../db' import { parseCents } from '../format' import { back, navigate } from '../router' import { BackButton, Header, Screen } from '../components/Screen' export function AddTransactionPage(props: { accountId: string onCreated: () => void }) { const [account, setAccount] = useState(undefined) const [type, setType] = useState('credit') const [amount, setAmount] = useState('') const [note, setNote] = useState('') const [err, setErr] = useState(null) const [busy, setBusy] = useState(false) useEffect(() => { let alive = true getAccount(props.accountId).then((a) => { if (alive) setAccount(a ?? null) }) return () => { alive = false } }, [props.accountId]) async function onSubmit(e: FormEvent) { e.preventDefault() if (busy) return const cents = parseCents(amount) if (cents === null) { setErr('Enter a valid amount (e.g. 12.34)') return } if (cents <= 0) { setErr('Amount must be greater than zero') return } setBusy(true) try { await createTransaction({ accountId: props.accountId, type, amount: cents, note, }) props.onCreated() back(`/accounts/${props.accountId}`) } catch (e) { setErr(e instanceof Error ? e.message : 'Could not save transaction') } finally { setBusy(false) } } if (account === null) { return ( back('/')} />} /> } >
Account not found
) } const submitDisabled = busy || amount.trim() === '' return ( back(`/accounts/${props.accountId}`)} /> } /> } footer={ } >
{ const v = e.target.value if (v === '' || /^\d*(\.\d{0,2})?$/.test(v)) { setAmount(v) if (err) setErr(null) } }} autoFocus />
setNote(e.target.value)} />
) }