Commit d13f87b4 authored by tom's avatar tom

accounts and verified contracts pages

parent 16408afe
......@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs';
// const Accounts = dynamic(() => import('ui/pages/Accounts'), { ssr: false });
const Accounts = dynamic(() => import('ui/pages/Accounts'), { ssr: false });
const Page: NextPage = () => {
return (
<PageNextJs pathname="/accounts">
{ /* <Accounts/> */ }
<Accounts/>
</PageNextJs>
);
};
......
......@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs';
// const AccountsLabelSearch = dynamic(() => import('ui/pages/AccountsLabelSearch'), { ssr: false });
const AccountsLabelSearch = dynamic(() => import('ui/pages/AccountsLabelSearch'), { ssr: false });
const Page: NextPage = () => {
return (
<PageNextJs pathname="/accounts/label/[slug]">
{ /* <AccountsLabelSearch/> */ }
<AccountsLabelSearch/>
</PageNextJs>
);
};
......
......@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs';
// const VerifiedContracts = dynamic(() => import('ui/pages/VerifiedContracts'), { ssr: false });
const VerifiedContracts = dynamic(() => import('ui/pages/VerifiedContracts'), { ssr: false });
const Page: NextPage = () => {
return (
<PageNextJs pathname="/verified-contracts">
{ /* <VerifiedContracts/> */ }
<VerifiedContracts/>
</PageNextJs>
);
};
......
......@@ -5,4 +5,4 @@ export interface VerifiedContractsSorting {
export type VerifiedContractsSortingField = VerifiedContractsSorting['sort'];
export type VerifiedContractsSortingValue = `${ VerifiedContractsSortingField }-${ VerifiedContractsSorting['order'] }`;
export type VerifiedContractsSortingValue = `${ VerifiedContractsSortingField }-${ VerifiedContractsSorting['order'] }` | 'default';
......@@ -7,8 +7,8 @@ import type { AddressesItem } from 'types/api/addresses';
import config from 'configs/app';
import { ZERO } from 'lib/consts';
import { currencyUnits } from 'lib/units';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tag } from 'toolkit/chakra/tag';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
......@@ -38,30 +38,30 @@ const AddressesListItem = ({
mr={ 2 }
truncation="constant"
/>
<Skeleton isLoaded={ !isLoading } fontSize="sm" ml="auto" minW={ 6 } color="text_secondary">
<Skeleton loading={ isLoading } fontSize="sm" ml="auto" minW={ 6 } color="text_secondary">
<span>{ index }</span>
</Skeleton>
</Flex>
{ item.public_tags !== null && item.public_tags.length > 0 && item.public_tags.map(tag => (
<Tag key={ tag.label } isLoading={ isLoading }>{ tag.display_name }</Tag>
<Tag key={ tag.label } loading={ isLoading } truncated>{ tag.display_name }</Tag>
)) }
<HStack spacing={ 3 } maxW="100%" alignItems="flex-start">
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 } flexShrink={ 0 }>{ `Balance ${ currencyUnits.ether }` }</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" minW="0" whiteSpace="pre-wrap">
<HStack gap={ 3 } maxW="100%" alignItems="flex-start">
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 } flexShrink={ 0 }>{ `Balance ${ currencyUnits.ether }` }</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary" minW="0" whiteSpace="pre-wrap">
<span>{ addressBalance.dp(8).toFormat() }</span>
</Skeleton>
</HStack>
{ !totalSupply.eq(ZERO) && (
<HStack spacing={ 3 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Percentage</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary">
<HStack gap={ 3 }>
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 }>Percentage</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary">
<span>{ addressBalance.div(BigNumber(totalSupply)).multipliedBy(100).dp(8).toFormat() + '%' }</span>
</Skeleton>
</HStack>
) }
<HStack spacing={ 3 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Txn count</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary">
<HStack gap={ 3 }>
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 }>Txn count</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary">
<span>{ Number(item.transaction_count).toLocaleString() }</span>
</Skeleton>
</HStack>
......
import { Table, Tbody, Tr, Th } from '@chakra-ui/react';
import type BigNumber from 'bignumber.js';
import React from 'react';
......@@ -6,7 +5,7 @@ import type { AddressesItem } from 'types/api/addresses';
import { ZERO } from 'lib/consts';
import { currencyUnits } from 'lib/units';
import { default as Thead } from 'ui/shared/TheadSticky';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import AddressesTableItem from './AddressesTableItem';
......@@ -21,17 +20,17 @@ interface Props {
const AddressesTable = ({ items, totalSupply, pageStartIndex, top, isLoading }: Props) => {
const hasPercentage = !totalSupply.eq(ZERO);
return (
<Table>
<Thead top={ top }>
<Tr>
<Th width="64px">Rank</Th>
<Th width={ hasPercentage ? '50%' : '60%' }>Address</Th>
<Th width={ hasPercentage ? '20%' : '25%' } isNumeric>{ `Balance ${ currencyUnits.ether }` }</Th>
{ hasPercentage && <Th width="15%" isNumeric>Percentage</Th> }
<Th width="15%" isNumeric>Txn count</Th>
</Tr>
</Thead>
<Tbody>
<TableRoot>
<TableHeaderSticky top={ top }>
<TableRow>
<TableColumnHeader width="64px">Rank</TableColumnHeader>
<TableColumnHeader width={ hasPercentage ? '50%' : '60%' }>Address</TableColumnHeader>
<TableColumnHeader width={ hasPercentage ? '20%' : '25%' } isNumeric>{ `Balance ${ currencyUnits.ether }` }</TableColumnHeader>
{ hasPercentage && <TableColumnHeader width="15%" isNumeric>Percentage</TableColumnHeader> }
<TableColumnHeader width="15%" isNumeric>Txn count</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ items.map((item, index) => (
<AddressesTableItem
key={ item.hash + (isLoading ? index : '') }
......@@ -42,8 +41,8 @@ const AddressesTable = ({ items, totalSupply, pageStartIndex, top, isLoading }:
isLoading={ isLoading }
/>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
);
};
......
import { Tr, Td, Text, Flex } from '@chakra-ui/react';
import { Text, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { AddressesItem } from 'types/api/addresses';
import config from 'configs/app';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import { Tag } from 'toolkit/chakra/tag';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
type Props = {
......@@ -29,13 +30,13 @@ const AddressesTableItem = ({
const addressBalanceChunks = addressBalance.dp(8).toFormat().split('.');
return (
<Tr>
<Td>
<Skeleton isLoaded={ !isLoading } display="inline-block" minW={ 6 } lineHeight="24px">
<TableRow>
<TableCell>
<Skeleton loading={ isLoading } display="inline-block" minW={ 6 } lineHeight="24px">
{ index }
</Skeleton>
</Td>
<Td>
</TableCell>
<TableCell>
<Flex alignItems="center" columnGap={ 2 }>
<AddressEntity
address={ item }
......@@ -44,27 +45,27 @@ const AddressesTableItem = ({
my="2px"
/>
{ item.public_tags && item.public_tags.length ? item.public_tags.map(tag => (
<Tag key={ tag.label } isLoading={ isLoading } isTruncated>{ tag.display_name }</Tag>
<Tag key={ tag.label } loading={ isLoading } truncated>{ tag.display_name }</Tag>
)) : null }
</Flex>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" maxW="100%">
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" maxW="100%">
<Text lineHeight="24px" as="span">{ addressBalanceChunks[0] + (addressBalanceChunks[1] ? '.' : '') }</Text>
<Text lineHeight="24px" variant="secondary" as="span">{ addressBalanceChunks[1] }</Text>
<Text lineHeight="24px" color="text.secondary" as="span">{ addressBalanceChunks[1] }</Text>
</Skeleton>
</Td>
</TableCell>
{ hasPercentage && (
<Td isNumeric>
<TableCell isNumeric>
<Text lineHeight="24px">{ addressBalance.div(totalSupply).multipliedBy(100).dp(8).toFormat() + '%' }</Text>
</Td>
</TableCell>
) }
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" lineHeight="24px">
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" lineHeight="24px">
{ Number(item.transaction_count).toLocaleString() }
</Skeleton>
</Td>
</Tr>
</TableCell>
</TableRow>
);
};
......
......@@ -6,7 +6,7 @@ import type { AddressesItem } from 'types/api/addresses';
import config from 'configs/app';
import { currencyUnits } from 'lib/units';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Skeleton } from 'toolkit/chakra/skeleton';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
......@@ -30,15 +30,15 @@ const AddressesLabelSearchListItem = ({
fontWeight={ 700 }
w="100%"
/>
<HStack spacing={ 3 } maxW="100%" alignItems="flex-start">
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 } flexShrink={ 0 }>{ `Balance ${ currencyUnits.ether }` }</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" minW="0" whiteSpace="pre-wrap">
<HStack gap={ 3 } maxW="100%" alignItems="flex-start">
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 } flexShrink={ 0 }>{ `Balance ${ currencyUnits.ether }` }</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary" minW="0" whiteSpace="pre-wrap">
<span>{ addressBalance.dp(8).toFormat() }</span>
</Skeleton>
</HStack>
<HStack spacing={ 3 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Txn count</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary">
<HStack gap={ 3 }>
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 }>Txn count</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary">
<span>{ Number(item.transaction_count).toLocaleString() }</span>
</Skeleton>
</HStack>
......
import { Table, Tbody, Tr, Th } from '@chakra-ui/react';
import React from 'react';
import type { AddressesItem } from 'types/api/addresses';
import { currencyUnits } from 'lib/units';
import { default as Thead } from 'ui/shared/TheadSticky';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import AddressesLabelSearchTableItem from './AddressesLabelSearchTableItem';
......@@ -16,15 +15,15 @@ interface Props {
const AddressesLabelSearchTable = ({ items, top, isLoading }: Props) => {
return (
<Table>
<Thead top={ top }>
<Tr>
<Th width="70%">Address</Th>
<Th width="15%" isNumeric>{ `Balance ${ currencyUnits.ether }` }</Th>
<Th width="15%" isNumeric>Txn count</Th>
</Tr>
</Thead>
<Tbody>
<TableRoot>
<TableHeaderSticky top={ top }>
<TableRow>
<TableColumnHeader width="70%">Address</TableColumnHeader>
<TableColumnHeader width="15%" isNumeric>{ `Balance ${ currencyUnits.ether }` }</TableColumnHeader>
<TableColumnHeader width="15%" isNumeric>Txn count</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ items.map((item, index) => (
<AddressesLabelSearchTableItem
key={ item.hash + (isLoading ? index : '') }
......@@ -32,8 +31,8 @@ const AddressesLabelSearchTable = ({ items, top, isLoading }: Props) => {
isLoading={ isLoading }
/>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
);
};
......
import { Tr, Td, Text } from '@chakra-ui/react';
import { Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { AddressesItem } from 'types/api/addresses';
import config from 'configs/app';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
type Props = {
......@@ -22,27 +23,27 @@ const AddressesLabelSearchTableItem = ({
const addressBalanceChunks = addressBalance.dp(8).toFormat().split('.');
return (
<Tr>
<Td>
<TableRow>
<TableCell>
<AddressEntity
address={ item }
isLoading={ isLoading }
fontWeight={ 700 }
my="2px"
/>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" maxW="100%">
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" maxW="100%">
<Text lineHeight="24px" as="span">{ addressBalanceChunks[0] + (addressBalanceChunks[1] ? '.' : '') }</Text>
<Text lineHeight="24px" variant="secondary" as="span">{ addressBalanceChunks[1] }</Text>
<Text lineHeight="24px" color="text.secondary" as="span">{ addressBalanceChunks[1] }</Text>
</Skeleton>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" lineHeight="24px">
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" lineHeight="24px">
{ Number(item.transaction_count).toLocaleString() }
</Skeleton>
</Td>
</Tr>
</TableCell>
</TableRow>
);
};
......
import { Hide, Show } from '@chakra-ui/react';
import { Box } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -45,7 +45,7 @@ const Accounts = () => {
const content = data?.items ? (
<>
<Hide below="lg" ssr={ false }>
<Box hideBelow="lg">
<AddressesTable
top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }
items={ data.items }
......@@ -53,8 +53,8 @@ const Accounts = () => {
pageStartIndex={ pageStartIndex }
isLoading={ isPlaceholderData }
/>
</Hide>
<Show below="lg" ssr={ false }>
</Box>
<Box hideFrom="lg">
{ data.items.map((item, index) => {
return (
<AddressesListItem
......@@ -66,7 +66,7 @@ const Accounts = () => {
/>
);
}) }
</Show>
</Box>
</>
) : null;
......@@ -75,11 +75,12 @@ const Accounts = () => {
<PageTitle title="Top accounts" withTextAd/>
<DataListDisplay
isError={ isError }
items={ data?.items }
itemsNum={ data?.items.length }
emptyText="There are no accounts."
content={ content }
actionBar={ actionBar }
/>
>
{ content }
</DataListDisplay>
</>
);
};
......
import { chakra, Flex, Hide, Show } from '@chakra-ui/react';
import { Box, chakra, Flex } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -7,10 +7,10 @@ import type { EntityTag as TEntityTag, EntityTagType } from 'ui/shared/EntityTag
import getQueryParamString from 'lib/router/getQueryParamString';
import { TOP_ADDRESS } from 'stubs/address';
import { generateListStub } from 'stubs/utils';
import { Skeleton } from 'toolkit/chakra/skeleton';
import AddressesLabelSearchListItem from 'ui/addressesLabelSearch/AddressesLabelSearchListItem';
import AddressesLabelSearchTable from 'ui/addressesLabelSearch/AddressesLabelSearchTable';
import { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import Skeleton from 'ui/shared/chakra/Skeleton';
import DataListDisplay from 'ui/shared/DataListDisplay';
import EntityTag from 'ui/shared/EntityTags/EntityTag';
import PageTitle from 'ui/shared/Page/PageTitle';
......@@ -43,14 +43,14 @@ const AccountsLabelSearch = () => {
const content = data?.items ? (
<>
<Hide below="lg" ssr={ false }>
<Box hideBelow="lg">
<AddressesLabelSearchTable
top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }
items={ data.items }
isLoading={ isPlaceholderData }
/>
</Hide>
<Show below="lg" ssr={ false }>
</Box>
<Box hideFrom="lg">
{ data.items.map((item, index) => {
return (
<AddressesLabelSearchListItem
......@@ -60,7 +60,7 @@ const AccountsLabelSearch = () => {
/>
);
}) }
</Show>
</Box>
</>
) : null;
......@@ -80,10 +80,7 @@ const AccountsLabelSearch = () => {
return (
<Flex alignItems="center" columnGap={ 2 } flexWrap="wrap" rowGap={ 1 }>
<Skeleton
isLoaded={ !isPlaceholderData }
display="inline-block"
>
<Skeleton loading={ isPlaceholderData } display="inline-block">
Found{ ' ' }
<chakra.span fontWeight={ 700 }>
{ num }{ data?.next_page_params || pagination.page > 1 ? '+' : '' }
......@@ -102,11 +99,12 @@ const AccountsLabelSearch = () => {
<PageTitle title="Search result" withTextAd/>
<DataListDisplay
isError={ isError }
items={ data?.items }
itemsNum={ data?.items.length }
emptyText={ text }
content={ content }
actionBar={ actionBar }
/>
>
{ content }
</DataListDisplay>
</>
);
};
......
import { Box, Hide, HStack, Show } from '@chakra-ui/react';
import { Box, createListCollection, HStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -27,12 +27,16 @@ import VerifiedContractsFilter from 'ui/verifiedContracts/VerifiedContractsFilte
import VerifiedContractsList from 'ui/verifiedContracts/VerifiedContractsList';
import VerifiedContractsTable from 'ui/verifiedContracts/VerifiedContractsTable';
const sortCollection = createListCollection({
items: SORT_OPTIONS,
});
const VerifiedContracts = () => {
const router = useRouter();
const [ searchTerm, setSearchTerm ] = React.useState(getQueryParamString(router.query.q) || undefined);
const [ type, setType ] = React.useState(getQueryParamString(router.query.filter) as VerifiedContractsFilters['filter'] || undefined);
const [ sort, setSort ] =
React.useState<VerifiedContractsSortingValue | undefined>(getSortValueFromQuery<VerifiedContractsSortingValue>(router.query, SORT_OPTIONS));
React.useState<VerifiedContractsSortingValue>(getSortValueFromQuery<VerifiedContractsSortingValue>(router.query, SORT_OPTIONS) ?? 'default');
const debouncedSearchTerm = useDebounce(searchTerm || '', 300);
......@@ -72,9 +76,9 @@ const VerifiedContracts = () => {
setType(filter);
}, [ debouncedSearchTerm, onFilterChange ]);
const handleSortChange = React.useCallback((value?: VerifiedContractsSortingValue) => {
setSort(value);
onSortingChange(getSortParamsFromValue(value));
const handleSortChange = React.useCallback(({ value }: { value: Array<string> }) => {
setSort(value[0] as VerifiedContractsSortingValue);
onSortingChange(value[0] === 'default' ? undefined : getSortParamsFromValue(value[0] as VerifiedContractsSortingValue));
}, [ onSortingChange ]);
const typeFilter = (
......@@ -88,7 +92,7 @@ const VerifiedContracts = () => {
const filterInput = (
<FilterInput
w={{ base: '100%', lg: '350px' }}
size="xs"
size="sm"
onChange={ handleSearchTermChange }
placeholder="Search by contract name or address"
initialValue={ searchTerm }
......@@ -98,23 +102,23 @@ const VerifiedContracts = () => {
const sortButton = (
<Sort
name="verified_contracts_sorting"
defaultValue={ sort }
options={ SORT_OPTIONS }
onChange={ handleSortChange }
defaultValue={ [ sort ] }
collection={ sortCollection }
onValueChange={ handleSortChange }
isLoading={ isPlaceholderData }
/>
);
const actionBar = (
<>
<HStack spacing={ 3 } mb={ 6 } display={{ base: 'flex', lg: 'none' }}>
<HStack gap={ 3 } mb={ 6 } display={{ base: 'flex', lg: 'none' }}>
{ typeFilter }
{ sortButton }
{ filterInput }
</HStack>
{ (!isMobile || pagination.isVisible) && (
<ActionBar mt={ -6 }>
<HStack spacing={ 3 } display={{ base: 'none', lg: 'flex' }}>
<HStack gap={ 3 } display={{ base: 'none', lg: 'flex' }}>
{ typeFilter }
{ filterInput }
</HStack>
......@@ -126,12 +130,12 @@ const VerifiedContracts = () => {
const content = data?.items ? (
<>
<Show below="lg" ssr={ false }>
<Box hideFrom="lg">
<VerifiedContractsList data={ data.items } isLoading={ isPlaceholderData }/>
</Show>
<Hide below="lg" ssr={ false }>
</Box>
<Box hideBelow="lg">
<VerifiedContractsTable data={ data.items } sort={ sort } setSorting={ handleSortChange } isLoading={ isPlaceholderData }/>
</Hide>
</Box>
</>
) : null;
......@@ -144,15 +148,16 @@ const VerifiedContracts = () => {
<VerifiedContractsCounters/>
<DataListDisplay
isError={ isError }
items={ data?.items }
itemsNum={ data?.items.length }
emptyText="There are no verified contracts."
filterProps={{
emptyFilteredText: `Couldn${ apos }t find any contract that matches your query.`,
hasActiveFilters: Boolean(searchTerm || type),
}}
content={ content }
actionBar={ actionBar }
/>
>
{ content }
</DataListDisplay>
</Box>
);
};
......
import { createListCollection } from '@chakra-ui/react';
import React from 'react';
import type { VerifiedContractsFilter as TVerifiedContractsFilter } from 'types/api/contracts';
......@@ -15,6 +16,10 @@ const OPTIONS = [
{ value: 'scilla', label: 'Scilla' },
].filter(({ value }) => value === 'all' || config.UI.views.address.languageFilters.includes(value)) as Array<{ value: OptionValue; label: string }>;
const collection = createListCollection({
items: OPTIONS,
});
interface Props {
hasActiveFilter: boolean;
defaultValue: TVerifiedContractsFilter | undefined;
......@@ -25,10 +30,10 @@ const VerifiedContractsFilter = ({ onChange, defaultValue, hasActiveFilter }: Pr
return (
<PopoverFilterRadio
name="verified_contracts_filter"
options={ OPTIONS }
collection={ collection }
onChange={ onChange }
hasActiveFilter={ hasActiveFilter }
defaultValue={ defaultValue || OPTIONS[0].value }
initialValue={ defaultValue || OPTIONS[0].value }
/>
);
};
......
......@@ -8,7 +8,7 @@ import config from 'configs/app';
import formatLanguageName from 'lib/contracts/formatLanguageName';
import { CONTRACT_LICENSES } from 'lib/contracts/licenses';
import { currencyUnits } from 'lib/units';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Skeleton } from 'toolkit/chakra/skeleton';
import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import IconSvg from 'ui/shared/IconSvg';
......@@ -53,63 +53,63 @@ const VerifiedContractsListItem = ({ data, isLoading }: Props) => {
noIcon
truncation="constant"
ml="auto"
color="text_secondary"
color="text.secondary"
flexShrink={ 0 }
/>
</Flex>
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Balance { currencyUnits.ether }</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary">
<Skeleton loading={ isLoading } fontWeight={ 500 }>Balance { currencyUnits.ether }</Skeleton>
<Skeleton loading={ isLoading } color="text.secondary">
<span>{ balance }</span>
</Skeleton>
</Flex>
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Txs count</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary">
<Skeleton loading={ isLoading } fontWeight={ 500 }>Txs count</Skeleton>
<Skeleton loading={ isLoading } color="text.secondary">
<span>{ data.transaction_count ? data.transaction_count.toLocaleString() : '0' }</span>
</Skeleton>
</Flex>
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 } flexShrink="0">Language</Skeleton>
<Skeleton isLoaded={ !isLoading } display="flex" flexWrap="wrap">
<Skeleton loading={ isLoading } fontWeight={ 500 } flexShrink="0">Language</Skeleton>
<Skeleton loading={ isLoading } display="flex" flexWrap="wrap">
<Box>{ formatLanguageName(data.language) }</Box>
<Box color="text_secondary" wordBreak="break-all" whiteSpace="pre-wrap"> ({ data.compiler_version })</Box>
<Box color="text.secondary" wordBreak="break-all" whiteSpace="pre-wrap"> ({ data.compiler_version })</Box>
</Skeleton>
</Flex>
{ data.zk_compiler_version && (
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 } flexShrink="0">ZK compiler</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary" wordBreak="break-all" whiteSpace="pre-wrap">
<Skeleton loading={ isLoading } fontWeight={ 500 } flexShrink="0">ZK compiler</Skeleton>
<Skeleton loading={ isLoading } color="text.secondary" wordBreak="break-all" whiteSpace="pre-wrap">
{ data.zk_compiler_version }
</Skeleton>
</Flex>
) }
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Optimization</Skeleton>
<Skeleton loading={ isLoading } fontWeight={ 500 }>Optimization</Skeleton>
{ data.optimization_enabled ?
<IconSvg name="check" boxSize={ 6 } color="green.500" cursor="pointer" isLoading={ isLoading }/> :
<IconSvg name="cross" boxSize={ 6 } color="red.600" cursor="pointer" isLoading={ isLoading }/> }
</Flex>
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Constructor args</Skeleton>
<Skeleton loading={ isLoading } fontWeight={ 500 }>Constructor args</Skeleton>
{ data.has_constructor_args ?
<IconSvg name="check" boxSize={ 6 } color="green.500" cursor="pointer" isLoading={ isLoading }/> :
<IconSvg name="cross" boxSize={ 6 } color="red.600" cursor="pointer" isLoading={ isLoading }/> }
</Flex>
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Verified</Skeleton>
<Skeleton loading={ isLoading } fontWeight={ 500 }>Verified</Skeleton>
<Flex alignItems="center" columnGap={ 2 }>
<IconSvg name="status/success" boxSize={ 4 } color="green.500" isLoading={ isLoading }/>
<TimeAgoWithTooltip
timestamp={ data.verified_at }
isLoading={ isLoading }
color="text_secondary"
color="text.secondary"
/>
</Flex>
</Flex>
<Flex columnGap={ 3 }>
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>License</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary">
<Skeleton loading={ isLoading } fontWeight={ 500 }>License</Skeleton>
<Skeleton loading={ isLoading } color="text.secondary">
<span>{ license }</span>
</Skeleton>
</Flex>
......
import { Table, Tbody, Tr, Th, Link } from '@chakra-ui/react';
import React from 'react';
import type { VerifiedContract } from 'types/api/contracts';
import type { VerifiedContractsSorting, VerifiedContractsSortingField, VerifiedContractsSortingValue } from 'types/api/verifiedContracts';
import { currencyUnits } from 'lib/units';
import { Link } from 'toolkit/chakra/link';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import IconSvg from 'ui/shared/IconSvg';
import getNextSortValue from 'ui/shared/sort/getNextSortValue';
import { default as Thead } from 'ui/shared/TheadSticky';
import { SORT_SEQUENCE } from 'ui/verifiedContracts/utils';
import VerifiedContractsTableItem from './VerifiedContractsTableItem';
interface Props {
data: Array<VerifiedContract>;
sort: VerifiedContractsSortingValue | undefined;
setSorting: (val: VerifiedContractsSortingValue | undefined) => void;
sort: VerifiedContractsSortingValue;
setSorting: ({ value }: { value: Array<string> }) => void;
isLoading?: boolean;
}
......@@ -25,21 +25,21 @@ const VerifiedContractsTable = ({ data, sort, setSorting, isLoading }: Props) =>
const onSortToggle = React.useCallback((field: VerifiedContractsSortingField) => () => {
const value = getNextSortValue<VerifiedContractsSortingField, VerifiedContractsSortingValue>(SORT_SEQUENCE, field)(sort);
setSorting(value);
setSorting({ value: [ value ] });
}, [ sort, setSorting ]);
return (
<Table minW="915px">
<Thead top={ ACTION_BAR_HEIGHT_DESKTOP }>
<Tr>
<Th width="50%">Contract</Th>
<Th width="130px" isNumeric>
<TableRoot>
<TableHeaderSticky top={ ACTION_BAR_HEIGHT_DESKTOP }>
<TableRow>
<TableColumnHeader width="50%">Contract</TableColumnHeader>
<TableColumnHeader width="130px" isNumeric>
<Link display="flex" alignItems="center" justifyContent="flex-end" onClick={ isLoading ? undefined : onSortToggle('balance') } columnGap={ 1 }>
{ sort?.includes('balance') && <IconSvg name="arrows/east" boxSize={ 4 } transform={ sortIconTransform }/> }
Balance { currencyUnits.ether }
</Link>
</Th>
<Th width="130px" isNumeric>
</TableColumnHeader>
<TableColumnHeader width="130px" isNumeric>
<Link
display="flex"
alignItems="center"
......@@ -50,22 +50,22 @@ const VerifiedContractsTable = ({ data, sort, setSorting, isLoading }: Props) =>
{ sort?.includes('transactions_count') && <IconSvg name="arrows/east" boxSize={ 4 } transform={ sortIconTransform }/> }
Txs
</Link>
</Th>
<Th width="50%">Language / Compiler version</Th>
<Th width="80px">Settings</Th>
<Th width="150px">Verified</Th>
<Th width="130px">License</Th>
</Tr>
</Thead>
<Tbody>
</TableColumnHeader>
<TableColumnHeader width="50%">Language / Compiler version</TableColumnHeader>
<TableColumnHeader width="80px">Settings</TableColumnHeader>
<TableColumnHeader width="150px">Verified</TableColumnHeader>
<TableColumnHeader width="130px">License</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ data.map((item, index) => (
<VerifiedContractsTableItem
key={ item.address.hash + (isLoading ? index : '') }
data={ item }
isLoading={ isLoading }/>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
);
};
......
import { Tr, Td, Flex, chakra, Tooltip } from '@chakra-ui/react';
import { Flex, chakra } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
......@@ -7,7 +7,9 @@ import type { VerifiedContract } from 'types/api/contracts';
import config from 'configs/app';
import formatLanguageName from 'lib/contracts/formatLanguageName';
import { CONTRACT_LICENSES } from 'lib/contracts/licenses';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import { Tooltip } from 'toolkit/chakra/tooltip';
import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import IconSvg from 'ui/shared/IconSvg';
......@@ -33,8 +35,8 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => {
})();
return (
<Tr>
<Td>
<TableRow>
<TableCell>
<Flex alignItems="center" mt={ 1 }>
<AddressEntity
address={ data.address }
......@@ -52,25 +54,26 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => {
truncation="constant"
my={ 1 }
ml={ 7 }
color="text_secondary"
color="text.secondary"
w="fit-content"
/>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" my={ 1 }>
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" my={ 1 }>
{ balance }
</Skeleton>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" my={ 1 }>
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" my={ 1 }>
{ data.transaction_count ? data.transaction_count.toLocaleString() : '0' }
</Skeleton>
</Td>
<Td>
</TableCell>
<TableCell>
<Flex flexWrap="wrap" columnGap={ 2 }>
<Skeleton isLoaded={ !isLoading } my={ 1 }>{ formatLanguageName(data.language) }</Skeleton>
<Skeleton loading={ isLoading } my={ 1 }>{ formatLanguageName(data.language) }</Skeleton>
{ data.compiler_version && (
<Skeleton isLoaded={ !isLoading } color="text_secondary" wordBreak="break-all" my={ 1 } cursor="pointer">
<Tooltip label={ data.compiler_version }>
<Skeleton loading={ isLoading } color="text.secondary" wordBreak="break-all" my={ 1 } cursor="pointer">
<Tooltip content={ data.compiler_version }>
<span>{ data.compiler_version.split('+')[0] }</span>
</Tooltip>
</Skeleton>
......@@ -78,45 +81,45 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => {
</Flex>
{ data.zk_compiler_version && (
<Flex flexWrap="wrap" columnGap={ 2 } my={ 1 }>
<Skeleton isLoaded={ !isLoading } >ZK compiler</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary" wordBreak="break-all">
<Skeleton loading={ isLoading } >ZK compiler</Skeleton>
<Skeleton loading={ isLoading } color="text.secondary" wordBreak="break-all">
<span>{ data.zk_compiler_version }</span>
</Skeleton>
</Flex>
) }
</Td>
<Td>
<Tooltip label={ isLoading ? undefined : 'Optimization' }>
</TableCell>
<TableCell>
<Tooltip content="Optimization" disabled={ isLoading }>
<chakra.span display="inline-block">
{ data.optimization_enabled ?
<IconSvg name="check" boxSize={ 6 } color="green.500" cursor="pointer" isLoading={ isLoading }/> :
<IconSvg name="cross" boxSize={ 6 } color="red.600" cursor="pointer" isLoading={ isLoading }/> }
</chakra.span>
</Tooltip>
<Tooltip label={ isLoading ? undefined : 'Constructor args' }>
<Tooltip content="Constructor args" disabled={ isLoading }>
<chakra.span display="inline-block" ml={ 2 }>
{ data.has_constructor_args ?
<IconSvg name="check" boxSize={ 6 } color="green.500" cursor="pointer" isLoading={ isLoading }/> :
<IconSvg name="cross" boxSize={ 6 } color="red.600" cursor="pointer" isLoading={ isLoading }/> }
</chakra.span>
</Tooltip>
</Td>
<Td>
</TableCell>
<TableCell>
<Flex alignItems="center" columnGap={ 2 } my={ 1 }>
<IconSvg name="status/success" boxSize={ 4 } color="green.500" isLoading={ isLoading }/>
<TimeAgoWithTooltip
timestamp={ data.verified_at }
isLoading={ isLoading }
color="text_secondary"
color="text.secondary"
/>
</Flex>
</Td>
<Td>
<Skeleton isLoaded={ !isLoading } my={ 1 } display="inline-block">
</TableCell>
<TableCell>
<Skeleton loading={ isLoading } my={ 1 } display="inline-block">
{ license }
</Skeleton>
</Td>
</Tr>
</TableCell>
</TableRow>
);
};
......
import type { VerifiedContractsSortingValue, VerifiedContractsSortingField } from 'types/api/verifiedContracts';
import type { SelectOption } from 'toolkit/chakra/select';
export const SORT_OPTIONS: Array<SelectOption<VerifiedContractsSortingValue>> = [
{ label: 'Default', value: undefined },
{ label: 'Default', value: 'default' },
{ label: 'Balance descending', value: 'balance-desc' },
{ label: 'Balance ascending', value: 'balance-asc' },
{ label: 'Txs count descending', value: 'transactions_count-desc' },
{ label: 'Txs count ascending', value: 'transactions_count-asc' },
];
export const SORT_SEQUENCE: Record<VerifiedContractsSortingField, Array<VerifiedContractsSortingValue | undefined>> = {
balance: [ 'balance-desc', 'balance-asc', undefined ],
transactions_count: [ 'transactions_count-desc', 'transactions_count-asc', undefined ],
export const SORT_SEQUENCE: Record<VerifiedContractsSortingField, Array<VerifiedContractsSortingValue>> = {
balance: [ 'balance-desc', 'balance-asc', 'default' ],
transactions_count: [ 'transactions_count-desc', 'transactions_count-asc', 'default' ],
};
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