Commit 3ac5beb6 authored by isstuev's avatar isstuev

fixes

parent 9fa8a76b
/* eslint-disable max-len */
export const tx = {
hash: '0x1ea365d2144796f793883534aa51bf20d23292b19478994eede23dfc599e7c34',
status: 'success',
status: 'success' as TxStatus,
block_num: 15006918,
confirmation_num: 283,
confirmation_duration: 30,
......@@ -9,10 +9,12 @@ export const tx = {
address_from: {
hash: '0x97Aa2EfcF35c0f4c9AaDDCa8c2330fa7A9533830',
type: 'Address',
alias: '',
},
address_to: {
hash: '0x35317007D203b8a86CA727ad44E473E40450E378',
type: 'Contract',
alias: '',
},
amount: {
value: 0.03,
......@@ -45,4 +47,9 @@ export const tx = {
{ from: '0x12E80C27BfFBB76b4A8d26FF2bfd3C9f310FFA01', to: '0xF7A558692dFB5F456e291791da7FAE8Dd046574e', token: 'USDT', amount: 192.7, 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 type { TxType, TxStatus } from './tx';
export const txs = [
{
...tx,
method: 'Withdraw',
txType: 'transaction',
txType: 'transaction' as TxType,
errorText: '',
},
{
...tx,
status: 'failed',
status: 'failed' as TxStatus,
errorText: 'Error: (Awaiting internal transactions for reason)',
txType: 'contract-call',
txType: 'contract-call' as TxType,
method: 'CommitHash CommitHash CommitHash CommitHash',
amount: {
value: 0.04,
......@@ -23,8 +25,8 @@ export const txs = [
},
{
...tx,
status: 'pending',
txType: 'token-transfer',
status: 'pending' as TxStatus,
txType: 'token-transfer' as TxType,
method: 'Multicall',
address_from: {
hash: '0x97Aa2EfcF35c0f4c9AaDDCa8c2330fa7A9533830',
......@@ -39,5 +41,6 @@ export const txs = [
value: 0.002495904453623692,
value_usd: 2.84,
},
errorText: '',
},
];
......@@ -19,7 +19,7 @@ const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => {
return (
<>
<Head><title>{ title }</title></Head>
<Transactions tab="pending"/>
<Transactions tab="txs_pending"/>
</>
);
};
......
......@@ -19,7 +19,7 @@ const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => {
return (
<>
<Head><title>{ title }</title></Head>
<Transactions tab="validated"/>
<Transactions tab="txs_validated"/>
</>
);
};
......
......@@ -35,7 +35,6 @@ const baseStyleContainer = defineStyle({
overflow: 'hidden',
textOverflow: 'ellipsis',
borderRadius: 'sm',
lineHeight: '20px',
...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';
......
......@@ -33,7 +33,7 @@ const TransactionPageContent = ({ tab }: Props) => {
return (
<Page>
{ /* 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)"/>
Transactions
</Link>
......
import {
Box,
Tab,
Tabs,
TabList,
TabPanel,
TabPanels,
} 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 PageHeader from 'ui/shared/PageHeader';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
import TxsPending from 'ui/txs/TxsPending';
import TxsValidated from 'ui/txs/TxsValidated';
const TABS = [ 'validated', 'pending' ] as const;
type TabName = typeof TABS[number];
const TABS: Array<RoutedTab> = [
{ routeName: 'txs_validated', title: 'Validated', component: <TxsValidated/> },
{ routeName: 'txs_pending', title: 'Pending', component: <TxsPending/> },
];
type Props = {
tab: TabName;
tab: RoutedTab['routeName'];
}
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 (
<Page>
<Box h="100%">
<PageHeader text="Transactions"/>
<Tabs variant="soft-rounded" colorScheme="blue" isLazy onChange={ onChangeTab } defaultIndex={ TABS.indexOf(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>
<RoutedTabs tabs={ TABS } defaultActiveTab={ tab }/>
</Box>
</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';
const searchFn = (searchTerm: string) => (item: ArrayElement<typeof data>): boolean => {
const formattedSearchTerm = searchTerm.toLowerCase();
return item.type.toLowerCase().includes(formattedSearchTerm) ||
item.from.toLowerCase().includes(formattedSearchTerm) ||
item.to.toLowerCase().includes(formattedSearchTerm);
item.from.hash.toLowerCase().includes(formattedSearchTerm) ||
item.to.hash.toLowerCase().includes(formattedSearchTerm);
};
const TxInternals = () => {
......
......@@ -10,7 +10,7 @@ import AccountListItemMobile from 'ui/shared/AccountListItemMobile';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import TxStatus from 'ui/tx/TxStatus';
import TxStatus from 'ui/shared/TxStatus';
type Props = ArrayElement<typeof data>;
......@@ -23,13 +23,13 @@ const TxInternalsListItem = ({ type, status, from, to, value, gasLimit }: Props)
</Flex>
<Box w="100%" display="flex" columnGap={ 3 }>
<Address width="calc((100% - 48px) / 2)">
<AddressIcon hash={ from }/>
<AddressLink ml={ 2 } fontWeight="500" hash={ from }/>
<AddressIcon hash={ from.hash }/>
<AddressLink ml={ 2 } fontWeight="500" hash={ from.hash }/>
</Address>
<Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500"/>
<Address width="calc((100% - 48px) / 2)">
<AddressIcon hash={ to }/>
<AddressLink ml={ 2 } fontWeight="500" hash={ to }/>
<AddressIcon hash={ to.hash }/>
<AddressLink ml={ 2 } fontWeight="500" hash={ to.hash }/>
</Address>
</Box>
<HStack spacing={ 3 }>
......
......@@ -5,8 +5,8 @@ import rightArrowIcon from 'icons/arrows/east.svg';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
interface Props {
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 React from 'react';
import type ArrayElement from 'types/utils/ArrayElement';
import type { txs } from 'data/txs';
import useLink from 'lib/link/useLink';
import Separator from 'ui/shared/Separator';
import Utilization from 'ui/shared/Utilization';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const TxAdditionalInfo = ({ tx }: { tx: any }) => {
const TxAdditionalInfo = ({ tx }: { tx: ArrayElement<typeof txs> }) => {
const sectionBorderColor = useColorModeValue('gray.200', 'whiteAlpha.200');
const sectionProps = {
......
......@@ -7,13 +7,13 @@ import React from 'react';
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 infoColor = useColorModeValue('blue.600', 'blue.300');
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
as={ infoIcon }
boxSize={ 5 }
......@@ -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 { txs } from 'data/txs';
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 TxsTable from './TxsTable';
......@@ -69,11 +71,32 @@ const TxsContent = ({ isPending }: Props) => {
return (
<>
{ !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 ?
sortedTxs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) :
<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 }/>
</Box>
</>
......
......@@ -8,12 +8,14 @@ import {
ModalContent,
ModalCloseButton,
Text,
Tooltip,
useColorModeValue,
useDisclosure } from '@chakra-ui/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 dayjs from 'lib/date/dayjs';
import useLink from 'lib/link/useLink';
......@@ -25,13 +27,10 @@ import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
import TxAdditionalInfoButton from 'ui/txs/TxAdditionalInfoButton';
import TxType from 'ui/txs/TxType';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const TxsListItem = ({ tx }: {tx: any}) => {
const TxsListItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const iconColor = useColorModeValue('blue.600', 'blue.300');
const secondaryTextColor = useColorModeValue('gray.500', 'gray.400');
const link = useLink();
return (
......@@ -61,34 +60,32 @@ const TxsListItem = ({ tx }: {tx: any}) => {
/>
</Address>
</Flex>
<Text color={ secondaryTextColor } fontWeight="400">{ dayjs(tx.timestamp).fromNow() }</Text>
<Text variant="secondary" fontWeight="400">{ dayjs(tx.timestamp).fromNow() }</Text>
</Flex>
<Flex mt={ 3 }>
<Text as="span" whiteSpace="pre">Method </Text>
<Box
color={ secondaryTextColor }
<Text
as="span"
variant="secondary"
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
>
{ tx.method }
</Box>
</Text>
</Flex>
<Box mt={ 2 }>
<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>
<Flex alignItems="center" height={ 6 } mt={ 6 }>
<Address width="calc((100%-40px)/2)">
<Tooltip label={ tx.address_from.type } shouldWrapChildren>
<AddressIcon hash={ tx.address_from.hash }/>
</Tooltip>
<AddressLink
hash={ tx.address_from.hash }
alias={ tx.address_from.alias }
fontWeight="500"
ml={ 2 }
truncation="constant"
/>
</Address>
<Icon
......@@ -98,25 +95,22 @@ const TxsListItem = ({ tx }: {tx: any}) => {
color="gray.500"
/>
<Address width="calc((100%-40px)/2)">
<Tooltip label={ tx.address_to.type } shouldWrapChildren>
<AddressIcon hash={ tx.address_to.hash }/>
</Tooltip>
<AddressLink
hash={ tx.address_to.hash }
alias={ tx.address_to.alias }
fontWeight="500"
ml={ 2 }
truncation="constant"
/>
</Address>
</Flex>
<Box mt={ 2 }>
<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 mt={ 2 } mb={ 3 }>
<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>
<Modal isOpen={ isOpen } onClose={ onClose } size="full">
......
import { Link, Table, Thead, Tbody, Tr, Th, TableContainer, useBreakpointValue, Icon } from '@chakra-ui/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';
......@@ -10,8 +11,7 @@ const CURRENCY = 'xDAI';
export type Sort = 'val-desc' | 'val-asc' | 'fee-desc' | 'fee-asc' | undefined;
type Props = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
txs: any;
txs: typeof data;
sort: (field: 'val' | 'fee') => () => void;
sorting: Sort;
}
......@@ -49,8 +49,7 @@ const TxsTable = ({ txs, sort, sorting }: Props) => {
</Tr>
</Thead>
<Tbody>
{ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ }
{ txs.map((item: any) => (
{ txs.map((item) => (
<TxsTableItem
key={ item.hash }
tx={ item }
......
......@@ -12,12 +12,16 @@ import {
PopoverTrigger,
PopoverContent,
PopoverBody,
Portal,
useBreakpointValue,
useColorModeValue,
} from '@chakra-ui/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 useLink from 'lib/link/useLink';
import Address from 'ui/shared/address/Address';
......@@ -30,16 +34,15 @@ import TxAdditionalInfoButton from 'ui/txs/TxAdditionalInfoButton';
import TxType from './TxType';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const TxsTableItem = ({ tx }: {tx: any}) => {
const TxsTableItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
const link = useLink();
const isLargeScreen = useBreakpointValue({ base: false, xl: true });
const addressFrom = (
<Address>
<Tooltip label={ tx.address_from.type } shouldWrapChildren>
<AddressIcon hash={ tx.address_from.hash }/>
<Tooltip label={ tx.address_from.type }>
<Box display="flex"><AddressIcon hash={ tx.address_from.hash }/></Box>
</Tooltip>
<AddressLink hash={ tx.address_from.hash } alias={ tx.address_from.alias } fontWeight="500" ml={ 2 }/>
</Address>
......@@ -47,8 +50,8 @@ const TxsTableItem = ({ tx }: {tx: any}) => {
const addressTo = (
<Address>
<Tooltip label={ tx.address_to.type } shouldWrapChildren>
<AddressIcon hash={ tx.address_to.hash }/>
<Tooltip label={ tx.address_to.type }>
<Box display="flex"> <AddressIcon hash={ tx.address_to.hash }/></Box>
</Tooltip>
<AddressLink hash={ tx.address_to.hash } alias={ tx.address_to.alias } fontWeight="500" ml={ 2 }/>
</Address>
......@@ -64,11 +67,13 @@ const TxsTableItem = ({ tx }: {tx: any}) => {
<PopoverTrigger>
<TxAdditionalInfoButton isOpen={ isOpen }/>
</PopoverTrigger>
<Portal>
<PopoverContent border="1px solid" borderColor={ infoBorderColor }>
<PopoverBody>
<TxAdditionalInfo tx={ tx }/>
</PopoverBody>
</PopoverContent>
</Portal>
</>
) }
</Popover>
......@@ -101,7 +106,7 @@ const TxsTableItem = ({ tx }: {tx: any}) => {
</TruncatedTextTooltip>
</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>
{ 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