import { formatEther } from '@ethersproject/units' import { TransactionStatus, useEthers, transactionErrored } from '@usedapp/core' import React, { ReactElement, useEffect, useState } from 'react' import styled from 'styled-components' import { TextBold } from '../../typography/Text' import { ContentBlock } from '../base/base' import { Button } from '../base/Button' import { BorderRad, Colors } from '../../global/styles' import { BigNumber } from 'ethers' import { SpinnerIcon, CheckIcon, ExclamationIcon } from './Icons' import { AnimatePresence, motion } from 'framer-motion' const formatter = new Intl.NumberFormat('en-us', { minimumFractionDigits: 4, maximumFractionDigits: 4, }) const formatBalance = (balance: BigNumber | undefined) => formatter.format(parseFloat(formatEther(balance ?? BigNumber.from('0')))) interface StatusBlockProps { color: string text: string icon: ReactElement } const StatusBlock = ({ color, text, icon }: StatusBlockProps) => ( {icon}
{text}
) interface StatusAnimationProps { transaction: TransactionStatus } export const StatusAnimation = ({ transaction }: StatusAnimationProps) => { const [showTransactionStatus, setShowTransactionStatus] = useState(false) const [timer, setTimer] = useState( setTimeout(() => { void 0 }, 1) ) useEffect(() => { setShowTransactionStatus(true) clearTimeout(timer) if (transaction.status !== 'Mining' && transaction.status !== 'CollectingSignaturePool') setTimer(setTimeout(() => setShowTransactionStatus(false), 5000)) }, [transaction]) return ( {showTransactionStatus && transactionErrored(transaction) && ( } key={transaction?.chainId + transaction.status} /> )} {showTransactionStatus && transaction.status === 'Mining' && ( } key={transaction?.chainId + transaction.status} /> )} {showTransactionStatus && transaction.status === 'CollectingSignaturePool' && ( } key={transaction?.chainId + transaction.status} /> )} {showTransactionStatus && transaction.status === 'Success' && ( } key={transaction?.chainId + transaction.status} /> )} ) } interface InputComponentProps { send: (value: string) => void ticker: string transaction: TransactionStatus } const InputComponent = ({ ticker, transaction, send }: InputComponentProps) => { const { account } = useEthers() const [value, setValue] = useState('0') const [disabled, setDisabled] = useState(false) const onClick = () => { if (Number(value) > 0) { setDisabled(true) send(value) } } useEffect(() => { if (transaction.status != 'Mining') { setDisabled(false) setValue('0') } }, [transaction]) return ( setValue(e.currentTarget.value)} disabled={disabled} /> {ticker} Send ) } interface TransactionFormProps { balance: BigNumber | undefined send: (value: string) => void title: string ticker: string transaction: TransactionStatus } export const TransactionForm = ({ balance, send, title, ticker, transaction }: TransactionFormProps) => ( {title} Your {ticker} balance: {formatBalance(balance)} ) const SmallButton = styled(Button)` display: flex; justify-content: center; min-width: 95px; height: unset; padding: 8px 24px; &:disabled { color: ${Colors.Gray['600']}; cursor: unset; } &:disabled:hover, &:disabled:focus { background-color: unset; color: unset; } ` const Input = styled.input` height: 100%; width: 120px; padding: 0 0 0 24px; border: 0; border-radius: ${BorderRad.m}; -moz-appearance: textfield; &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } &:focus { outline: transparent auto 1px; } &:focus-visible { box-shadow: inset 0 0 0 2px ${Colors.Black['900']}; } ` const CellTitle = styled(TextBold)` font-size: 18px; ` const InputRow = styled.div` display: flex; margin: 0 auto; color: ${Colors.Gray['600']}; align-items: center; border: ${Colors.Gray['300']} 1px solid; border-radius: ${BorderRad.m}; overflow: hidden; ` const FormTicker = styled.div` padding: 0 16px; ` const LabelRow = styled.div` display: flex; justify-content: center; margin: 32px 0 24px 0; ` const Label = styled.label` font-weight: 700; ` const TitleRow = styled.div` display: flex; align-items: baseline; justify-content: space-between; border-bottom: ${Colors.Gray['300']} 1px solid; padding: 16px; ` const BalanceWrapper = styled.div` color: ${Colors.Gray['600']}; font-size: 14px; ` const SmallContentBlock = styled(ContentBlock)` padding: 0; ` const IconContainer = styled.div` margin-right: 15px; height: 40px; width: 40px; float: left; ` const InformationRow = styled(motion.div)` height: 60px; font-size: 14px; display: flex; align-items: center; justify-content: center; text-align: center; overflow: auto; ` const AnimationWrapper = styled.div` height: 80px; display: flex; align-items: center; justify-content: center; overflow: auto; margin: 10px; `