import { useMemo, useState } from 'react'; import { useAccountSelection } from '../../home/hooks/useAccounts'; /** * The half of a transfer form that is the same whichever way the money is * addressed: which account it leaves, how much, and the note against it. * * The account list is read from `GET /accounts` on every mount — never from * Redux, and never carried in from the previous screen. * * There is no balance check here, and that is not an omission. No endpoint in * the CBS API returns a balance, so the app has nothing to compare an amount * against; inventing a limit would be worse than having none, because a * customer refused by the app has no way to find out they were refused * wrongly. The bank rejects an overdrawn transfer on submission, and that * refusal is the authoritative one. */ export const useTransferForm = () => { const { accounts, selectedAccountNumber, setSelectedAccountNumber, selectedAccount, isLoading, refetch } = useAccountSelection(); const [amount, setAmount] = useState(''); const [remarks, setRemarks] = useState(''); /** Grouping separators are allowed in, but never reach the parsed value. */ const parsedAmount = useMemo(() => Number.parseFloat(amount.replace(/,/g, '')), [amount]); const amountError = useMemo(() => { if (amount.length === 0) { return undefined; } if (Number.isNaN(parsedAmount) || parsedAmount <= 0) { return 'Enter a valid amount'; } return undefined; }, [amount, parsedAmount]); const amountValid = !amountError && parsedAmount > 0; const handleAmountChange = (value: string) => { // One decimal point, digits either side, at most two paise. Filtering on // the way in beats validating after the fact: the field cannot hold // something the parser would then have to reject. const cleaned = value.replace(/[^0-9.]/g, ''); const [rupees = '', ...rest] = cleaned.split('.'); const paise = rest.join('').slice(0, 2); setAmount(rest.length ? `${rupees}.${paise}` : rupees); }; return { accounts, selectedAccount, sourceAccountNumber: selectedAccountNumber, setSourceAccountNumber: setSelectedAccountNumber, accountsLoading: isLoading, refetchAccounts: refetch, amount, handleAmountChange, parsedAmount, amountError, amountValid, remarks, setRemarks, }; };