Commit 64b466b6 authored by isstuev's avatar isstuev

search redesign

parent ebd5aa67
...@@ -7,6 +7,8 @@ import relativeTime from 'dayjs/plugin/relativeTime'; ...@@ -7,6 +7,8 @@ import relativeTime from 'dayjs/plugin/relativeTime';
import updateLocale from 'dayjs/plugin/updateLocale'; import updateLocale from 'dayjs/plugin/updateLocale';
import weekOfYear from 'dayjs/plugin/weekOfYear'; import weekOfYear from 'dayjs/plugin/weekOfYear';
import { nbsp } from 'lib/html-entities';
const relativeTimeConfig = { const relativeTimeConfig = {
thresholds: [ thresholds: [
{ l: 's', r: 1 }, { l: 's', r: 1 },
...@@ -33,7 +35,7 @@ dayjs.extend(minMax); ...@@ -33,7 +35,7 @@ dayjs.extend(minMax);
dayjs.updateLocale('en', { dayjs.updateLocale('en', {
formats: { formats: {
LLLL: 'MMMM-DD-YYYY HH:mm:ss A Z UTC', llll: `MMM DD YYYY HH:mm:ss A (Z${ nbsp }UTC)`,
}, },
relativeTime: { relativeTime: {
s: 'a sec', s: 'a sec',
......
...@@ -187,7 +187,7 @@ const ContractCode = ({ addressHash, noSocket }: Props) => { ...@@ -187,7 +187,7 @@ const ContractCode = ({ addressHash, noSocket }: Props) => {
<InfoItem label="Optimization enabled" value={ data.optimization_enabled ? 'true' : 'false' } isLoading={ isPlaceholderData }/> } <InfoItem label="Optimization enabled" value={ data.optimization_enabled ? 'true' : 'false' } isLoading={ isPlaceholderData }/> }
{ data.optimization_runs && <InfoItem label="Optimization runs" value={ String(data.optimization_runs) } isLoading={ isPlaceholderData }/> } { data.optimization_runs && <InfoItem label="Optimization runs" value={ String(data.optimization_runs) } isLoading={ isPlaceholderData }/> }
{ data.verified_at && { data.verified_at &&
<InfoItem label="Verified at" value={ dayjs(data.verified_at).format('LLLL') } wordBreak="break-word" isLoading={ isPlaceholderData }/> } <InfoItem label="Verified at" value={ dayjs(data.verified_at).format('llll') } wordBreak="break-word" isLoading={ isPlaceholderData }/> }
{ data.file_path && <InfoItem label="Contract file path" value={ data.file_path } wordBreak="break-word" isLoading={ isPlaceholderData }/> } { data.file_path && <InfoItem label="Contract file path" value={ data.file_path } wordBreak="break-word" isLoading={ isPlaceholderData }/> }
</Grid> </Grid>
) } ) }
......
...@@ -166,7 +166,7 @@ const BlockDetails = ({ query }: Props) => { ...@@ -166,7 +166,7 @@ const BlockDetails = ({ query }: Props) => {
</Skeleton> </Skeleton>
<TextSeparator/> <TextSeparator/>
<Skeleton isLoaded={ !isPlaceholderData } whiteSpace="normal"> <Skeleton isLoaded={ !isPlaceholderData } whiteSpace="normal">
{ dayjs(data.timestamp).format('LLLL') } { dayjs(data.timestamp).format('llll') }
</Skeleton> </Skeleton>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
......
...@@ -54,7 +54,7 @@ const IndexingAlertIntTxs = ({ className }: { className?: string }) => { ...@@ -54,7 +54,7 @@ const IndexingAlertIntTxs = ({ className }: { className?: string }) => {
<Text fontSize="xs" color={ hintTextcolor }> <Text fontSize="xs" color={ hintTextcolor }>
{ data.indexed_internal_transactions_ratio && { data.indexed_internal_transactions_ratio &&
`${ Math.floor(Number(data.indexed_internal_transactions_ratio) * 100) }% Blocks With Internal Transactions Indexed${ nbsp }${ ndash } ` } `${ Math.floor(Number(data.indexed_internal_transactions_ratio) * 100) }% Blocks With Internal Transactions Indexed${ nbsp }${ ndash } ` }
We{ apos }re indexing this chain right now. Some of the counts may be inaccurate.` We{ apos }re indexing this chain right now. Some of the counts may be inaccurate.
</Text> </Text>
); );
......
...@@ -15,39 +15,6 @@ import Pagination from 'ui/shared/pagination/Pagination'; ...@@ -15,39 +15,6 @@ import Pagination from 'ui/shared/pagination/Pagination';
import Thead from 'ui/shared/TheadSticky'; import Thead from 'ui/shared/TheadSticky';
import Header from 'ui/snippets/header/Header'; import Header from 'ui/snippets/header/Header';
import useSearchQuery from 'ui/snippets/searchBar/useSearchQuery'; import useSearchQuery from 'ui/snippets/searchBar/useSearchQuery';
// eslint-disable-next-line import-helpers/order-imports
import * as searchMock from 'mocks/search/index';
const mock = [
searchMock.address1,
searchMock.block1,
searchMock.contract1,
searchMock.label1,
searchMock.token1,
searchMock.token2,
searchMock.tx1,
searchMock.address1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.contract1,
searchMock.label1,
searchMock.token1,
searchMock.token2,
searchMock.tx1,
searchMock.address1,
searchMock.block1,
searchMock.contract1,
searchMock.label1,
searchMock.token1,
searchMock.token2,
];
const SearchResultsPageContent = () => { const SearchResultsPageContent = () => {
const router = useRouter(); const router = useRouter();
...@@ -101,8 +68,7 @@ const SearchResultsPageContent = () => { ...@@ -101,8 +68,7 @@ const SearchResultsPageContent = () => {
return ( return (
<> <>
<Show below="lg" ssr={ false }> <Show below="lg" ssr={ false }>
{ mock.map((item, index) => ( { data.items.map((item, index) => (
// { data.items.map((item, index) => (
<SearchResultListItem <SearchResultListItem
key={ (isPlaceholderData ? 'placeholder_' : 'actual_') + index } key={ (isPlaceholderData ? 'placeholder_' : 'actual_') + index }
data={ item } data={ item }
...@@ -117,13 +83,12 @@ const SearchResultsPageContent = () => { ...@@ -117,13 +83,12 @@ const SearchResultsPageContent = () => {
<Tr> <Tr>
<Th width="30%">Search Result</Th> <Th width="30%">Search Result</Th>
<Th width="35%"/> <Th width="35%"/>
<Th width="35%"/> <Th width="35%" pr={ 10 }/>
<Th width="150px">Category</Th> <Th width="150px">Category</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
{ /* { data.items.map((item, index) => ( */ } { data.items.map((item, index) => (
{ mock.map((item, index) => (
<SearchResultTableItem <SearchResultTableItem
key={ (isPlaceholderData ? 'placeholder_' : 'actual_') + index } key={ (isPlaceholderData ? 'placeholder_' : 'actual_') + index }
data={ item } data={ item }
......
...@@ -15,10 +15,10 @@ import { saveToRecentKeywords } from 'lib/recentSearchKeywords'; ...@@ -15,10 +15,10 @@ import { saveToRecentKeywords } from 'lib/recentSearchKeywords';
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 HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import { getItemCategory, searchItemTitles } from 'ui/shared/search/utils';
import TokenLogo from 'ui/shared/TokenLogo'; import TokenLogo from 'ui/shared/TokenLogo';
interface Props { interface Props {
...@@ -89,7 +89,6 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -89,7 +89,6 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
<Flex alignItems="flex-start"> <Flex alignItems="flex-start">
<Icon as={ labelIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/> <Icon as={ labelIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/>
<LinkInternal <LinkInternal
ml={ 2 }
href={ route({ pathname: '/address/[hash]', query: { hash: data.address } }) } href={ route({ pathname: '/address/[hash]', query: { hash: data.address } }) }
fontWeight={ 700 } fontWeight={ 700 }
wordBreak="break-all" wordBreak="break-all"
...@@ -138,32 +137,25 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -138,32 +137,25 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
return ( return (
<Grid templateColumns="1fr auto" overflow="hidden" gap={ 5 }> <Grid templateColumns="1fr auto" overflow="hidden" gap={ 5 }>
<Skeleton isLoaded={ !isLoading } overflow="hidden" display="flex" alignItems="center"> <Skeleton isLoaded={ !isLoading } overflow="hidden" display="flex" alignItems="center">
<HashStringShorten hash={ data.address }/> <HashStringShortenDynamic hash={ data.address }/>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> } { data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Skeleton> </Skeleton>
{ data.token_type === 'ERC-20' && data.exchange_rate && ( <Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" fontWeight={ 700 }>
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" fontWeight={ 700 }> { data.token_type === 'ERC-20' && data.exchange_rate && `$${ Number(data.exchange_rate).toLocaleString() }` }
${ Number(data.exchange_rate).toLocaleString() } { data.token_type !== 'ERC-20' && data.total_supply && `Items ${ Number(data.total_supply).toLocaleString() }` }
</Text> </Text>
) }
{ data.token_type !== 'ERC-20' && data.total_supply && (
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" variant="secondary">
Items { Number(data.total_supply).toLocaleString() }
</Text>
) }
</Grid> </Grid>
); );
} }
case 'block': { case 'block': {
const shouldHighlightHash = data.block_hash.toLowerCase() === searchTerm.toLowerCase(); const shouldHighlightHash = data.block_hash.toLowerCase() === searchTerm.toLowerCase();
return ( return (
<Flex alignItems="center" justifyContent="space-between" w="100%"> <>
<Text variant="secondary" mr={ 2 }>{ dayjs(data.timestamp).format('llll') }</Text> <Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block" whiteSpace="nowrap" overflow="hidden" mb={ 1 }>
<Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block" whiteSpace="nowrap" overflow="hidden"> <HashStringShortenDynamic hash={ data.block_hash }/>
<HashStringShorten hash={ data.block_hash }/>
</Box> </Box>
</Flex> <Text variant="secondary" mr={ 2 }>{ dayjs(data.timestamp).format('llll') }</Text>
</>
); );
} }
case 'transaction': { case 'transaction': {
...@@ -192,12 +184,14 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -192,12 +184,14 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
} }
})(); })();
const category = getItemCategory(data);
return ( return (
<ListItemMobile py={ 3 } fontSize="sm" rowGap={ 2 }> <ListItemMobile py={ 3 } fontSize="sm" rowGap={ 2 }>
<Flex justifyContent="space-between" w="100%" overflow="hidden" lineHeight={ 6 }> <Flex justifyContent="space-between" w="100%" overflow="hidden" lineHeight={ 6 }>
{ firstRow } { firstRow }
<Skeleton isLoaded={ !isLoading } color="text_secondary" ml={ 8 } textTransform="capitalize"> <Skeleton isLoaded={ !isLoading } color="text_secondary" ml={ 8 } textTransform="capitalize">
<span>{ data.type }</span> <span>{ category ? searchItemTitles[category].itemTitleShort : '' }</span>
</Skeleton> </Skeleton>
</Flex> </Flex>
{ Boolean(secondRow) && ( { Boolean(secondRow) && (
......
...@@ -17,6 +17,7 @@ import AddressIcon from 'ui/shared/address/AddressIcon'; ...@@ -17,6 +17,7 @@ import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
import { getItemCategory, searchItemTitles } from 'ui/shared/search/utils';
import TokenLogo from 'ui/shared/TokenLogo'; import TokenLogo from 'ui/shared/TokenLogo';
interface Props { interface Props {
...@@ -66,25 +67,19 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -66,25 +67,19 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
</Flex> </Flex>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } whiteSpace="nowrap" overflow="hidden" display="flex" alignItems="center"> <Skeleton isLoaded={ !isLoading } whiteSpace="nowrap" overflow="hidden" display="flex" alignItems="center" justifyContent="space-between">
<Box overflow="hidden" whiteSpace="nowrap" w={ data.is_smart_contract_verified ? 'calc(100%-32px)' : 'unset' }> <Box overflow="hidden" whiteSpace="nowrap" w={ data.is_smart_contract_verified ? 'calc(100%-32px)' : 'unset' }>
<HashStringShortenDynamic hash={ data.address }/> <HashStringShortenDynamic hash={ data.address }/>
</Box> </Box>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> } { data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Skeleton> </Skeleton>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle" isNumeric>
<Skeleton isLoaded={ !isLoading } whiteSpace="nowrap" overflow="hidden"> <Skeleton isLoaded={ !isLoading } whiteSpace="nowrap" overflow="hidden">
{ data.token_type === 'ERC-20' && data.exchange_rate && ( <Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" fontWeight={ 700 }>
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" fontWeight={ 700 }> { data.token_type === 'ERC-20' && data.exchange_rate && `$${ Number(data.exchange_rate).toLocaleString() }` }
${ Number(data.exchange_rate).toLocaleString() } { data.token_type !== 'ERC-20' && data.total_supply && `Items ${ Number(data.total_supply).toLocaleString() }` }
</Text> </Text>
) }
{ data.token_type !== 'ERC-20' && data.total_supply && (
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis" variant="secondary">
Items { Number(data.total_supply).toLocaleString() }
</Text>
) }
</Skeleton> </Skeleton>
</Td> </Td>
</> </>
...@@ -154,12 +149,15 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -154,12 +149,15 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
</LinkInternal> </LinkInternal>
</Flex> </Flex>
</Td> </Td>
<Td colSpan={ 2 } fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle">
<Flex alignItems="center" overflow="hidden"> <Flex alignItems="center" overflow="hidden" justifyContent="space-between">
<HashStringShortenDynamic hash={ data.address }/> <Box overflow="hidden" whiteSpace="nowrap" w={ data.is_smart_contract_verified ? 'calc(100%-32px)' : 'unset' }>
<HashStringShortenDynamic hash={ data.address }/>
</Box>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> } { data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Flex> </Flex>
</Td> </Td>
<Td></Td>
</> </>
); );
} }
...@@ -186,7 +184,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -186,7 +184,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
<HashStringShortenDynamic hash={ data.block_hash }/> <HashStringShortenDynamic hash={ data.block_hash }/>
</Box> </Box>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle" isNumeric>
<Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text> <Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text>
</Td> </Td>
</> </>
...@@ -204,7 +202,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -204,7 +202,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
</chakra.mark> </chakra.mark>
</Flex> </Flex>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle" isNumeric>
<Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text> <Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text>
</Td> </Td>
</> </>
...@@ -213,12 +211,14 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => { ...@@ -213,12 +211,14 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
} }
})(); })();
const category = getItemCategory(data);
return ( return (
<Tr> <Tr>
{ content } { content }
<Td fontSize="sm" textTransform="capitalize" verticalAlign="middle"> <Td fontSize="sm" textTransform="capitalize" verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"> <Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block">
<span>{ data.type }</span> <span>{ category ? searchItemTitles[category].itemTitle : '' }</span>
</Skeleton> </Skeleton>
</Td> </Td>
</Tr> </Tr>
......
import type { SearchResultItem } from 'types/api/search';
export type Category = 'token' | 'nft' | 'address' | 'app' | 'public_tag' | 'transaction' | 'block';
export const searchCategories: Array<{id: Category; title: string }> = [
{ id: 'token', title: 'Tokens (ERC-20)' },
{ id: 'nft', title: 'NFTs (ERC-721 & 1155)' },
{ id: 'address', title: 'Addresses' },
{ id: 'app', title: 'Apps' },
{ id: 'public_tag', title: 'Public tags' },
{ id: 'transaction', title: 'Transactions' },
{ id: 'block', title: 'Blocks' },
];
export const searchItemTitles: Record<Category, { itemTitle: string; itemTitleShort: string }> = {
token: { itemTitle: 'Token', itemTitleShort: 'Token' },
nft: { itemTitle: 'NFT', itemTitleShort: 'NFT' },
address: { itemTitle: 'Address', itemTitleShort: 'Address' },
app: { itemTitle: 'App', itemTitleShort: 'App' },
public_tag: { itemTitle: 'Public tag', itemTitleShort: 'Tag' },
transaction: { itemTitle: 'Transaction', itemTitleShort: 'Txn' },
block: { itemTitle: 'Block', itemTitleShort: 'Block' },
};
export function getItemCategory(item: SearchResultItem): Category | undefined {
switch (item.type) {
case 'address':
case 'contract': {
return 'address';
}
case 'token': {
if (item.token_type === 'ERC-20') {
return 'token';
}
return 'nft';
}
case 'block': {
return 'block';
}
case 'label': {
return 'public_tag';
}
case 'transaction': {
return 'transaction';
}
}
}
...@@ -9,45 +9,11 @@ import useIsMobile from 'lib/hooks/useIsMobile'; ...@@ -9,45 +9,11 @@ import useIsMobile from 'lib/hooks/useIsMobile';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import type { QueryWithPagesResult } from 'ui/shared/pagination/useQueryWithPages'; import type { QueryWithPagesResult } from 'ui/shared/pagination/useQueryWithPages';
import type { Category } from 'ui/shared/search/utils';
import { getItemCategory, searchCategories } from 'ui/shared/search/utils';
import SearchBarSuggestItem from './SearchBarSuggestItem'; import SearchBarSuggestItem from './SearchBarSuggestItem';
type Category = 'token' | 'nft' | 'address' | 'app' | 'public_tag' | 'transaction' | 'block';
const CATEGORIES: Array<{id: Category; title: string }> = [
{ id: 'token', title: 'Tokens (ERC-20)' },
{ id: 'nft', title: 'NFTs (ERC-721 & ERC-1155)' },
{ id: 'address', title: 'Addresses' },
{ id: 'app', title: 'Apps' },
{ id: 'public_tag', title: 'Public tags' },
{ id: 'transaction', title: 'Transactions' },
{ id: 'block', title: 'Blocks' },
];
const getItemCategory = (item: SearchResultItem): Category | undefined => {
switch (item.type) {
case 'address':
case 'contract': {
return 'address';
}
case 'token': {
if (item.token_type === 'ERC-20') {
return 'token';
}
return 'nft';
}
case 'block': {
return 'block';
}
case 'label': {
return 'public_tag';
}
case 'transaction': {
return 'transaction';
}
}
};
interface Props { interface Props {
query: QueryWithPagesResult<'search'>; query: QueryWithPagesResult<'search'>;
searchTerm: string; searchTerm: string;
...@@ -55,40 +21,6 @@ interface Props { ...@@ -55,40 +21,6 @@ interface Props {
containerId: string; containerId: string;
} }
// eslint-disable-next-line import-helpers/order-imports
import * as searchMock from 'mocks/search/index';
const mock = [
searchMock.address1,
searchMock.block1,
searchMock.contract1,
searchMock.label1,
searchMock.token1,
searchMock.token2,
searchMock.tx1,
searchMock.address1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.block1,
searchMock.contract1,
searchMock.label1,
searchMock.token1,
searchMock.token2,
searchMock.tx1,
searchMock.address1,
searchMock.block1,
searchMock.contract1,
searchMock.label1,
searchMock.token1,
searchMock.token2,
];
const SearchBarSuggest = ({ query, searchTerm, onItemClick, containerId }: Props) => { const SearchBarSuggest = ({ query, searchTerm, onItemClick, containerId }: Props) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
...@@ -133,8 +65,7 @@ const SearchBarSuggest = ({ query, searchTerm, onItemClick, containerId }: Props ...@@ -133,8 +65,7 @@ const SearchBarSuggest = ({ query, searchTerm, onItemClick, containerId }: Props
return {}; return {};
} }
const map: Partial<Record<Category, Array<SearchResultItem>>> = {}; const map: Partial<Record<Category, Array<SearchResultItem>>> = {};
// query.data?.items.forEach(item => { query.data?.items.forEach(item => {
mock.forEach(item => {
const cat = getItemCategory(item); const cat = getItemCategory(item);
if (cat) { if (cat) {
if (cat in map) { if (cat in map) {
...@@ -168,7 +99,7 @@ const SearchBarSuggest = ({ query, searchTerm, onItemClick, containerId }: Props ...@@ -168,7 +99,7 @@ const SearchBarSuggest = ({ query, searchTerm, onItemClick, containerId }: Props
return <Text>Something went wrong. Try refreshing the page or come back later.</Text>; return <Text>Something went wrong. Try refreshing the page or come back later.</Text>;
} }
const resultCategories = CATEGORIES.filter(cat => itemsGroups[cat.id]); const resultCategories = searchCategories.filter(cat => itemsGroups[cat.id]);
return ( return (
<> <>
......
...@@ -27,45 +27,29 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm }: Props) => { ...@@ -27,45 +27,29 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm }: Props) => {
flexShrink={ 0 } flexShrink={ 0 }
/> />
{ data.name && ( <Box
<Text as={ shouldHighlightHash ? 'mark' : 'span' }
fontWeight={ 700 } display="block"
overflow="hidden" overflow="hidden"
whiteSpace="nowrap" whiteSpace="nowrap"
textOverflow="ellipsis" fontWeight={ 700 }
flexGrow={ 1 } flexGrow={ 1 }
>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
</Text>
) }
{ !data.name && (
<Box
as={ shouldHighlightHash ? 'mark' : 'span' }
display="block"
overflow="hidden"
whiteSpace="nowrap"
fontWeight={ 700 }
flexGrow={ 1 }
> >
<HashStringShortenDynamic hash={ data.address } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.address } isTooltipDisabled/>
</Box> </Box>
) } { data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
{ !data.name && data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Flex> </Flex>
{ data.name && ( { data.name && (
<Flex alignItems="center" justifyContent="space-between"> <Text
<Text variant="secondary"
as={ shouldHighlightHash ? 'mark' : 'span' } overflow="hidden"
overflow="hidden" whiteSpace="nowrap"
whiteSpace="nowrap" textOverflow="ellipsis"
variant="secondary" flexGrow={ 1 }
flexGrow={ 1 } >
> <span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
<HashStringShortenDynamic hash={ data.address } isTooltipDisabled/> </Text>
</Text>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Flex>
) } ) }
</> </>
); );
...@@ -79,43 +63,29 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm }: Props) => { ...@@ -79,43 +63,29 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm }: Props) => {
flexShrink={ 0 } flexShrink={ 0 }
/> />
<Flex alignItems="center" w="420px">
<Box
as={ shouldHighlightHash ? 'mark' : 'span' }
display="block"
overflow="hidden"
whiteSpace="nowrap"
fontWeight={ 700 }
>
<HashStringShortenDynamic hash={ data.address } isTooltipDisabled/>
</Box>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Flex>
{ data.name && ( { data.name && (
<> <Text
<Text variant="secondary"
fontWeight={ 700 } overflow="hidden"
overflow="hidden" whiteSpace="nowrap"
whiteSpace="nowrap" textOverflow="ellipsis"
textOverflow="ellipsis" flexGrow={ 0 }
flexGrow={ 0 } ml={ 6 }
w="200px" >
> <span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/>
<span dangerouslySetInnerHTML={{ __html: highlightText(data.name, searchTerm) }}/> </Text>
</Text>
<Text
as={ shouldHighlightHash ? 'mark' : 'span' }
overflow="hidden"
whiteSpace="nowrap"
variant="secondary"
ml={ 2 }
>
<HashStringShortenDynamic hash={ data.address } isTooltipDisabled/>
</Text>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</>
) }
{ !data.name && (
<>
<Box
as={ shouldHighlightHash ? 'mark' : 'span' }
display="block"
overflow="hidden"
whiteSpace="nowrap"
fontWeight={ 700 }
>
<HashStringShortenDynamic hash={ data.address } isTooltipDisabled/>
</Box>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</>
) } ) }
</Flex> </Flex>
); );
......
import { Text, Icon, Grid } from '@chakra-ui/react'; import { Text, Icon, Flex, Grid } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { SearchResultBlock } from 'types/api/search'; import type { SearchResultBlock } from 'types/api/search';
...@@ -20,7 +20,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: Props) => { ...@@ -20,7 +20,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: Props) => {
if (isMobile) { if (isMobile) {
return ( return (
<> <>
<Grid alignItems="center" templateColumns="24px auto 1fr" gap={ 2 }> <Flex alignItems="center">
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/> <Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/>
<Text <Text
fontWeight={ 700 } fontWeight={ 700 }
...@@ -30,23 +30,24 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: Props) => { ...@@ -30,23 +30,24 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: Props) => {
> >
<span dangerouslySetInnerHTML={{ __html: highlightText(data.block_number.toString(), searchTerm) }}/> <span dangerouslySetInnerHTML={{ __html: highlightText(data.block_number.toString(), searchTerm) }}/>
</Text> </Text>
<Text variant="secondary" overflow="hidden" whiteSpace="nowrap" as={ shouldHighlightHash ? 'mark' : 'span' } display="block"> </Flex>
<HashStringShortenDynamic hash={ data.block_hash } isTooltipDisabled/> <Text variant="secondary" overflow="hidden" whiteSpace="nowrap" as={ shouldHighlightHash ? 'mark' : 'span' } display="block">
</Text> <HashStringShortenDynamic hash={ data.block_hash } isTooltipDisabled/>
</Grid> </Text>
<Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text> <Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text>
</> </>
); );
} }
return ( return (
<Grid templateColumns="24px auto 1fr auto" gap={ 2 }> <Grid templateColumns="24px auto minmax(auto, max-content) auto" gap={ 2 }>
<Icon as={ blockIcon } boxSize={ 6 } color="gray.500"/> <Icon as={ blockIcon } boxSize={ 6 } color="gray.500"/>
<Text <Text
fontWeight={ 700 } fontWeight={ 700 }
overflow="hidden" overflow="hidden"
whiteSpace="nowrap" whiteSpace="nowrap"
textOverflow="ellipsis" textOverflow="ellipsis"
w="200px"
> >
<span dangerouslySetInnerHTML={{ __html: highlightText(data.block_number.toString(), searchTerm) }}/> <span dangerouslySetInnerHTML={{ __html: highlightText(data.block_number.toString(), searchTerm) }}/>
</Text> </Text>
...@@ -59,7 +60,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: Props) => { ...@@ -59,7 +60,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: Props) => {
> >
<HashStringShortenDynamic hash={ data.block_hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.block_hash } isTooltipDisabled/>
</Text> </Text>
<Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text> <Text variant="secondary" textAlign="end">{ dayjs(data.timestamp).format('llll') }</Text>
</Grid> </Grid>
); );
}; };
......
...@@ -38,16 +38,10 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => { ...@@ -38,16 +38,10 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => {
<HashStringShortenDynamic hash={ data.address } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.address } isTooltipDisabled/>
</Text> </Text>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> } { data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
{ data.token_type === 'ERC-20' && data.exchange_rate && ( <Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis"ml={ 2 } fontWeight={ 700 } maxW="200px">
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis"ml={ 2 } fontWeight={ 700 } maxW="200px"> { data.token_type === 'ERC-20' && data.exchange_rate && `$${ Number(data.exchange_rate).toLocaleString() }` }
${ Number(data.exchange_rate).toLocaleString() } { data.token_type !== 'ERC-20' && data.total_supply && `Items ${ Number(data.total_supply).toLocaleString() }` }
</Text> </Text>
) }
{ data.token_type !== 'ERC-20' && data.total_supply && (
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis"ml={ 2 } variant="secondary" maxW="200px" >
Items { Number(data.total_supply).toLocaleString() }
</Text>
) }
</Grid> </Grid>
</> </>
); );
...@@ -72,16 +66,10 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => { ...@@ -72,16 +66,10 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => {
</Text> </Text>
{ data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> } { data.is_smart_contract_verified && <Icon as={ iconSuccess } color="green.500" ml={ 2 }/> }
</Flex> </Flex>
{ data.token_type === 'ERC-20' && data.exchange_rate && ( <Text overflow="hidden" whiteSpace="nowrap" ml={ 2 } fontWeight={ 700 }>
<Text overflow="hidden" whiteSpace="nowrap" ml={ 2 } fontWeight={ 700 }> { data.token_type === 'ERC-20' && data.exchange_rate && `$${ Number(data.exchange_rate).toLocaleString() }` }
${ Number(data.exchange_rate).toLocaleString() } { data.token_type !== 'ERC-20' && data.total_supply && `Items ${ Number(data.total_supply).toLocaleString() }` }
</Text> </Text>
) }
{ data.token_type !== 'ERC-20' && data.total_supply && (
<Text overflow="hidden" whiteSpace="nowrap" ml={ 2 } variant="secondary">
Items { Number(data.total_supply).toLocaleString() }
</Text>
) }
</Grid> </Grid>
); );
}; };
......
...@@ -29,12 +29,13 @@ const SearchBarSuggestTx = ({ data, isMobile }: Props) => { ...@@ -29,12 +29,13 @@ const SearchBarSuggestTx = ({ data, isMobile }: Props) => {
} }
return ( return (
<Grid templateColumns="24px 1fr auto" gap={ 2 }> <Grid templateColumns="24px minmax(auto, max-content) auto" gap={ 2 }>
<Icon as={ txIcon } boxSize={ 6 } color="gray.500"/> <Icon as={ txIcon } boxSize={ 6 } color="gray.500"/>
<chakra.mark overflow="hidden" whiteSpace="nowrap" display="block" fontWeight={ 700 } width="fit-content">
<chakra.mark overflow="hidden" whiteSpace="nowrap" display="block" fontWeight={ 700 } >
<HashStringShortenDynamic hash={ data.tx_hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.tx_hash } isTooltipDisabled/>
</chakra.mark> </chakra.mark>
<Text variant="secondary">{ dayjs(data.timestamp).format('llll') }</Text> <Text variant="secondary" textAlign="end">{ dayjs(data.timestamp).format('llll') }</Text>
</Grid> </Grid>
); );
}; };
......
...@@ -195,7 +195,7 @@ const TxDetails = () => { ...@@ -195,7 +195,7 @@ const TxDetails = () => {
<Icon as={ clockIcon } boxSize={ 5 } color="gray.500" isLoading={ isPlaceholderData }/> <Icon as={ clockIcon } boxSize={ 5 } color="gray.500" isLoading={ isPlaceholderData }/>
<Skeleton isLoaded={ !isPlaceholderData } ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Skeleton> <Skeleton isLoaded={ !isPlaceholderData } ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Skeleton>
<TextSeparator/> <TextSeparator/>
<Skeleton isLoaded={ !isPlaceholderData } whiteSpace="normal">{ dayjs(data.timestamp).format('LLLL') }</Skeleton> <Skeleton isLoaded={ !isPlaceholderData } whiteSpace="normal">{ dayjs(data.timestamp).format('llll') }</Skeleton>
<TextSeparator color="gray.500"/> <TextSeparator color="gray.500"/>
<Skeleton isLoaded={ !isPlaceholderData } color="text_secondary"> <Skeleton isLoaded={ !isPlaceholderData } color="text_secondary">
<span>{ getConfirmationDuration(data.confirmation_duration) }</span> <span>{ getConfirmationDuration(data.confirmation_duration) }</span>
......
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