import { FC, useCallback, useState } from "react"; import Container from "../Container"; import Flex from "../Flex"; import Input from "../Input"; import Select from "../Select"; import Text from "../Text"; import { SelectOption, TransactionState, transactionsData, TxFields, getTxFields, } from "../../state/transactions"; import { useSnapshot } from "valtio"; import state from "../../state"; import { streamState } from "../DebugStream"; import { Button } from ".."; interface UIProps { setState: ( pTx?: Partial | undefined ) => TransactionState | undefined; state: TransactionState; estimateFee?: (...arg: any) => Promise; } export const TxUI: FC = ({ state: txState, setState, estimateFee, }) => { const { accounts } = useSnapshot(state); const { selectedAccount, selectedDestAccount, selectedTransaction, txFields, } = txState; const transactionsOptions = transactionsData.map(tx => ({ value: tx.TransactionType, label: tx.TransactionType, })); const accountOptions: SelectOption[] = accounts.map(acc => ({ label: acc.name, value: acc.address, })); const destAccountOptions: SelectOption[] = accounts .map(acc => ({ label: acc.name, value: acc.address, })) .filter(acc => acc.value !== selectedAccount?.value); const [feeLoading, setFeeLoading] = useState(false); const resetOptions = useCallback( (tt: string) => { const fields = getTxFields(tt); if (!fields.Destination) setState({ selectedDestAccount: null }); return setState({ txFields: fields }); }, [setState] ); const handleSetAccount = (acc: SelectOption) => { setState({ selectedAccount: acc }); streamState.selectedAccount = acc; }; const handleSetField = useCallback( (field: keyof TxFields, value: string, opFields?: TxFields) => { const fields = opFields || txFields; const obj = fields[field]; setState({ txFields: { ...fields, [field]: typeof obj === "object" ? { ...obj, $value: value } : value, }, }); }, [setState, txFields] ); const handleEstimateFee = useCallback( async (state?: TransactionState, silent?: boolean) => { setFeeLoading(true); const fee = await estimateFee?.(state, { silent }); if (fee) handleSetField("Fee", fee, state?.txFields); setFeeLoading(false); }, [estimateFee, handleSetField] ); const handleChangeTxType = (tt: SelectOption) => { setState({ selectedTransaction: tt }); const newState = resetOptions(tt.value); handleEstimateFee(newState, true); }; const specialFields = ["TransactionType", "Account", "Destination"]; const otherFields = Object.keys(txFields).filter( k => !specialFields.includes(k) ) as [keyof TxFields]; return ( Transaction type:{" "} handleSetAccount(acc)} // TODO make react-select have correct types for acc /> {txFields.Destination !== undefined && ( Destination account:{" "} { handleSetField(field, e.target.value); }} css={{ width: "70%", flex: "inherit" }} /> {isFee && ( )} ); })} ); };