Commit 3ac5beb6 authored by isstuev's avatar isstuev

fixes

parent 9fa8a76b
/* eslint-disable max-len */ /* eslint-disable max-len */
export const tx = { export const tx = {
hash: '0x1ea365d2144796f793883534aa51bf20d23292b19478994eede23dfc599e7c34', hash: '0x1ea365d2144796f793883534aa51bf20d23292b19478994eede23dfc599e7c34',
status: 'success', status: 'success' as TxStatus,
block_num: 15006918, block_num: 15006918,
confirmation_num: 283, confirmation_num: 283,
confirmation_duration: 30, confirmation_duration: 30,
...@@ -9,10 +9,12 @@ export const tx = { ...@@ -9,10 +9,12 @@ export const tx = {
address_from: { address_from: {
hash: '0x97Aa2EfcF35c0f4c9AaDDCa8c2330fa7A9533830', hash: '0x97Aa2EfcF35c0f4c9AaDDCa8c2330fa7A9533830',
type: 'Address', type: 'Address',
alias: '',
}, },
address_to: { address_to: {
hash: '0x35317007D203b8a86CA727ad44E473E40450E378', hash: '0x35317007D203b8a86CA727ad44E473E40450E378',
type: 'Contract', type: 'Contract',
alias: '',
}, },
amount: { amount: {
value: 0.03, value: 0.03,
...@@ -45,4 +47,9 @@ export const tx = { ...@@ -45,4 +47,9 @@ export const tx = {
{ from: '0x12E80C27BfFBB76b4A8d26FF2bfd3C9f310FFA01', to: '0xF7A558692dFB5F456e291791da7FAE8Dd046574e', token: 'USDT', amount: 192.7, usd: 194.05 }, { from: '0x12E80C27BfFBB76b4A8d26FF2bfd3C9f310FFA01', to: '0xF7A558692dFB5F456e291791da7FAE8Dd046574e', token: 'USDT', amount: 192.7, usd: 194.05 },
{ from: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45', to: '0x12E80C27BfFBB76b4A8d26FF2bfd3C9f310FFA01', token: 'TOKE', amount: 76.1851851851846, usd: 194.05 }, { from: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45', to: '0x12E80C27BfFBB76b4A8d26FF2bfd3C9f310FFA01', token: 'TOKE', amount: 76.1851851851846, usd: 194.05 },
], ],
txType: 'transaction' as TxType,
}; };
export type TxType = 'contract-call' | 'transaction' | 'token-transfer' | 'internal-tx' | 'multicall';
export type TxStatus = 'success' | 'failed' | 'pending';
import { tx } from './tx'; import { tx } from './tx';
import type { TxType, TxStatus } from './tx';
export const txs = [ export const txs = [
{ {
...tx, ...tx,
method: 'Withdraw', method: 'Withdraw',
txType: 'transaction', txType: 'transaction' as TxType,
errorText: '',
}, },
{ {
...tx, ...tx,
status: 'failed', status: 'failed' as TxStatus,
errorText: 'Error: (Awaiting internal transactions for reason)', errorText: 'Error: (Awaiting internal transactions for reason)',
txType: 'contract-call', txType: 'contract-call' as TxType,
method: 'CommitHash CommitHash CommitHash CommitHash', method: 'CommitHash CommitHash CommitHash CommitHash',
amount: { amount: {
value: 0.04, value: 0.04,
...@@ -23,8 +25,8 @@ export const txs = [ ...@@ -23,8 +25,8 @@ export const txs = [
}, },
{ {
...tx, ...tx,
status: 'pending', status: 'pending' as TxStatus,
txType: 'token-transfer', txType: 'token-transfer' as TxType,
method: 'Multicall', method: 'Multicall',
address_from: { address_from: {
hash: '0x97Aa2EfcF35c0f4c9AaDDCa8c2330fa7A9533830', hash: '0x97Aa2EfcF35c0f4c9AaDDCa8c2330fa7A9533830',
...@@ -39,5 +41,6 @@ export const txs = [ ...@@ -39,5 +41,6 @@ export const txs = [
value: 0.002495904453623692, value: 0.002495904453623692,
value_usd: 2.84, value_usd: 2.84,
}, },
errorText: '',
}, },
]; ];
...@@ -19,7 +19,7 @@ const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => { ...@@ -19,7 +19,7 @@ const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => {
return ( return (
<> <>
<Head><title>{ title }</title></Head> <Head><title>{ title }</title></Head>
<Transactions tab="pending"/> <Transactions tab="txs_pending"/>
</> </>
); );
}; };
......
...@@ -19,7 +19,7 @@ const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => { ...@@ -19,7 +19,7 @@ const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => {
return ( return (
<> <>
<Head><title>{ title }</title></Head> <Head><title>{ title }</title></Head>
<Transactions tab="validated"/> <Transactions tab="txs_validated"/>
</> </>
); );
}; };
......
...@@ -35,7 +35,6 @@ const baseStyleContainer = defineStyle({ ...@@ -35,7 +35,6 @@ const baseStyleContainer = defineStyle({
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
borderRadius: 'sm', borderRadius: 'sm',
lineHeight: '20px',
...transitionProps, ...transitionProps,
}); });
......
export type Sort = 'val-desc' | 'val-asc' | 'fee-desc' | 'fee-asc' | undefined;
import { Box } from '@chakra-ui/react'; import React from 'react'; import { Box } from '@chakra-ui/react';
import React from 'react';
import type { RoutedTab } from 'ui/shared/RoutedTabs/types'; import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
......
...@@ -33,7 +33,7 @@ const TransactionPageContent = ({ tab }: Props) => { ...@@ -33,7 +33,7 @@ const TransactionPageContent = ({ tab }: Props) => {
return ( return (
<Page> <Page>
{ /* TODO should be shown only when navigating from txs list */ } { /* TODO should be shown only when navigating from txs list */ }
<Link mb={ 6 } display="inline-flex" href={ link('txs') }> <Link mb={ 6 } display="inline-flex" href={ link('txs_validated') }>
<Icon as={ eastArrowIcon } boxSize={ 6 } mr={ 2 } transform="rotate(180deg)"/> <Icon as={ eastArrowIcon } boxSize={ 6 } mr={ 2 } transform="rotate(180deg)"/>
Transactions Transactions
</Link> </Link>
......
import { import {
Box, Box,
Tab,
Tabs,
TabList,
TabPanel,
TabPanels,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React, { useCallback, useState } from 'react'; import React from 'react';
import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import useLink from 'lib/link/useLink';
import Page from 'ui/shared/Page'; import Page from 'ui/shared/Page';
import PageHeader from 'ui/shared/PageHeader'; import PageHeader from 'ui/shared/PageHeader';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
import TxsPending from 'ui/txs/TxsPending'; import TxsPending from 'ui/txs/TxsPending';
import TxsValidated from 'ui/txs/TxsValidated'; import TxsValidated from 'ui/txs/TxsValidated';
const TABS = [ 'validated', 'pending' ] as const; const TABS: Array<RoutedTab> = [
{ routeName: 'txs_validated', title: 'Validated', component: <TxsValidated/> },
type TabName = typeof TABS[number]; { routeName: 'txs_pending', title: 'Pending', component: <TxsPending/> },
];
type Props = { type Props = {
tab: TabName; tab: RoutedTab['routeName'];
} }
const Transactions = ({ tab }: Props) => { const Transactions = ({ tab }: Props) => {
const [ , setActiveTab ] = useState<TabName>(tab);
const link = useLink();
const onChangeTab = useCallback((index: number) => {
setActiveTab(TABS[index]);
const newUrl = link(TABS[index] === 'validated' ? 'txs_validated' : 'txs_pending');
history.replaceState(history.state, '', newUrl);
}, [ link ]);
return ( return (
<Page> <Page>
<Box h="100%"> <Box h="100%">
<PageHeader text="Transactions"/> <PageHeader text="Transactions"/>
<Tabs variant="soft-rounded" colorScheme="blue" isLazy onChange={ onChangeTab } defaultIndex={ TABS.indexOf(tab) }> <RoutedTabs tabs={ TABS } defaultActiveTab={ tab }/>
<TabList marginBottom={{ base: 6, lg: 8 }}>
<Tab>Validated</Tab>
<Tab>Pending</Tab>
</TabList>
<TabPanels>
<TabPanel padding={ 0 }>
<TxsValidated/>
</TabPanel>
<TabPanel padding={ 0 }>
<TxsPending/>
</TabPanel>
</TabPanels>
</Tabs>
</Box> </Box>
</Page> </Page>
); );
......
// DEPRECATED
// migrate to separate components
// ui/shared/FilterButton.tsx + custom filter
// ui/shared/FilterInput.tsx
import { Flex, Icon, Button, Circle, InputGroup, InputLeftElement, Input, useColorModeValue } from '@chakra-ui/react';
import type { ChangeEvent } from 'react';
import React from 'react';
import upDownArrow from 'icons/arrows/up-down.svg';
import filterIcon from 'icons/filter.svg';
import searchIcon from 'icons/search.svg';
const FilterIcon = <Icon as={ filterIcon } boxSize={ 5 }/>;
type Props = {
isMobile?: boolean;
}
const Filters = ({ isMobile }: Props) => {
const [ isFilterActive, setIsFilterActive ] = React.useState(false);
const [ value, setValue ] = React.useState('');
const [ isSortActive, setIsSortActive ] = React.useState(false);
const handleClick = React.useCallback(() => {
setIsFilterActive(flag => !flag);
}, []);
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
}, []);
const handleSort = React.useCallback(() => {
setIsSortActive(flag => !flag);
}, []);
const badgeColor = useColorModeValue('white', 'black');
const badgeBgColor = useColorModeValue('blue.700', 'gray.50');
const searchIconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
const inputBorderColor = useColorModeValue('blackAlpha.100', 'whiteAlpha.200');
return (
<Flex>
<Button
leftIcon={ isMobile ? undefined : FilterIcon }
rightIcon={ isFilterActive ? <Circle bg={ badgeBgColor } size={ 5 } color={ badgeColor }>2</Circle> : undefined }
size="sm"
variant="outline"
colorScheme="gray-dark"
onClick={ handleClick }
isActive={ isFilterActive }
px={ 1.5 }
>
{ isMobile ? FilterIcon : 'Filter' }
</Button>
{ isMobile && (
<IconButton
icon={ <Icon as={ upDownArrow } boxSize={ 5 }/> }
aria-label="sort"
size="sm"
variant="outline"
colorScheme="gray-dark"
ml={ 2 }
minWidth="36px"
onClick={ handleSort }
isActive={ isSortActive }
/>
) }
<InputGroup size="xs" ml={ isMobile ? 2 : 3 } maxW="360px">
<InputLeftElement ml={ 1 }>
<Icon as={ searchIcon } boxSize={ 5 } color={ searchIconColor }/>
</InputLeftElement>
<Input
paddingInlineStart="38px"
placeholder="Search by addresses, hash, method..."
ml="1px"
borderWidth="2px"
textOverflow="ellipsis"
onChange={ handleChange }
borderColor={ inputBorderColor }
value={ value }
size="xs"
/>
</InputGroup>
</Flex>
);
};
export default Filters;
import { Button, Flex, Input, Icon, IconButton } from '@chakra-ui/react';
import React from 'react';
import arrowIcon from 'icons/arrows/east-mini.svg';
type Props = {
currentPage: number;
maxPage?: number;
isMobile?: boolean;
}
const MAX_PAGE_DEFAULT = 50;
const Pagination = ({ currentPage, maxPage, isMobile }: Props) => {
const pageNumber = (
<Flex alignItems="center">
<Button
variant="outline"
colorScheme="gray"
size="sm"
isActive
borderWidth="1px"
fontWeight={ 400 }
mr={ 3 }
h={ 8 }
>
{ currentPage }
</Button>
of
<Button
variant="outline"
colorScheme="gray"
size="sm"
width={ 8 }
borderWidth="1px"
fontWeight={ 400 }
ml={ 3 }
>
{ maxPage || MAX_PAGE_DEFAULT }
</Button>
</Flex>
);
if (isMobile) {
return (
<Flex
fontSize="sm"
width="100%"
justifyContent="space-between"
alignItems="center"
>
<IconButton
variant="outline"
size="sm"
aria-label="Next page"
w="36px"
icon={ <Icon as={ arrowIcon } w={ 5 } h={ 5 }/> }
/>
{ pageNumber }
<IconButton
variant="outline"
size="sm"
aria-label="Next page"
w="36px"
icon={ <Icon as={ arrowIcon } w={ 5 } h={ 5 } transform="rotate(180deg)"/> }
/>
</Flex>
);
}
return (
<Flex
fontSize="sm"
>
<Flex alignItems="center" justifyContent="space-between">
<Button
variant="outline"
size="sm"
aria-label="Next page"
leftIcon={ <Icon as={ arrowIcon } w={ 5 } h={ 5 }/> }
mr={ 8 }
pl={ 1 }
>
Previous
</Button>
{ pageNumber }
<Button
variant="outline"
size="sm"
aria-label="Next page"
rightIcon={ <Icon as={ arrowIcon } w={ 5 } h={ 5 } transform="rotate(180deg)"/> }
ml={ 8 }
pr={ 1 }
>
Next
</Button>
</Flex>
<Flex alignItems="center" width="132px" ml={ 16 }>
Go to <Input w="84px" size="xs" ml={ 2 }/>
</Flex>
</Flex>
);
};
export default Pagination;
import { Icon, IconButton } from '@chakra-ui/react';
import React from 'react';
import upDownArrow from 'icons/arrows/up-down.svg';
type Props = {
handleSort: () => void;
isSortActive: boolean;
}
const SortButton = ({ handleSort, isSortActive }: Props) => {
return (
<IconButton
icon={ <Icon as={ upDownArrow } boxSize={ 5 }/> }
aria-label="sort"
size="sm"
variant="outline"
colorScheme="gray-dark"
ml={ 2 }
minWidth="36px"
onClick={ handleSort }
isActive={ isSortActive }
/>
);
};
export default SortButton;
...@@ -16,8 +16,8 @@ import TxInternalsTable from 'ui/tx/internals/TxInternalsTable'; ...@@ -16,8 +16,8 @@ import TxInternalsTable from 'ui/tx/internals/TxInternalsTable';
const searchFn = (searchTerm: string) => (item: ArrayElement<typeof data>): boolean => { const searchFn = (searchTerm: string) => (item: ArrayElement<typeof data>): boolean => {
const formattedSearchTerm = searchTerm.toLowerCase(); const formattedSearchTerm = searchTerm.toLowerCase();
return item.type.toLowerCase().includes(formattedSearchTerm) || return item.type.toLowerCase().includes(formattedSearchTerm) ||
item.from.toLowerCase().includes(formattedSearchTerm) || item.from.hash.toLowerCase().includes(formattedSearchTerm) ||
item.to.toLowerCase().includes(formattedSearchTerm); item.to.hash.toLowerCase().includes(formattedSearchTerm);
}; };
const TxInternals = () => { const TxInternals = () => {
......
...@@ -10,7 +10,7 @@ import AccountListItemMobile from 'ui/shared/AccountListItemMobile'; ...@@ -10,7 +10,7 @@ import AccountListItemMobile from 'ui/shared/AccountListItemMobile';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import TxStatus from 'ui/tx/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
type Props = ArrayElement<typeof data>; type Props = ArrayElement<typeof data>;
...@@ -23,13 +23,13 @@ const TxInternalsListItem = ({ type, status, from, to, value, gasLimit }: Props) ...@@ -23,13 +23,13 @@ const TxInternalsListItem = ({ type, status, from, to, value, gasLimit }: Props)
</Flex> </Flex>
<Box w="100%" display="flex" columnGap={ 3 }> <Box w="100%" display="flex" columnGap={ 3 }>
<Address width="calc((100% - 48px) / 2)"> <Address width="calc((100% - 48px) / 2)">
<AddressIcon hash={ from }/> <AddressIcon hash={ from.hash }/>
<AddressLink ml={ 2 } fontWeight="500" hash={ from }/> <AddressLink ml={ 2 } fontWeight="500" hash={ from.hash }/>
</Address> </Address>
<Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500"/> <Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500"/>
<Address width="calc((100% - 48px) / 2)"> <Address width="calc((100% - 48px) / 2)">
<AddressIcon hash={ to }/> <AddressIcon hash={ to.hash }/>
<AddressLink ml={ 2 } fontWeight="500" hash={ to }/> <AddressLink ml={ 2 } fontWeight="500" hash={ to.hash }/>
</Address> </Address>
</Box> </Box>
<HStack spacing={ 3 }> <HStack spacing={ 3 }>
......
...@@ -5,8 +5,8 @@ import rightArrowIcon from 'icons/arrows/east.svg'; ...@@ -5,8 +5,8 @@ import rightArrowIcon from 'icons/arrows/east.svg';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
interface Props { interface Props {
type: string; type: string;
......
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
import { Button, Flex, Input, IconButton } from '@chakra-ui/react';
import React from 'react';
type Props = {
currentPage: number;
maxPage?: number;
isMobile?: boolean;
}
const MAX_PAGE_DEFAULT = 50;
const Pagination = ({ currentPage, maxPage, isMobile }: Props) => {
return (
<Flex
fontSize="sm"
width={ isMobile ? '100%' : '434px' }
justifyContent="space-between"
>
<Flex alignItems="center" justifyContent="space-between" flexGrow={ 1 }>
<IconButton
variant="outline"
size="sm"
aria-label="Next page"
w="36px"
icon={ <ChevronLeftIcon w={ 5 } h={ 5 }/> }
/>
<Flex alignItems="center">
<Button
variant="outline"
colorScheme="gray"
size="sm"
isActive
borderWidth="1px"
fontWeight={ 400 }
mr={ 3 }
h={ 8 }
>
{ currentPage }
</Button>
of
<Button
variant="outline"
colorScheme="gray"
size="sm"
width={ 8 }
borderWidth="1px"
fontWeight={ 400 }
ml={ 3 }
>
{ maxPage || MAX_PAGE_DEFAULT }
</Button>
</Flex>
<IconButton
variant="outline"
size="sm"
aria-label="Next page"
w="36px"
icon={ <ChevronRightIcon w={ 5 } h={ 5 }/> }
/>
</Flex>
{ !isMobile && (
<Flex alignItems="center" width="132px" ml={ 16 }>
Go to <Input w="84px" h="32px" size="sm" ml={ 2 }/>
</Flex>
) }
</Flex>
);
};
export default Pagination;
import { Box, Heading, Text, Flex, Link, useColorModeValue } from '@chakra-ui/react'; import { Box, Heading, Text, Flex, Link, useColorModeValue } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type ArrayElement from 'types/utils/ArrayElement';
import type { txs } from 'data/txs';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import Separator from 'ui/shared/Separator'; import Separator from 'ui/shared/Separator';
import Utilization from 'ui/shared/Utilization'; import Utilization from 'ui/shared/Utilization';
// eslint-disable-next-line @typescript-eslint/no-explicit-any const TxAdditionalInfo = ({ tx }: { tx: ArrayElement<typeof txs> }) => {
const TxAdditionalInfo = ({ tx }: { tx: any }) => {
const sectionBorderColor = useColorModeValue('gray.200', 'whiteAlpha.200'); const sectionBorderColor = useColorModeValue('gray.200', 'whiteAlpha.200');
const sectionProps = { const sectionProps = {
......
...@@ -7,13 +7,13 @@ import React from 'react'; ...@@ -7,13 +7,13 @@ import React from 'react';
import infoIcon from 'icons/info.svg'; import infoIcon from 'icons/info.svg';
const TxAdditionalInfoButton = ({ isOpen, onClick }: {isOpen?: boolean; onClick?: () => void}) => { const TxAdditionalInfoButton = ({ isOpen, onClick }: {isOpen?: boolean; onClick?: () => void}, ref: React.ForwardedRef<HTMLDivElement>) => {
const infoBgColor = useColorModeValue('blue.50', 'gray.600'); const infoBgColor = useColorModeValue('blue.50', 'gray.600');
const infoColor = useColorModeValue('blue.600', 'blue.300'); const infoColor = useColorModeValue('blue.600', 'blue.300');
return ( return (
<Center background={ isOpen ? infoBgColor : 'unset' } borderRadius="8px" w="30px" h="30px" onClick={ onClick }> <Center ref={ ref } background={ isOpen ? infoBgColor : 'unset' } borderRadius="8px" w="30px" h="30px" onClick={ onClick }>
<Icon <Icon
as={ infoIcon } as={ infoIcon }
boxSize={ 5 } boxSize={ 5 }
...@@ -24,4 +24,4 @@ const TxAdditionalInfoButton = ({ isOpen, onClick }: {isOpen?: boolean; onClick? ...@@ -24,4 +24,4 @@ const TxAdditionalInfoButton = ({ isOpen, onClick }: {isOpen?: boolean; onClick?
); );
}; };
export default TxAdditionalInfoButton; export default React.forwardRef(TxAdditionalInfoButton);
import { Box } from '@chakra-ui/react'; import { Box, HStack } from '@chakra-ui/react';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { txs } from 'data/txs'; import { txs } from 'data/txs';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import Filters from 'ui/shared/Filters'; import FilterButton from 'ui/shared/FilterButton';
import FilterInput from 'ui/shared/FilterInput';
import Pagination from 'ui/shared/Pagination';
import SortButton from 'ui/shared/SortButton';
import Pagination from './Pagination';
import TxsListItem from './TxsListItem'; import TxsListItem from './TxsListItem';
import TxsTable from './TxsTable'; import TxsTable from './TxsTable';
...@@ -69,11 +71,32 @@ const TxsContent = ({ isPending }: Props) => { ...@@ -69,11 +71,32 @@ const TxsContent = ({ isPending }: Props) => {
return ( return (
<> <>
{ !isPending && <Box mb={ 12 }>Only the first 10,000 elements are displayed</Box> } { !isPending && <Box mb={ 12 }>Only the first 10,000 elements are displayed</Box> }
<Box mb={ 6 }><Filters isMobile={ isMobile }/></Box> <HStack mb={ 6 }>
{ /* TODO */ }
<FilterButton
isActive={ false }
isCollapsed={ isMobile }
// eslint-disable-next-line react/jsx-no-bind
onClick={ () => {} }
appliedFiltersNum={ 0 }
/>
<SortButton
// eslint-disable-next-line react/jsx-no-bind
handleSort={ () => {} }
isSortActive={ Boolean(sorting) }
/>
<FilterInput
// eslint-disable-next-line react/jsx-no-bind
onChange={ () => {} }
maxW="360px"
size="xs"
placeholder="Search by addresses, hash, method..."
/>
</HStack>
{ isMobile ? { isMobile ?
sortedTxs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) : sortedTxs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) :
<TxsTable txs={ sortedTxs } sort={ sort } sorting={ sorting }/> } <TxsTable txs={ sortedTxs } sort={ sort } sorting={ sorting }/> }
<Box mx={ isMobile ? 0 : 6 } my={ isMobile ? 6 : 3 }> <Box mx={{ base: 0, lg: 6 }} my={{ base: 6, lg: 3 }}>
<Pagination currentPage={ 1 } isMobile={ isMobile }/> <Pagination currentPage={ 1 } isMobile={ isMobile }/>
</Box> </Box>
</> </>
......
...@@ -8,12 +8,14 @@ import { ...@@ -8,12 +8,14 @@ import {
ModalContent, ModalContent,
ModalCloseButton, ModalCloseButton,
Text, Text,
Tooltip,
useColorModeValue, useColorModeValue,
useDisclosure } from '@chakra-ui/react'; useDisclosure } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import rightArrowIcon from 'icons/arrows/right.svg'; import type ArrayElement from 'types/utils/ArrayElement';
import type { txs } from 'data/txs';
import rightArrowIcon from 'icons/arrows/east.svg';
import transactionIcon from 'icons/transactions.svg'; import transactionIcon from 'icons/transactions.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
...@@ -25,13 +27,10 @@ import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; ...@@ -25,13 +27,10 @@ import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
import TxAdditionalInfoButton from 'ui/txs/TxAdditionalInfoButton'; import TxAdditionalInfoButton from 'ui/txs/TxAdditionalInfoButton';
import TxType from 'ui/txs/TxType'; import TxType from 'ui/txs/TxType';
// eslint-disable-next-line @typescript-eslint/no-explicit-any const TxsListItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
const TxsListItem = ({ tx }: {tx: any}) => {
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const iconColor = useColorModeValue('blue.600', 'blue.300'); const iconColor = useColorModeValue('blue.600', 'blue.300');
const secondaryTextColor = useColorModeValue('gray.500', 'gray.400');
const link = useLink(); const link = useLink();
return ( return (
...@@ -61,34 +60,32 @@ const TxsListItem = ({ tx }: {tx: any}) => { ...@@ -61,34 +60,32 @@ const TxsListItem = ({ tx }: {tx: any}) => {
/> />
</Address> </Address>
</Flex> </Flex>
<Text color={ secondaryTextColor } fontWeight="400">{ dayjs(tx.timestamp).fromNow() }</Text> <Text variant="secondary" fontWeight="400">{ dayjs(tx.timestamp).fromNow() }</Text>
</Flex> </Flex>
<Flex mt={ 3 }> <Flex mt={ 3 }>
<Text as="span" whiteSpace="pre">Method </Text> <Text as="span" whiteSpace="pre">Method </Text>
<Box <Text
color={ secondaryTextColor } as="span"
variant="secondary"
overflow="hidden" overflow="hidden"
whiteSpace="nowrap" whiteSpace="nowrap"
textOverflow="ellipsis" textOverflow="ellipsis"
> >
{ tx.method } { tx.method }
</Box> </Text>
</Flex> </Flex>
<Box mt={ 2 }> <Box mt={ 2 }>
<Text as="span">Block </Text> <Text as="span">Block </Text>
<Link href={ link('block', { id: tx.block_num }) }>{ tx.block_num }</Link> <Link href={ link('block', { id: tx.block_num.toString() }) }>{ tx.block_num }</Link>
</Box> </Box>
<Flex alignItems="center" height={ 6 } mt={ 6 }> <Flex alignItems="center" height={ 6 } mt={ 6 }>
<Address width="calc((100%-40px)/2)"> <Address width="calc((100%-40px)/2)">
<Tooltip label={ tx.address_from.type } shouldWrapChildren> <AddressIcon hash={ tx.address_from.hash }/>
<AddressIcon hash={ tx.address_from.hash }/>
</Tooltip>
<AddressLink <AddressLink
hash={ tx.address_from.hash } hash={ tx.address_from.hash }
alias={ tx.address_from.alias } alias={ tx.address_from.alias }
fontWeight="500" fontWeight="500"
ml={ 2 } ml={ 2 }
truncation="constant"
/> />
</Address> </Address>
<Icon <Icon
...@@ -98,25 +95,22 @@ const TxsListItem = ({ tx }: {tx: any}) => { ...@@ -98,25 +95,22 @@ const TxsListItem = ({ tx }: {tx: any}) => {
color="gray.500" color="gray.500"
/> />
<Address width="calc((100%-40px)/2)"> <Address width="calc((100%-40px)/2)">
<Tooltip label={ tx.address_to.type } shouldWrapChildren> <AddressIcon hash={ tx.address_to.hash }/>
<AddressIcon hash={ tx.address_to.hash }/>
</Tooltip>
<AddressLink <AddressLink
hash={ tx.address_to.hash } hash={ tx.address_to.hash }
alias={ tx.address_to.alias } alias={ tx.address_to.alias }
fontWeight="500" fontWeight="500"
ml={ 2 } ml={ 2 }
truncation="constant"
/> />
</Address> </Address>
</Flex> </Flex>
<Box mt={ 2 }> <Box mt={ 2 }>
<Text as="span">Value xDAI </Text> <Text as="span">Value xDAI </Text>
<Text as="span" color={ secondaryTextColor }>{ tx.amount.value.toFixed(8) }</Text> <Text as="span" variant="secondary">{ tx.amount.value.toFixed(8) }</Text>
</Box> </Box>
<Box mt={ 2 } mb={ 3 }> <Box mt={ 2 } mb={ 3 }>
<Text as="span">Fee xDAI </Text> <Text as="span">Fee xDAI </Text>
<Text as="span" color={ secondaryTextColor }>{ tx.fee.value.toFixed(8) }</Text> <Text as="span" variant="secondary">{ tx.fee.value.toFixed(8) }</Text>
</Box> </Box>
</Box> </Box>
<Modal isOpen={ isOpen } onClose={ onClose } size="full"> <Modal isOpen={ isOpen } onClose={ onClose } size="full">
......
import { Link, Table, Thead, Tbody, Tr, Th, TableContainer, useBreakpointValue, Icon } from '@chakra-ui/react'; import { Link, Table, Thead, Tbody, Tr, Th, TableContainer, useBreakpointValue, Icon } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import rightArrowIcon from 'icons/arrows/right.svg'; import type { txs as data } from 'data/txs';
import rightArrowIcon from 'icons/arrows/east.svg';
import TxsTableItem from './TxsTableItem'; import TxsTableItem from './TxsTableItem';
...@@ -10,8 +11,7 @@ const CURRENCY = 'xDAI'; ...@@ -10,8 +11,7 @@ const CURRENCY = 'xDAI';
export type Sort = 'val-desc' | 'val-asc' | 'fee-desc' | 'fee-asc' | undefined; export type Sort = 'val-desc' | 'val-asc' | 'fee-desc' | 'fee-asc' | undefined;
type Props = { type Props = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any txs: typeof data;
txs: any;
sort: (field: 'val' | 'fee') => () => void; sort: (field: 'val' | 'fee') => () => void;
sorting: Sort; sorting: Sort;
} }
...@@ -49,8 +49,7 @@ const TxsTable = ({ txs, sort, sorting }: Props) => { ...@@ -49,8 +49,7 @@ const TxsTable = ({ txs, sort, sorting }: Props) => {
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
{ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ } { txs.map((item) => (
{ txs.map((item: any) => (
<TxsTableItem <TxsTableItem
key={ item.hash } key={ item.hash }
tx={ item } tx={ item }
......
...@@ -12,12 +12,16 @@ import { ...@@ -12,12 +12,16 @@ import {
PopoverTrigger, PopoverTrigger,
PopoverContent, PopoverContent,
PopoverBody, PopoverBody,
Portal,
useBreakpointValue, useBreakpointValue,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import rightArrowIcon from 'icons/arrows/right.svg'; import type ArrayElement from 'types/utils/ArrayElement';
import type { txs } from 'data/txs';
import rightArrowIcon from 'icons/arrows/east.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
...@@ -30,16 +34,15 @@ import TxAdditionalInfoButton from 'ui/txs/TxAdditionalInfoButton'; ...@@ -30,16 +34,15 @@ import TxAdditionalInfoButton from 'ui/txs/TxAdditionalInfoButton';
import TxType from './TxType'; import TxType from './TxType';
// eslint-disable-next-line @typescript-eslint/no-explicit-any const TxsTableItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
const TxsTableItem = ({ tx }: {tx: any}) => {
const link = useLink(); const link = useLink();
const isLargeScreen = useBreakpointValue({ base: false, xl: true }); const isLargeScreen = useBreakpointValue({ base: false, xl: true });
const addressFrom = ( const addressFrom = (
<Address> <Address>
<Tooltip label={ tx.address_from.type } shouldWrapChildren> <Tooltip label={ tx.address_from.type }>
<AddressIcon hash={ tx.address_from.hash }/> <Box display="flex"><AddressIcon hash={ tx.address_from.hash }/></Box>
</Tooltip> </Tooltip>
<AddressLink hash={ tx.address_from.hash } alias={ tx.address_from.alias } fontWeight="500" ml={ 2 }/> <AddressLink hash={ tx.address_from.hash } alias={ tx.address_from.alias } fontWeight="500" ml={ 2 }/>
</Address> </Address>
...@@ -47,8 +50,8 @@ const TxsTableItem = ({ tx }: {tx: any}) => { ...@@ -47,8 +50,8 @@ const TxsTableItem = ({ tx }: {tx: any}) => {
const addressTo = ( const addressTo = (
<Address> <Address>
<Tooltip label={ tx.address_to.type } shouldWrapChildren> <Tooltip label={ tx.address_to.type }>
<AddressIcon hash={ tx.address_to.hash }/> <Box display="flex"> <AddressIcon hash={ tx.address_to.hash }/></Box>
</Tooltip> </Tooltip>
<AddressLink hash={ tx.address_to.hash } alias={ tx.address_to.alias } fontWeight="500" ml={ 2 }/> <AddressLink hash={ tx.address_to.hash } alias={ tx.address_to.alias } fontWeight="500" ml={ 2 }/>
</Address> </Address>
...@@ -64,11 +67,13 @@ const TxsTableItem = ({ tx }: {tx: any}) => { ...@@ -64,11 +67,13 @@ const TxsTableItem = ({ tx }: {tx: any}) => {
<PopoverTrigger> <PopoverTrigger>
<TxAdditionalInfoButton isOpen={ isOpen }/> <TxAdditionalInfoButton isOpen={ isOpen }/>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent border="1px solid" borderColor={ infoBorderColor }> <Portal>
<PopoverBody> <PopoverContent border="1px solid" borderColor={ infoBorderColor }>
<TxAdditionalInfo tx={ tx }/> <PopoverBody>
</PopoverBody> <TxAdditionalInfo tx={ tx }/>
</PopoverContent> </PopoverBody>
</PopoverContent>
</Portal>
</> </>
) } ) }
</Popover> </Popover>
...@@ -101,7 +106,7 @@ const TxsTableItem = ({ tx }: {tx: any}) => { ...@@ -101,7 +106,7 @@ const TxsTableItem = ({ tx }: {tx: any}) => {
</TruncatedTextTooltip> </TruncatedTextTooltip>
</Td> </Td>
<Td> <Td>
<Link href={ link('block', { id: tx.block_num }) }>{ tx.block_num }</Link> <Link href={ link('block', { id: tx.block_num.toString() }) }>{ tx.block_num }</Link>
</Td> </Td>
{ isLargeScreen ? ( { isLargeScreen ? (
<> <>
......
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