Update CBS Mobile App codebase
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
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,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user