Commit 8b43fcbf authored by tom's avatar tom

refactor menu and usd values

parent 9bb47004
......@@ -15,13 +15,14 @@ import starOutlineIcon from 'icons/star_outline.svg';
import walletIcon from 'icons/wallet.svg';
import useFetch from 'lib/hooks/useFetch';
import useIsMobile from 'lib/hooks/useIsMobile';
import AddressTokenSelect from 'ui/address/details/AddressTokenSelect';
import AddressIcon from 'ui/shared/address/AddressIcon';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import ExternalLink from 'ui/shared/ExternalLink';
import HashStringShorten from 'ui/shared/HashStringShorten';
import Tokens from './details/Tokens';
interface Props {
addressQuery: UseQueryResult<TAddress>;
}
......@@ -97,7 +98,7 @@ const AddressDetails = ({ addressQuery }: Props) => {
>
{ tokenBalancesQuery.data.length > 0 ? (
<>
<AddressTokenSelect data={ tokenBalancesQuery.data }/>
<Tokens data={ tokenBalancesQuery.data }/>
<Button variant="outline" size="sm" ml={ 3 }>
<Icon as={ walletIcon } boxSize={ 5 }/>
</Button>
......
import { MenuItem, Flex, Text, useColorModeValue } from '@chakra-ui/react';
import { Flex, Text, useColorModeValue } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { AddressTokenBalance } from 'types/api/address';
import getCurrencyValue from 'lib/getCurrencyValue';
import TokenLogo from 'ui/shared/TokenLogo';
interface Props {
......@@ -13,8 +14,14 @@ interface Props {
const AddressTokenSelect = ({ data }: Props) => {
const tokenDecimals = Number(data.token.decimals) || 18;
const { usd } = getCurrencyValue({
value: data.value,
accuracyUsd: 2,
exchangeRate: data.token.exchange_rate,
});
return (
<MenuItem
<Flex
px={ 1 }
py="10px"
display="flex"
......@@ -22,25 +29,22 @@ const AddressTokenSelect = ({ data }: Props) => {
rowGap={ 2 }
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') }
borderBottomWidth="1px"
_last={{
borderBottomWidth: '0px',
}}
_hover={{
bgColor: useColorModeValue('blue.50', 'gray.800'),
}}
fontSize="sm"
isFocusable={ false }
cursor="pointer"
>
<Flex alignItems="center" w="100%">
<TokenLogo hash={ data.token.address } name={ data.token.name } boxSize={ 6 }/>
<Text fontWeight={ 700 } ml={ 2 }>{ data.token.name }</Text>
<Text fontWeight={ 700 } ml="auto">$23 463.73</Text>
{ usd && <Text fontWeight={ 700 } ml="auto">${ usd }</Text> }
</Flex>
<Flex alignItems="center" justifyContent="space-between" w="100%">
<Text >{ BigNumber(data.value).dividedBy(10 ** tokenDecimals).dp(2).toFormat() } { data.token.symbol }</Text>
<Text >@1.001</Text>
{ data.token.exchange_rate && <Text >@{ data.token.exchange_rate }</Text> }
</Flex>
</MenuItem>
</Flex>
);
};
......
import {
Icon, Text, Button, Menu, MenuButton, MenuGroup, MenuList,
Input, forwardRef, InputGroup, InputLeftElement, useColorModeValue,
Icon, Text,
Input, InputGroup, InputLeftElement, useColorModeValue,
Popover, PopoverTrigger, PopoverContent, PopoverBody, Box,
useDisclosure,
} from '@chakra-ui/react';
import _groupBy from 'lodash/groupBy';
import type { ChangeEvent } from 'react';
......@@ -8,28 +10,10 @@ import React from 'react';
import type { AddressTokenBalance } from 'types/api/address';
import arrowIcon from 'icons/arrows/east-mini.svg';
import searchIcon from 'icons/search.svg';
import tokensIcon from 'icons/tokens.svg';
import AddressTokenSelectErc20 from './AddressTokenSelectErc20';
const Trigger = forwardRef((props, ref) => {
return (
<Button
{ ...props }
ref={ ref }
size="sm"
variant="outline"
colorScheme="gray"
>
<Icon as={ tokensIcon } boxSize={ 5 } mr={ 2 }/>
<Text fontWeight={ 600 }>2</Text>
<Text whiteSpace="pre" variant="secondary" fontWeight={ 400 }> ($23 463.73 USD)</Text>
<Icon as={ arrowIcon } transform={ props.isActive ? 'rotate(90deg)' : 'rotate(-90deg)' } transitionDuration="normal" boxSize={ 5 } ml={ 3 }/>
</Button>
);
});
import TokenItemErc20 from './TokenItemErc20';
import TokensButton from './TokensButton';
interface Props {
data: Array<AddressTokenBalance>;
......@@ -37,6 +21,7 @@ interface Props {
const AddressTokenSelect = ({ data }: Props) => {
const [ searchTerm, setSearchTerm ] = React.useState('');
const { isOpen, onToggle, onClose } = useDisclosure();
const handleInputChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.target.value);
......@@ -54,33 +39,35 @@ const AddressTokenSelect = ({ data }: Props) => {
const groupedData = _groupBy(filteredData, 'token.type');
return (
<Menu>
{ ({ isOpen }) => (
<>
<MenuButton isActive={ isOpen } as={ Trigger }/>
<MenuList px={ 4 } py={ 6 } w="355px" bgColor={ bgColor } boxShadow="2xl">
<InputGroup size="xs" mb={ 5 }>
<InputLeftElement >
<Icon as={ searchIcon } boxSize={ 4 } color={ searchIconColor }/>
</InputLeftElement>
<Input
paddingInlineStart="38px"
placeholder="Search by token name"
ml="1px"
onChange={ handleInputChange }
borderColor={ inputBorderColor }
onKeyDown={ handleKeyDown }
/>
</InputGroup>
{ groupedData['ERC-20'] && (
<MenuGroup title={ `ERC-20 tokens (${ groupedData['ERC-20'].length })` } mb={ 3 } mt={ 0 } mx={ 0 } color="gray.500">
{ groupedData['ERC-20'].map((data) => <AddressTokenSelectErc20 key={ data.token.address } data={ data }/>) }
</MenuGroup>
) }
</MenuList>
</>
) }
</Menu>
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy>
<PopoverTrigger>
<TokensButton isOpen={ isOpen } onClick={ onToggle } data={ data }/>
</PopoverTrigger>
<PopoverContent w="355px" maxH="450px" overflowY="scroll">
<PopoverBody px={ 4 } py={ 6 } bgColor={ bgColor } boxShadow="2xl" >
<InputGroup size="xs" mb={ 5 }>
<InputLeftElement >
<Icon as={ searchIcon } boxSize={ 4 } color={ searchIconColor }/>
</InputLeftElement>
<Input
paddingInlineStart="38px"
placeholder="Search by token name"
ml="1px"
onChange={ handleInputChange }
borderColor={ inputBorderColor }
onKeyDown={ handleKeyDown }
/>
</InputGroup>
{ groupedData['ERC-20'] && (
<Box color="gray.500">
<Text mb={ 3 } color="gray.500" fontWeight={ 600 } fontSize="sm">ERC-20 tokens ({ groupedData['ERC-20'].length })</Text>
{ groupedData['ERC-20'].map((data) => <TokenItemErc20 key={ data.token.address } data={ data }/>) }
</Box>
) }
{ filteredData.length === 0 && searchTerm && <Text fontSize="sm">Could not find any matches.</Text> }
</PopoverBody>
</PopoverContent>
</Popover>
);
};
......
import { Button, Icon, Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { AddressTokenBalance } from 'types/api/address';
import arrowIcon from 'icons/arrows/east-mini.svg';
import tokensIcon from 'icons/tokens.svg';
import { ZERO } from 'lib/consts';
interface Props {
isOpen: boolean;
onClick: () => void;
data: Array<AddressTokenBalance>;
}
const TokensButton = ({ isOpen, onClick, data }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
const usdBn = data.reduce((result, item) => {
if (!item.token.exchange_rate) {
return result;
}
const decimals = Number(item.token.decimals || '18');
return BigNumber(item.value).div(BigNumber(10 ** decimals)).multipliedBy(BigNumber(item.token.exchange_rate));
}, ZERO);
return (
<Button
ref={ ref }
size="sm"
variant="outline"
colorScheme="gray"
onClick={ onClick }
>
<Icon as={ tokensIcon } boxSize={ 4 } mr={ 2 }/>
<Text fontWeight={ 600 }>{ data.length }</Text>
<Text whiteSpace="pre" variant="secondary" fontWeight={ 400 }> (${ usdBn.toFixed(2) })</Text>
<Icon as={ arrowIcon } transform={ isOpen ? 'rotate(90deg)' : 'rotate(-90deg)' } transitionDuration="normal" boxSize={ 5 } ml={ 3 }/>
</Button>
);
};
export default React.forwardRef(TokensButton);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment