Commit d2368c18 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #564 from blockscout/internal-link

Internal link navigation with SPA
parents 43f96e1b 88f06cb3
...@@ -25,13 +25,13 @@ export default function useNavItems() { ...@@ -25,13 +25,13 @@ export default function useNavItems() {
return React.useMemo(() => { return React.useMemo(() => {
const mainNavItems = [ const mainNavItems = [
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block'), isNewUi: false }, { text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block'), isNewUi: true },
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx'), isNewUi: false }, { text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx'), isNewUi: true },
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens', isNewUi: false }, { text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute.startsWith('token'), isNewUi: true },
{ text: 'Accounts', url: link('accounts'), icon: walletIcon, isActive: currentRoute === 'accounts', isNewUi: false }, { text: 'Accounts', url: link('accounts'), icon: walletIcon, isActive: currentRoute === 'accounts', isNewUi: true },
isMarketplaceFilled ? isMarketplaceFilled ?
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps', isNewUi: true } : null, { text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute.startsWith('app'), isNewUi: true } : null,
{ text: 'Charts & stats', url: link('stats'), icon: statsIcon, isActive: currentRoute === 'stats', isNewUi: false }, { text: 'Charts & stats', url: link('stats'), icon: statsIcon, isActive: currentRoute === 'stats', isNewUi: true },
// there should be custom site sections like Stats, Faucet, More, etc but never an 'other' // there should be custom site sections like Stats, Faucet, More, etc but never an 'other'
// examples https://explorer-edgenet.polygon.technology/ and https://explorer.celo.org/ // examples https://explorer-edgenet.polygon.technology/ and https://explorer.celo.org/
// at this stage custom menu items is under development, we will implement it later // at this stage custom menu items is under development, we will implement it later
......
import type { ServerResponse } from 'http';
export function appendValue(res: ServerResponse | undefined, name: string, value: number) {
const currentValue = res?.getHeader('Server-Timing') || '';
const nextValue = [
currentValue,
`${ name };dur=${ value }`,
].filter(Boolean).join(',');
res?.setHeader('Server-Timing', nextValue);
}
...@@ -10,6 +10,7 @@ const cspPolicy = getCspPolicy(); ...@@ -10,6 +10,7 @@ const cspPolicy = getCspPolicy();
export function middleware(req: NextRequest) { export function middleware(req: NextRequest) {
const isPageRequest = req.headers.get('accept')?.includes('text/html'); const isPageRequest = req.headers.get('accept')?.includes('text/html');
const start = Date.now();
if (!isPageRequest) { if (!isPageRequest) {
return; return;
...@@ -25,8 +26,11 @@ export function middleware(req: NextRequest) { ...@@ -25,8 +26,11 @@ export function middleware(req: NextRequest) {
return NextResponse.redirect(authUrl); return NextResponse.redirect(authUrl);
} }
const end = Date.now();
const res = NextResponse.next(); const res = NextResponse.next();
res.headers.append('Content-Security-Policy-Report-Only', cspPolicy); res.headers.append('Content-Security-Policy-Report-Only', cspPolicy);
res.headers.append('Server-Timing', `middleware;dur=${ end - start }`);
return res; return res;
} }
......
...@@ -21,7 +21,7 @@ export const baseResponse: AddressCoinBalanceHistoryResponse = { ...@@ -21,7 +21,7 @@ export const baseResponse: AddressCoinBalanceHistoryResponse = {
block_number: 30367234, block_number: 30367234,
block_timestamp: '2022-10-01T17:55:20Z', block_timestamp: '2022-10-01T17:55:20Z',
delta: '1933020674364000', delta: '1933020674364000',
transaction_hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193', transaction_hash: null,
value: '10143933697708939226', value: '10143933697708939226',
}, },
{ {
......
import { ColorModeScript } from '@chakra-ui/react'; import { ColorModeScript } from '@chakra-ui/react';
import type { DocumentContext } from 'next/document';
import Document, { Html, Head, Main, NextScript } from 'next/document'; import Document, { Html, Head, Main, NextScript } from 'next/document';
import React from 'react'; import React from 'react';
import * as serverTiming from 'lib/next/serverTiming';
import theme from 'theme'; import theme from 'theme';
class MyDocument extends Document { class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const originalRenderPage = ctx.renderPage;
ctx.renderPage = async() => {
const start = Date.now();
const result = await originalRenderPage();
const end = Date.now();
serverTiming.appendValue(ctx.res, 'renderPage', end - start);
return result;
};
const initialProps = await Document.getInitialProps(ctx);
return initialProps;
}
render() { render() {
return ( return (
<Html lang="en"> <Html lang="en">
......
...@@ -10,6 +10,7 @@ import link from 'lib/link/link'; ...@@ -10,6 +10,7 @@ import link from 'lib/link/link';
import getNetworkTitle from 'lib/networks/getNetworkTitle'; import getNetworkTitle from 'lib/networks/getNetworkTitle';
import type { Props } from 'lib/next/getServerSideProps'; import type { Props } from 'lib/next/getServerSideProps';
import { getServerSideProps as getServerSidePropsBase } from 'lib/next/getServerSideProps'; import { getServerSideProps as getServerSidePropsBase } from 'lib/next/getServerSideProps';
import * as serverTiming from 'lib/next/serverTiming';
import SearchResults from 'ui/pages/SearchResults'; import SearchResults from 'ui/pages/SearchResults';
const SearchResultsPage: NextPage = () => { const SearchResultsPage: NextPage = () => {
...@@ -27,6 +28,8 @@ const SearchResultsPage: NextPage = () => { ...@@ -27,6 +28,8 @@ const SearchResultsPage: NextPage = () => {
export default SearchResultsPage; export default SearchResultsPage;
export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, resolvedUrl, query }) => { export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, resolvedUrl, query }) => {
const start = Date.now();
try { try {
const q = String(query.q); const q = String(query.q);
const url = buildUrlNode('search_check_redirect', undefined, { q }); const url = buildUrlNode('search_check_redirect', undefined, { q });
...@@ -63,5 +66,9 @@ export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, r ...@@ -63,5 +66,9 @@ export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, r
}; };
} catch (error) {} } catch (error) {}
const end = Date.now();
serverTiming.appendValue(res, 'query.search.check-redirect', end - start);
return getServerSidePropsBase({ req, res, resolvedUrl, query }); return getServerSidePropsBase({ req, res, resolvedUrl, query });
}; };
...@@ -18,11 +18,13 @@ const AddressCoinBalance = () => { ...@@ -18,11 +18,13 @@ const AddressCoinBalance = () => {
const [ socketAlert, setSocketAlert ] = React.useState(false); const [ socketAlert, setSocketAlert ] = React.useState(false);
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const router = useRouter(); const router = useRouter();
const scrollRef = React.useRef<HTMLDivElement>(null);
const addressHash = String(router.query?.id); const addressHash = String(router.query?.id);
const coinBalanceQuery = useQueryWithPages({ const coinBalanceQuery = useQueryWithPages({
resourceName: 'address_coin_balance', resourceName: 'address_coin_balance',
pathParams: { id: addressHash }, pathParams: { id: addressHash },
scrollRef,
}); });
const handleSocketError = React.useCallback(() => { const handleSocketError = React.useCallback(() => {
...@@ -65,6 +67,7 @@ const AddressCoinBalance = () => { ...@@ -65,6 +67,7 @@ const AddressCoinBalance = () => {
<> <>
{ socketAlert && <SocketAlert mb={ 6 }/> } { socketAlert && <SocketAlert mb={ 6 }/> }
<AddressCoinBalanceChart addressHash={ addressHash }/> <AddressCoinBalanceChart addressHash={ addressHash }/>
<div ref={ scrollRef }></div>
<AddressCoinBalanceHistory query={ coinBalanceQuery }/> <AddressCoinBalanceHistory query={ coinBalanceQuery }/>
</> </>
); );
......
import { Box, Flex, Text, Icon, Grid, Link } from '@chakra-ui/react'; import { Box, Flex, Text, Icon, Grid } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query'; import type { UseQueryResult } from '@tanstack/react-query';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
...@@ -17,9 +17,10 @@ import AddressLink from 'ui/shared/address/AddressLink'; ...@@ -17,9 +17,10 @@ import AddressLink from 'ui/shared/address/AddressLink';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import ExternalLink from 'ui/shared/ExternalLink';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal';
import AddressAddToMetaMask from './details/AddressAddToMetaMask'; import AddressAddToMetaMask from './details/AddressAddToMetaMask';
import AddressBalance from './details/AddressBalance'; import AddressBalance from './details/AddressBalance';
...@@ -107,8 +108,8 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -107,8 +108,8 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
<Flex mt={ 8 } columnGap={ 4 } flexWrap="wrap"> <Flex mt={ 8 } columnGap={ 4 } flexWrap="wrap">
<Text fontSize="sm">Verify with other explorers</Text> <Text fontSize="sm">Verify with other explorers</Text>
{ explorers.map((explorer) => { { explorers.map((explorer) => {
const url = new URL(explorer.paths.tx + '/' + router.query.id, explorer.baseUrl); const url = new URL(explorer.paths.address + '/' + router.query.id, explorer.baseUrl);
return <ExternalLink key={ explorer.baseUrl } title={ explorer.title } href={ url.toString() }/>; return <LinkExternal key={ explorer.baseUrl } title={ explorer.title } href={ url.toString() }/>;
}) } }) }
</Flex> </Flex>
) } ) }
...@@ -135,7 +136,9 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -135,7 +136,9 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
hint="Implementation address of the proxy contract." hint="Implementation address of the proxy contract."
columnGap={ 1 } columnGap={ 1 }
> >
<Link href={ link('address_index', { id: data.implementation_address }) }>{ data.implementation_name }</Link> <LinkInternal href={ link('address_index', { id: data.implementation_address }) }>
{ data.implementation_name }
</LinkInternal>
<Text variant="secondary" overflow="hidden"> <Text variant="secondary" overflow="hidden">
<HashStringShortenDynamic hash={ `(${ data.implementation_address })` }/> <HashStringShortenDynamic hash={ `(${ data.implementation_address })` }/>
</Text> </Text>
...@@ -195,14 +198,14 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -195,14 +198,14 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
alignSelf="center" alignSelf="center"
py={{ base: '2px', lg: 1 }} py={{ base: '2px', lg: 1 }}
> >
<Link <LinkInternal
href={ link('block', { id: String(data.block_number_balance_updated_at) }) } href={ link('block', { id: String(data.block_number_balance_updated_at) }) }
display="flex" display="flex"
alignItems="center" alignItems="center"
> >
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 }/> <Icon as={ blockIcon } boxSize={ 6 } mr={ 2 }/>
{ data.block_number_balance_updated_at } { data.block_number_balance_updated_at }
</Link> </LinkInternal>
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
</Grid> </Grid>
......
import { Link, Text, Flex } from '@chakra-ui/react'; import { Text, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -8,6 +8,7 @@ import appConfig from 'configs/app/config'; ...@@ -8,6 +8,7 @@ import appConfig from 'configs/app/config';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link'; import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
...@@ -23,7 +24,7 @@ const AddressBlocksValidatedListItem = (props: Props) => { ...@@ -23,7 +24,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
return ( return (
<ListItemMobile rowGap={ 2 } isAnimated> <ListItemMobile rowGap={ 2 } isAnimated>
<Flex justifyContent="space-between" w="100%"> <Flex justifyContent="space-between" w="100%">
<Link href={ blockUrl } fontWeight="700">{ props.height }</Link> <LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
<Text variant="secondary">{ timeAgo }</Text> <Text variant="secondary">{ timeAgo }</Text>
</Flex> </Flex>
<Flex columnGap={ 2 } w="100%"> <Flex columnGap={ 2 } w="100%">
......
import { Link, Td, Tr, Text, Box, Flex } from '@chakra-ui/react'; import { Td, Tr, Text, Box, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -7,6 +7,7 @@ import type { Block } from 'types/api/block'; ...@@ -7,6 +7,7 @@ import type { Block } from 'types/api/block';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link'; import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
type Props = Block & { type Props = Block & {
...@@ -21,7 +22,7 @@ const AddressBlocksValidatedTableItem = (props: Props) => { ...@@ -21,7 +22,7 @@ const AddressBlocksValidatedTableItem = (props: Props) => {
return ( return (
<Tr> <Tr>
<Td> <Td>
<Link href={ blockUrl } fontWeight="700">{ props.height }</Link> <LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
</Td> </Td>
<Td> <Td>
<Text variant="secondary">{ timeAgo }</Text> <Text variant="secondary">{ timeAgo }</Text>
......
import { Link, Text, Stat, StatHelpText, StatArrow, Flex } from '@chakra-ui/react'; import { Text, Stat, StatHelpText, StatArrow, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -10,6 +10,7 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; ...@@ -10,6 +10,7 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link'; import link from 'lib/link/link';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile';
type Props = AddressCoinBalanceHistoryItem & { type Props = AddressCoinBalanceHistoryItem & {
...@@ -25,19 +26,19 @@ const AddressCoinBalanceListItem = (props: Props) => { ...@@ -25,19 +26,19 @@ const AddressCoinBalanceListItem = (props: Props) => {
return ( return (
<ListItemMobile rowGap={ 2 } isAnimated> <ListItemMobile rowGap={ 2 } isAnimated>
<Flex justifyContent="space-between" w="100%"> <Flex justifyContent="space-between" w="100%">
<Text fontWeight={ 600 }>{ BigNumber(props.value).div(WEI).toFixed(8) } { appConfig.network.currency.symbol }</Text> <Text fontWeight={ 600 }>{ BigNumber(props.value).div(WEI).dp(8).toFormat() } { appConfig.network.currency.symbol }</Text>
<Stat flexGrow="0"> <Stat flexGrow="0">
<StatHelpText display="flex" mb={ 0 } alignItems="center"> <StatHelpText display="flex" mb={ 0 } alignItems="center">
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/> <StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/>
<Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }> <Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }>
{ deltaBn.toFormat() } { deltaBn.dp(8).toFormat() }
</Text> </Text>
</StatHelpText> </StatHelpText>
</Stat> </Stat>
</Flex> </Flex>
<Flex columnGap={ 2 } w="100%"> <Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Block</Text> <Text fontWeight={ 500 } flexShrink={ 0 }>Block</Text>
<Link href={ blockUrl } fontWeight="700">{ props.block_number }</Link> <LinkInternal href={ blockUrl } fontWeight="700">{ props.block_number }</LinkInternal>
</Flex> </Flex>
{ props.transaction_hash && ( { props.transaction_hash && (
<Flex columnGap={ 2 } w="100%"> <Flex columnGap={ 2 } w="100%">
......
import { Link, Td, Tr, Text, Stat, StatHelpText, StatArrow } from '@chakra-ui/react'; import { Td, Tr, Text, Stat, StatHelpText, StatArrow } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -9,6 +9,7 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; ...@@ -9,6 +9,7 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link'; import link from 'lib/link/link';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import LinkInternal from 'ui/shared/LinkInternal';
type Props = AddressCoinBalanceHistoryItem & { type Props = AddressCoinBalanceHistoryItem & {
page: number; page: number;
...@@ -23,12 +24,12 @@ const AddressCoinBalanceTableItem = (props: Props) => { ...@@ -23,12 +24,12 @@ const AddressCoinBalanceTableItem = (props: Props) => {
return ( return (
<Tr> <Tr>
<Td> <Td>
<Link href={ blockUrl } fontWeight="700">{ props.block_number }</Link> <LinkInternal href={ blockUrl } fontWeight="700">{ props.block_number }</LinkInternal>
</Td> </Td>
<Td> <Td>
{ props.transaction_hash ? { props.transaction_hash ?
( (
<Address maxW="150px" fontWeight="700"> <Address w="150px" fontWeight="700">
<AddressLink hash={ props.transaction_hash } type="transaction"/> <AddressLink hash={ props.transaction_hash } type="transaction"/>
</Address> </Address>
) : ) :
...@@ -39,14 +40,14 @@ const AddressCoinBalanceTableItem = (props: Props) => { ...@@ -39,14 +40,14 @@ const AddressCoinBalanceTableItem = (props: Props) => {
<Text variant="secondary">{ timeAgo }</Text> <Text variant="secondary">{ timeAgo }</Text>
</Td> </Td>
<Td isNumeric pr={ 1 }> <Td isNumeric pr={ 1 }>
<Text>{ BigNumber(props.value).div(WEI).toFixed(8) }</Text> <Text>{ BigNumber(props.value).div(WEI).dp(8).toFormat() }</Text>
</Td> </Td>
<Td isNumeric display="flex" justifyContent="end"> <Td isNumeric display="flex" justifyContent="end">
<Stat flexGrow="0"> <Stat flexGrow="0">
<StatHelpText display="flex" mb={ 0 } alignItems="center"> <StatHelpText display="flex" mb={ 0 } alignItems="center">
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/> <StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/>
<Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }> <Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }>
{ deltaBn.toFormat() } { deltaBn.dp(8).toFormat() }
</Text> </Text>
</StatHelpText> </StatHelpText>
</Stat> </Stat>
......
...@@ -8,7 +8,8 @@ import Address from 'ui/shared/address/Address'; ...@@ -8,7 +8,8 @@ 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 DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import ExternalLink from 'ui/shared/ExternalLink'; import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal';
import RawDataSnippet from 'ui/shared/RawDataSnippet'; import RawDataSnippet from 'ui/shared/RawDataSnippet';
import ContractSourceCode from './ContractSourceCode'; import ContractSourceCode from './ContractSourceCode';
...@@ -72,7 +73,9 @@ const ContractCode = () => { ...@@ -72,7 +73,9 @@ const ContractCode = () => {
const decoded = data.decoded_constructor_args const decoded = data.decoded_constructor_args
.map(([ value, { name, type } ], index) => { .map(([ value, { name, type } ], index) => {
const valueEl = type === 'address' ? <Link href={ link('address_index', { id: value }) }>{ value }</Link> : <span>{ value }</span>; const valueEl = type === 'address' ?
<LinkInternal href={ link('address_index', { id: value }) }>{ value }</LinkInternal> :
<span>{ value }</span>;
return ( return (
<Box key={ index }> <Box key={ index }>
<span>Arg [{ index }] { name || '' } ({ type }): </span> <span>Arg [{ index }] { name || '' } ({ type }): </span>
...@@ -98,7 +101,7 @@ const ContractCode = () => { ...@@ -98,7 +101,7 @@ const ContractCode = () => {
return data.external_libraries.map((item) => ( return data.external_libraries.map((item) => (
<Box key={ item.address_hash }> <Box key={ item.address_hash }>
<chakra.span fontWeight={ 500 }>{ item.name }: </chakra.span> <chakra.span fontWeight={ 500 }>{ item.name }: </chakra.span>
<Link href={ link('address_index', { id: item.address_hash }, { tab: 'contract' }) }>{ item.address_hash }</Link> <LinkInternal href={ link('address_index', { id: item.address_hash }, { tab: 'contract' }) }>{ item.address_hash }</LinkInternal>
</Box> </Box>
)); ));
})(); })();
...@@ -110,7 +113,7 @@ const ContractCode = () => { ...@@ -110,7 +113,7 @@ const ContractCode = () => {
{ data.is_verified_via_sourcify && ( { data.is_verified_via_sourcify && (
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap"> <Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>This contract has been { data.is_partially_verified ? 'partially ' : '' }verified via Sourcify. </span> <span>This contract has been { data.is_partially_verified ? 'partially ' : '' }verified via Sourcify. </span>
{ data.sourcify_repo_url && <ExternalLink href={ data.sourcify_repo_url } title="View contract in Sourcify repository" fontSize="md"/> } { data.sourcify_repo_url && <LinkExternal href={ data.sourcify_repo_url } title="View contract in Sourcify repository" fontSize="md"/> }
</Alert> </Alert>
) } ) }
{ data.is_changed_bytecode && ( { data.is_changed_bytecode && (
...@@ -126,7 +129,7 @@ const ContractCode = () => { ...@@ -126,7 +129,7 @@ const ContractCode = () => {
<AddressLink type="address" hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/> <AddressLink type="address" hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/>
</Address> </Address>
<chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span> <chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span>
<Link href={ link('address_contract_verification', { id: data.verified_twin_address_hash }) }>Verify & Publish</Link> <LinkInternal href={ link('address_contract_verification', { id: data.verified_twin_address_hash }) }>Verify & Publish</LinkInternal>
<span> page</span> <span> page</span>
</Alert> </Alert>
) } ) }
......
import { Box, chakra, Link, Spinner } from '@chakra-ui/react'; import { Box, chakra, Spinner } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { ContractMethodWriteResult } from './types'; import type { ContractMethodWriteResult } from './types';
import link from 'lib/link/link'; import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props { interface Props {
result: ContractMethodWriteResult; result: ContractMethodWriteResult;
...@@ -30,7 +31,7 @@ const ContractWriteResultDumb = ({ result, onSettle, txInfo }: Props) => { ...@@ -30,7 +31,7 @@ const ContractWriteResultDumb = ({ result, onSettle, txInfo }: Props) => {
const isErrorResult = 'message' in result; const isErrorResult = 'message' in result;
const txLink = ( const txLink = (
<Link href={ link('tx', { id: txHash }) }>View transaction details</Link> <LinkInternal href={ link('tx', { id: txHash }) }>View transaction details</LinkInternal>
); );
const content = (() => { const content = (() => {
......
import { Link, Skeleton } from '@chakra-ui/react'; import { Skeleton } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query'; import type { UseQueryResult } from '@tanstack/react-query';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import NextLink from 'next/link';
import React from 'react'; import React from 'react';
import type { AddressCounters } from 'types/api/address'; import type { AddressCounters } from 'types/api/address';
import link from 'lib/link/link'; import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props { interface Props {
prop: keyof AddressCounters; prop: keyof AddressCounters;
...@@ -42,11 +42,9 @@ const AddressCounterItem = ({ prop, query, address, onClick }: Props) => { ...@@ -42,11 +42,9 @@ const AddressCounterItem = ({ prop, query, address, onClick }: Props) => {
return <span>0</span>; return <span>0</span>;
} }
return ( return (
<NextLink href={ link('address_index', { id: address }, { tab: PROP_TO_TAB[prop] }) } passHref> <LinkInternal href={ link('address_index', { id: address }, { tab: PROP_TO_TAB[prop] }) } onClick={ onClick }>
<Link onClick={ onClick }> { Number(data).toLocaleString() }
{ Number(data).toLocaleString() } </LinkInternal>
</Link>
</NextLink>
); );
} }
} }
......
import { Link } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { Address } from 'types/api/address'; import type { Address } from 'types/api/address';
import link from 'lib/link/link'; import link from 'lib/link/link';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props { interface Props {
data: Pick<Address, 'name' | 'token' | 'is_contract'>; data: Pick<Address, 'name' | 'token' | 'is_contract'>;
...@@ -17,9 +17,9 @@ const AddressNameInfo = ({ data }: Props) => { ...@@ -17,9 +17,9 @@ const AddressNameInfo = ({ data }: Props) => {
title="Token name" title="Token name"
hint="Token name and symbol" hint="Token name and symbol"
> >
<Link href={ link('token_index', { hash: data.token.address }) }> <LinkInternal href={ link('token_index', { hash: data.token.address }) }>
{ data.token.name } ({ data.token.symbol }) { data.token.name } ({ data.token.symbol })
</Link> </LinkInternal>
</DetailsInfoItem> </DetailsInfoItem>
); );
} }
......
import { Flex, Tag, Icon, Box, HStack, Text, Link } from '@chakra-ui/react'; import { Flex, Tag, Icon, Box, HStack, Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -12,6 +12,7 @@ import Address from 'ui/shared/address/Address'; ...@@ -12,6 +12,7 @@ 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 InOutTag from 'ui/shared/InOutTag'; import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils'; import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
...@@ -49,7 +50,7 @@ const TxInternalsListItem = ({ ...@@ -49,7 +50,7 @@ const TxInternalsListItem = ({
</Flex> </Flex>
<HStack spacing={ 1 }> <HStack spacing={ 1 }>
<Text fontSize="sm" fontWeight={ 500 }>Block</Text> <Text fontSize="sm" fontWeight={ 500 }>Block</Text>
<Link href={ link('block', { id: block.toString() }) }>{ block }</Link> <LinkInternal href={ link('block', { id: block.toString() }) }>{ block }</LinkInternal>
</HStack> </HStack>
<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)">
......
import { Tr, Td, Tag, Icon, Box, Flex, Text, Link } from '@chakra-ui/react'; import { Tr, Td, Tag, Icon, Box, Flex, Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -12,6 +12,7 @@ import Address from 'ui/shared/address/Address'; ...@@ -12,6 +12,7 @@ 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 InOutTag from 'ui/shared/InOutTag'; import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils'; import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
...@@ -57,7 +58,7 @@ const AddressIntTxsTableItem = ({ ...@@ -57,7 +58,7 @@ const AddressIntTxsTableItem = ({
</Flex> </Flex>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Link href={ link('block', { id: block.toString() }) }>{ block }</Link> <LinkInternal href={ link('block', { id: block.toString() }) }>{ block }</LinkInternal>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Address display="inline-flex" maxW="100%"> <Address display="inline-flex" maxW="100%">
......
import { Grid, GridItem, Text, Icon, Link, Box, Tooltip } from '@chakra-ui/react'; import { Grid, GridItem, Text, Icon, Link, Box, Tooltip } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import capitalize from 'lodash/capitalize'; import capitalize from 'lodash/capitalize';
import NextLink from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll'; import { scroller, Element } from 'react-scroll';
...@@ -23,6 +22,7 @@ import DataFetchAlert from 'ui/shared/DataFetchAlert'; ...@@ -23,6 +22,7 @@ import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import PrevNext from 'ui/shared/PrevNext'; import PrevNext from 'ui/shared/PrevNext';
import TextSeparator from 'ui/shared/TextSeparator'; import TextSeparator from 'ui/shared/TextSeparator';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
...@@ -116,11 +116,9 @@ const BlockDetails = () => { ...@@ -116,11 +116,9 @@ const BlockDetails = () => {
title="Transactions" title="Transactions"
hint="The number of transactions in the block." hint="The number of transactions in the block."
> >
<NextLink href={ link('block', { id: router.query.id }, { tab: 'txs' }) } passHref> <LinkInternal href={ link('block', { id: router.query.id }, { tab: 'txs' }) }>
<Link> { data.tx_count } transactions
{ data.tx_count } transactions </LinkInternal>
</Link>
</NextLink>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title={ appConfig.network.verificationType === 'validation' ? 'Validated by' : 'Mined by' } title={ appConfig.network.verificationType === 'validation' ? 'Validated by' : 'Mined by' }
......
import { Flex, Link, Spinner, Text, Box, Icon } from '@chakra-ui/react'; import { Flex, Spinner, Text, Box, Icon } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import capitalize from 'lodash/capitalize'; import capitalize from 'lodash/capitalize';
import React from 'react'; import React from 'react';
...@@ -14,6 +14,7 @@ import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; ...@@ -14,6 +14,7 @@ import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import BlockTimestamp from 'ui/blocks/BlockTimestamp'; import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
...@@ -33,12 +34,12 @@ const BlocksListItem = ({ data, isPending, enableTimeIncrement }: Props) => { ...@@ -33,12 +34,12 @@ const BlocksListItem = ({ data, isPending, enableTimeIncrement }: Props) => {
<Flex justifyContent="space-between" w="100%"> <Flex justifyContent="space-between" w="100%">
<Flex columnGap={ 2 } alignItems="center"> <Flex columnGap={ 2 } alignItems="center">
{ isPending && <Spinner size="sm"/> } { isPending && <Spinner size="sm"/> }
<Link <LinkInternal
fontWeight={ 600 } fontWeight={ 600 }
href={ link('block', { id: String(data.height) }) } href={ link('block', { id: String(data.height) }) }
> >
{ data.height } { data.height }
</Link> </LinkInternal>
</Flex> </Flex>
<BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement }/> <BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement }/>
</Flex> </Flex>
......
import { Tr, Td, Link, Flex, Box, Icon, Tooltip, Spinner, useColorModeValue } from '@chakra-ui/react'; import { Tr, Td, Flex, Box, Icon, Tooltip, Spinner, useColorModeValue } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import React from 'react'; import React from 'react';
...@@ -12,6 +12,7 @@ import link from 'lib/link/link'; ...@@ -12,6 +12,7 @@ import link from 'lib/link/link';
import BlockTimestamp from 'ui/blocks/BlockTimestamp'; import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import LinkInternal from 'ui/shared/LinkInternal';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
interface Props { interface Props {
...@@ -38,12 +39,12 @@ const BlocksTableItem = ({ data, isPending, enableTimeIncrement }: Props) => { ...@@ -38,12 +39,12 @@ const BlocksTableItem = ({ data, isPending, enableTimeIncrement }: Props) => {
<Flex columnGap={ 2 } alignItems="center" mb={ 2 }> <Flex columnGap={ 2 } alignItems="center" mb={ 2 }>
{ isPending && <Spinner size="sm" flexShrink={ 0 }/> } { isPending && <Spinner size="sm" flexShrink={ 0 }/> }
<Tooltip isDisabled={ data.type !== 'reorg' } label="Chain reorganizations"> <Tooltip isDisabled={ data.type !== 'reorg' } label="Chain reorganizations">
<Link <LinkInternal
fontWeight={ 600 } fontWeight={ 600 }
href={ link('block', { id: String(data.height) }) } href={ link('block', { id: String(data.height) }) }
> >
{ data.height } { data.height }
</Link> </LinkInternal>
</Tooltip> </Tooltip>
</Flex> </Flex>
<BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement }/> <BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement }/>
......
import { Box, Heading, Flex, Link, Text, VStack, Skeleton } from '@chakra-ui/react'; import { Box, Heading, Flex, Text, VStack, Skeleton } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { AnimatePresence } from 'framer-motion'; import { AnimatePresence } from 'framer-motion';
import React from 'react'; import React from 'react';
...@@ -12,6 +12,7 @@ import { nbsp } from 'lib/html-entities'; ...@@ -12,6 +12,7 @@ import { nbsp } from 'lib/html-entities';
import link from 'lib/link/link'; import link from 'lib/link/link';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import LinkInternal from 'ui/shared/LinkInternal';
import LatestBlocksItem from './LatestBlocksItem'; import LatestBlocksItem from './LatestBlocksItem';
import LatestBlocksItemSkeleton from './LatestBlocksItemSkeleton'; import LatestBlocksItemSkeleton from './LatestBlocksItemSkeleton';
...@@ -97,7 +98,7 @@ const LatestBlocks = () => { ...@@ -97,7 +98,7 @@ const LatestBlocks = () => {
</AnimatePresence> </AnimatePresence>
</VStack> </VStack>
<Flex justifyContent="center"> <Flex justifyContent="center">
<Link fontSize="sm" href={ link('blocks') }>View all blocks</Link> <LinkInternal fontSize="sm" href={ link('blocks') }>View all blocks</LinkInternal>
</Flex> </Flex>
</> </>
); );
......
...@@ -5,7 +5,6 @@ import { ...@@ -5,7 +5,6 @@ import {
GridItem, GridItem,
HStack, HStack,
Icon, Icon,
Link,
Text, Text,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
...@@ -18,6 +17,7 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward'; ...@@ -18,6 +17,7 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import link from 'lib/link/link'; import link from 'lib/link/link';
import BlockTimestamp from 'ui/blocks/BlockTimestamp'; import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import LinkInternal from 'ui/shared/LinkInternal';
type Props = { type Props = {
block: Block; block: Block;
...@@ -43,13 +43,13 @@ const LatestBlocksItem = ({ block, h }: Props) => { ...@@ -43,13 +43,13 @@ const LatestBlocksItem = ({ block, h }: Props) => {
<Flex justifyContent="space-between" alignItems="center" mb={ 3 }> <Flex justifyContent="space-between" alignItems="center" mb={ 3 }>
<HStack spacing={ 2 }> <HStack spacing={ 2 }>
<Icon as={ blockIcon } boxSize="30px" color="link"/> <Icon as={ blockIcon } boxSize="30px" color="link"/>
<Link <LinkInternal
href={ link('block', { id: String(block.height) }) } href={ link('block', { id: String(block.height) }) }
fontSize="xl" fontSize="xl"
fontWeight="500" fontWeight="500"
> >
{ block.height } { block.height }
</Link> </LinkInternal>
</HStack> </HStack>
<BlockTimestamp ts={ block.timestamp } isEnabled fontSize="sm"/> <BlockTimestamp ts={ block.timestamp } isEnabled fontSize="sm"/>
</Flex> </Flex>
......
import { Box, Heading, Flex, Link, Text, Skeleton } from '@chakra-ui/react'; import { Box, Heading, Flex, Text, Skeleton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useNewTxsSocket from 'lib/hooks/useNewTxsSocket'; import useNewTxsSocket from 'lib/hooks/useNewTxsSocket';
import link from 'lib/link/link'; import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal';
import SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice'; import SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import LatestTxsItem from './LatestTxsItem'; import LatestTxsItem from './LatestTxsItem';
...@@ -36,12 +37,12 @@ const LatestTransactions = () => { ...@@ -36,12 +37,12 @@ const LatestTransactions = () => {
const txsUrl = link('txs'); const txsUrl = link('txs');
content = ( content = (
<> <>
<SocketNewItemsNotice borderBottomRadius={ 0 } url={ link('txs') } num={ num } alert={ socketAlert }/> <SocketNewItemsNotice borderBottomRadius={ 0 } url={ txsUrl } num={ num } alert={ socketAlert }/>
<Box mb={{ base: 3, lg: 4 }}> <Box mb={{ base: 3, lg: 4 }}>
{ data.slice(0, txsCount).map((tx => <LatestTxsItem key={ tx.hash } tx={ tx }/>)) } { data.slice(0, txsCount).map((tx => <LatestTxsItem key={ tx.hash } tx={ tx }/>)) }
</Box> </Box>
<Flex justifyContent="center"> <Flex justifyContent="center">
<Link fontSize="sm" href={ txsUrl }>View all transactions</Link> <LinkInternal fontSize="sm" href={ txsUrl }>View all transactions</LinkInternal>
</Flex> </Flex>
</> </>
); );
......
...@@ -8,7 +8,6 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types'; ...@@ -8,7 +8,6 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import iconSuccess from 'icons/status/success.svg'; import iconSuccess from 'icons/status/success.svg';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext'; import { useAppContext } from 'lib/appContext';
import isBrowser from 'lib/isBrowser';
import notEmpty from 'lib/notEmpty'; import notEmpty from 'lib/notEmpty';
import AddressBlocksValidated from 'ui/address/AddressBlocksValidated'; import AddressBlocksValidated from 'ui/address/AddressBlocksValidated';
import AddressCoinBalance from 'ui/address/AddressCoinBalance'; import AddressCoinBalance from 'ui/address/AddressCoinBalance';
...@@ -41,11 +40,8 @@ const AddressPageContent = () => { ...@@ -41,11 +40,8 @@ const AddressPageContent = () => {
const router = useRouter(); const router = useRouter();
const appProps = useAppContext(); const appProps = useAppContext();
const isInBrowser = isBrowser();
const referrer = isInBrowser ? window.document.referrer : appProps.referrer; const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/accounts');
const hasGoBackLink = referrer && referrer.includes('/accounts');
const tabsScrollRef = React.useRef<HTMLDivElement>(null); const tabsScrollRef = React.useRef<HTMLDivElement>(null);
...@@ -134,7 +130,7 @@ const AddressPageContent = () => { ...@@ -134,7 +130,7 @@ const AddressPageContent = () => {
<PageTitle <PageTitle
text={ `${ addressQuery.data?.is_contract ? 'Contract' : 'Address' } details` } text={ `${ addressQuery.data?.is_contract ? 'Contract' : 'Address' } details` }
additionalsRight={ tagsNode } additionalsRight={ tagsNode }
backLinkUrl={ hasGoBackLink ? referrer : undefined } backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to top accounts list" backLinkLabel="Back to top accounts list"
/> />
) } ) }
......
...@@ -6,7 +6,6 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types'; ...@@ -6,7 +6,6 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import { useAppContext } from 'lib/appContext'; import { useAppContext } from 'lib/appContext';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import isBrowser from 'lib/isBrowser';
import BlockDetails from 'ui/block/BlockDetails'; import BlockDetails from 'ui/block/BlockDetails';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
...@@ -24,7 +23,6 @@ const TAB_LIST_PROPS = { ...@@ -24,7 +23,6 @@ const TAB_LIST_PROPS = {
const BlockPageContent = () => { const BlockPageContent = () => {
const router = useRouter(); const router = useRouter();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isInBrowser = isBrowser();
const appProps = useAppContext(); const appProps = useAppContext();
const blockTxsQuery = useQueryWithPages({ const blockTxsQuery = useQueryWithPages({
...@@ -46,15 +44,14 @@ const BlockPageContent = () => { ...@@ -46,15 +44,14 @@ const BlockPageContent = () => {
const hasPagination = !isMobile && router.query.tab === 'txs' && blockTxsQuery.isPaginationVisible; const hasPagination = !isMobile && router.query.tab === 'txs' && blockTxsQuery.isPaginationVisible;
const referrer = isInBrowser ? window.document.referrer : appProps.referrer; const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/blocks');
const hasGoBackLink = referrer && referrer.includes('/blocks');
return ( return (
<Page> <Page>
<TextAd mb={ 6 }/> <TextAd mb={ 6 }/>
<PageTitle <PageTitle
text={ `Block #${ router.query.id }` } text={ `Block #${ router.query.id }` }
backLinkUrl={ hasGoBackLink ? referrer : undefined } backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to blocks list" backLinkLabel="Back to blocks list"
/> />
<RoutedTabs <RoutedTabs
......
...@@ -8,7 +8,6 @@ import useApiQuery from 'lib/api/useApiQuery'; ...@@ -8,7 +8,6 @@ import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext'; import { useAppContext } from 'lib/appContext';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import isBrowser from 'lib/isBrowser';
import AdBanner from 'ui/shared/ad/AdBanner'; import AdBanner from 'ui/shared/ad/AdBanner';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
...@@ -29,11 +28,8 @@ const TokenPageContent = () => { ...@@ -29,11 +28,8 @@ const TokenPageContent = () => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const appProps = useAppContext(); const appProps = useAppContext();
const isInBrowser = isBrowser();
const referrer = isInBrowser ? window.document.referrer : appProps.referrer; const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/tokens');
const hasGoBackLink = referrer && referrer.includes('/tokens');
const scrollRef = React.useRef<HTMLDivElement>(null); const scrollRef = React.useRef<HTMLDivElement>(null);
...@@ -104,7 +100,7 @@ const TokenPageContent = () => { ...@@ -104,7 +100,7 @@ const TokenPageContent = () => {
<TextAd mb={ 6 }/> <TextAd mb={ 6 }/>
<PageTitle <PageTitle
text={ `${ tokenQuery.data?.name } (${ tokenQuery.data?.symbol }) token` } text={ `${ tokenQuery.data?.name } (${ tokenQuery.data?.symbol }) token` }
backLinkUrl={ hasGoBackLink ? referrer : undefined } backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to tokens list" backLinkLabel="Back to tokens list"
additionalsLeft={ ( additionalsLeft={ (
<TokenLogo hash={ tokenQuery.data?.address } name={ tokenQuery.data?.name } boxSize={ 6 }/> <TokenLogo hash={ tokenQuery.data?.address } name={ tokenQuery.data?.name } boxSize={ 6 }/>
......
...@@ -6,10 +6,9 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types'; ...@@ -6,10 +6,9 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext'; import { useAppContext } from 'lib/appContext';
import isBrowser from 'lib/isBrowser';
import networkExplorers from 'lib/networks/networkExplorers'; import networkExplorers from 'lib/networks/networkExplorers';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import ExternalLink from 'ui/shared/ExternalLink'; import LinkExternal from 'ui/shared/LinkExternal';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs'; import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
...@@ -33,11 +32,8 @@ const TABS: Array<RoutedTab> = [ ...@@ -33,11 +32,8 @@ const TABS: Array<RoutedTab> = [
const TransactionPageContent = () => { const TransactionPageContent = () => {
const router = useRouter(); const router = useRouter();
const appProps = useAppContext(); const appProps = useAppContext();
const isInBrowser = isBrowser();
const referrer = isInBrowser ? window.document.referrer : appProps.referrer; const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/txs');
const hasGoBackLink = referrer && referrer.includes('/txs');
const { data } = useApiQuery('tx', { const { data } = useApiQuery('tx', {
pathParams: { id: router.query.id?.toString() }, pathParams: { id: router.query.id?.toString() },
...@@ -48,7 +44,7 @@ const TransactionPageContent = () => { ...@@ -48,7 +44,7 @@ const TransactionPageContent = () => {
.filter((explorer) => explorer.paths.tx) .filter((explorer) => explorer.paths.tx)
.map((explorer) => { .map((explorer) => {
const url = new URL(explorer.paths.tx + '/' + router.query.id, explorer.baseUrl); const url = new URL(explorer.paths.tx + '/' + router.query.id, explorer.baseUrl);
return <ExternalLink key={ explorer.baseUrl } title={ `Open in ${ explorer.title }` } href={ url.toString() }/>; return <LinkExternal key={ explorer.baseUrl } title={ `Open in ${ explorer.title }` } href={ url.toString() }/>;
}); });
const additionals = ( const additionals = (
...@@ -74,7 +70,7 @@ const TransactionPageContent = () => { ...@@ -74,7 +70,7 @@ const TransactionPageContent = () => {
<PageTitle <PageTitle
text="Transaction details" text="Transaction details"
additionalsRight={ additionals } additionalsRight={ additionals }
backLinkUrl={ hasGoBackLink ? referrer : undefined } backLinkUrl={ hasGoBackLink ? appProps.referrer : undefined }
backLinkLabel="Back to transactions list" backLinkLabel="Back to transactions list"
/> />
<RoutedTabs tabs={ TABS }/> <RoutedTabs tabs={ TABS }/>
......
import { Text, Link, Flex, Icon, Box, chakra } from '@chakra-ui/react'; import { Text, Flex, Icon, Box, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { SearchResultItem } from 'types/api/search'; import type { SearchResultItem } from 'types/api/search';
...@@ -11,6 +11,7 @@ import Address from 'ui/shared/address/Address'; ...@@ -11,6 +11,7 @@ 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 HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile';
import TokenLogo from 'ui/shared/TokenLogo'; import TokenLogo from 'ui/shared/TokenLogo';
...@@ -29,9 +30,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => { ...@@ -29,9 +30,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
return ( return (
<Flex alignItems="flex-start"> <Flex alignItems="flex-start">
<TokenLogo boxSize={ 6 } hash={ data.address } name={ data.name } flexShrink={ 0 }/> <TokenLogo boxSize={ 6 } hash={ data.address } name={ data.name } flexShrink={ 0 }/>
<Link ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all"> <LinkInternal ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all">
<chakra.span dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}/> <chakra.span dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}/>
</Link> </LinkInternal>
</Flex> </Flex>
); );
} }
...@@ -54,9 +55,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => { ...@@ -54,9 +55,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
return ( return (
<Flex alignItems="center"> <Flex alignItems="center">
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/> <Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/>
<Link fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }> <LinkInternal fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }>
<Box as={ shouldHighlightHash ? 'span' : 'mark' }>{ data.block_number }</Box> <Box as={ shouldHighlightHash ? 'span' : 'mark' }>{ data.block_number }</Box>
</Link> </LinkInternal>
</Flex> </Flex>
); );
} }
......
import { Tr, Td, Text, Link, Flex, Icon, Box } from '@chakra-ui/react'; import { Tr, Td, Text, Flex, Icon, Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { SearchResultItem } from 'types/api/search'; import type { SearchResultItem } from 'types/api/search';
...@@ -11,6 +11,7 @@ import Address from 'ui/shared/address/Address'; ...@@ -11,6 +11,7 @@ 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 HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import TokenLogo from 'ui/shared/TokenLogo'; import TokenLogo from 'ui/shared/TokenLogo';
interface Props { interface Props {
...@@ -29,9 +30,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => { ...@@ -29,9 +30,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm"> <Td fontSize="sm">
<Flex alignItems="center"> <Flex alignItems="center">
<TokenLogo boxSize={ 6 } hash={ data.address } name={ data.name } flexShrink={ 0 }/> <TokenLogo boxSize={ 6 } hash={ data.address } name={ data.name } flexShrink={ 0 }/>
<Link ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all"> <LinkInternal ml={ 2 } href={ link('token_index', { hash: data.address }) } fontWeight={ 700 } wordBreak="break-all">
<span dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}/> <span dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}/>
</Link> </LinkInternal>
</Flex> </Flex>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle">
...@@ -52,11 +53,11 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => { ...@@ -52,11 +53,11 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm"> <Td fontSize="sm">
<Flex alignItems="center" overflow="hidden"> <Flex alignItems="center" overflow="hidden">
<AddressIcon address={{ hash: data.address, is_contract: data.type === 'contract', implementation_name: null }} mr={ 2 } flexShrink={ 0 }/> <AddressIcon address={{ hash: data.address, is_contract: data.type === 'contract', implementation_name: null }} mr={ 2 } flexShrink={ 0 }/>
<Link href={ link('address_index', { id: data.address }) } fontWeight={ 700 } overflow="hidden" whiteSpace="nowrap"> <LinkInternal href={ link('address_index', { id: data.address }) } fontWeight={ 700 } overflow="hidden" whiteSpace="nowrap">
<Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block"> <Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block">
<HashStringShortenDynamic hash={ data.address }/> <HashStringShortenDynamic hash={ data.address }/>
</Box> </Box>
</Link> </LinkInternal>
</Flex> </Flex>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle">
...@@ -86,9 +87,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => { ...@@ -86,9 +87,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm"> <Td fontSize="sm">
<Flex alignItems="center"> <Flex alignItems="center">
<Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/> <Icon as={ blockIcon } boxSize={ 6 } mr={ 2 } color="gray.500"/>
<Link fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }> <LinkInternal fontWeight={ 700 } href={ link('block', { id: String(data.block_number) }) }>
<Box as={ shouldHighlightHash ? 'span' : 'mark' }>{ data.block_number }</Box> <Box as={ shouldHighlightHash ? 'span' : 'mark' }>{ data.block_number }</Box>
</Link> </LinkInternal>
</Flex> </Flex>
</Td> </Td>
<Td fontSize="sm" verticalAlign="middle"> <Td fontSize="sm" verticalAlign="middle">
......
...@@ -9,7 +9,7 @@ interface Props { ...@@ -9,7 +9,7 @@ interface Props {
className?: string; className?: string;
} }
const ExternalLink = ({ href, title, className }: Props) => { const LinkExternal = ({ href, title, className }: Props) => {
return ( return (
<Link className={ className } fontSize="sm" display="inline-flex" alignItems="center" target="_blank" href={ href }> <Link className={ className } fontSize="sm" display="inline-flex" alignItems="center" target="_blank" href={ href }>
{ title } { title }
...@@ -18,4 +18,4 @@ const ExternalLink = ({ href, title, className }: Props) => { ...@@ -18,4 +18,4 @@ const ExternalLink = ({ href, title, className }: Props) => {
); );
}; };
export default React.memo(chakra(ExternalLink)); export default React.memo(chakra(LinkExternal));
import type { LinkProps } from '@chakra-ui/react';
import { Link } from '@chakra-ui/react';
import NextLink from 'next/link';
import type { LegacyRef } from 'react';
import React from 'react';
// NOTE! use this component only for links to pages that are completely implemented in new UI
const LinkInternal = (props: LinkProps, ref: LegacyRef<HTMLAnchorElement>) => {
if (!props.href) {
return <Link { ...props } ref={ ref }/>;
}
return (
<NextLink href={ props.href } passHref target={ props.target }>
<Link { ...props } ref={ ref }/>
</NextLink>
);
};
export default React.memo(React.forwardRef(LinkInternal));
import { Heading, Flex, Grid, Tooltip, Link, Icon, chakra } from '@chakra-ui/react'; import { Heading, Flex, Grid, Tooltip, Icon, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import eastArrowIcon from 'icons/arrows/east.svg'; import eastArrowIcon from 'icons/arrows/east.svg';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import LinkInternal from 'ui/shared/LinkInternal';
type Props = { type Props = {
text: string; text: string;
...@@ -42,9 +43,9 @@ const PageTitle = ({ text, additionalsLeft, additionalsRight, withTextAd, backLi ...@@ -42,9 +43,9 @@ const PageTitle = ({ text, additionalsLeft, additionalsRight, withTextAd, backLi
> >
{ backLinkUrl && ( { backLinkUrl && (
<Tooltip label={ backLinkLabel }> <Tooltip label={ backLinkLabel }>
<Link display="inline-flex" href={ backLinkUrl } h="40px"> <LinkInternal display="inline-flex" href={ backLinkUrl } h="40px">
<Icon as={ eastArrowIcon } boxSize={ 6 } transform="rotate(180deg)" margin="auto"/> <Icon as={ eastArrowIcon } boxSize={ 6 } transform="rotate(180deg)" margin="auto"/>
</Link> </LinkInternal>
</Tooltip> </Tooltip>
) } ) }
{ additionalsLeft !== undefined && ( { additionalsLeft !== undefined && (
......
import { Link, chakra, shouldForwardProp, Tooltip, Box } from '@chakra-ui/react'; import { chakra, shouldForwardProp, Tooltip, Box } from '@chakra-ui/react';
import type { HTMLAttributeAnchorTarget } from 'react'; import type { HTMLAttributeAnchorTarget } from 'react';
import React from 'react'; import React from 'react';
...@@ -6,6 +6,7 @@ import useIsMobile from 'lib/hooks/useIsMobile'; ...@@ -6,6 +6,7 @@ import useIsMobile from 'lib/hooks/useIsMobile';
import link from 'lib/link/link'; import link from 'lib/link/link';
import HashStringShorten from 'ui/shared/HashStringShorten'; 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 TruncatedTextTooltip from '../TruncatedTextTooltip'; import TruncatedTextTooltip from '../TruncatedTextTooltip';
...@@ -93,7 +94,7 @@ const AddressLink = (props: Props) => { ...@@ -93,7 +94,7 @@ const AddressLink = (props: Props) => {
} }
return ( return (
<Link <LinkInternal
className={ className } className={ className }
href={ url } href={ url }
target={ target } target={ target }
...@@ -101,7 +102,7 @@ const AddressLink = (props: Props) => { ...@@ -101,7 +102,7 @@ const AddressLink = (props: Props) => {
whiteSpace="nowrap" whiteSpace="nowrap"
> >
{ content } { content }
</Link> </LinkInternal>
); );
}; };
......
...@@ -58,7 +58,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, tx_hash: txHash ...@@ -58,7 +58,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, tx_hash: txHash
<AddressLink <AddressLink
hash={ hasTxInfo ? txHash : address.hash } hash={ hasTxInfo ? txHash : address.hash }
alias={ hasTxInfo ? undefined : address.name } alias={ hasTxInfo ? undefined : address.name }
type={ type } type={ type === 'address' ? 'transaction' : 'address' }
/> />
</Address> </Address>
{ /* api doesn't have find topic feature yet */ } { /* api doesn't have find topic feature yet */ }
......
import { Icon, Link, GridItem, Show, Flex } from '@chakra-ui/react'; import { Icon, GridItem, Show, Flex } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react'; import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
...@@ -7,6 +6,7 @@ import type { TokenTransfer } from 'types/api/tokenTransfer'; ...@@ -7,6 +6,7 @@ import type { TokenTransfer } from 'types/api/tokenTransfer';
import tokenIcon from 'icons/token.svg'; import tokenIcon from 'icons/token.svg';
import link from 'lib/link/link'; import link from 'lib/link/link';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import LinkInternal from 'ui/shared/LinkInternal';
import { flattenTotal } from 'ui/shared/TokenTransfer/helpers'; import { flattenTotal } from 'ui/shared/TokenTransfer/helpers';
import TxDetailsTokenTransfer from './TxDetailsTokenTransfer'; import TxDetailsTokenTransfer from './TxDetailsTokenTransfer';
...@@ -64,9 +64,9 @@ const TxDetailsTokenTransfers = ({ data, txHash }: Props) => { ...@@ -64,9 +64,9 @@ const TxDetailsTokenTransfers = ({ data, txHash }: Props) => {
<Show above="lg" ssr={ false }><GridItem></GridItem></Show> <Show above="lg" ssr={ false }><GridItem></GridItem></Show>
<GridItem fontSize="sm" alignItems="center" display="inline-flex" pl={{ base: '28px', lg: 0 }}> <GridItem fontSize="sm" alignItems="center" display="inline-flex" pl={{ base: '28px', lg: 0 }}>
<Icon as={ tokenIcon } boxSize={ 6 }/> <Icon as={ tokenIcon } boxSize={ 6 }/>
<NextLink href={ viewAllUrl } passHref> <LinkInternal href={ viewAllUrl }>
<Link>View all</Link> View all
</NextLink> </LinkInternal>
</GridItem> </GridItem>
</> </>
) } ) }
......
import { Box, Heading, Text, Flex, Link } from '@chakra-ui/react'; import { Box, Heading, Text, Flex } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
...@@ -8,6 +8,7 @@ import appConfig from 'configs/app/config'; ...@@ -8,6 +8,7 @@ import appConfig from 'configs/app/config';
import getValueWithUnit from 'lib/getValueWithUnit'; import getValueWithUnit from 'lib/getValueWithUnit';
import link from 'lib/link/link'; import link from 'lib/link/link';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import LinkInternal from 'ui/shared/LinkInternal';
import TextSeparator from 'ui/shared/TextSeparator'; import TextSeparator from 'ui/shared/TextSeparator';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
...@@ -89,7 +90,7 @@ const TxAdditionalInfoContent = ({ tx }: { tx: Transaction }) => { ...@@ -89,7 +90,7 @@ const TxAdditionalInfoContent = ({ tx }: { tx: Transaction }) => {
<Text fontWeight="600" as="span">{ tx.position }</Text> <Text fontWeight="600" as="span">{ tx.position }</Text>
</Box> </Box>
</Box> </Box>
<Link fontSize="sm" href={ link('tx', { id: tx.hash }) }>More details</Link> <LinkInternal fontSize="sm" href={ link('tx', { id: tx.hash }) }>More details</LinkInternal>
</> </>
); );
}; };
......
...@@ -3,7 +3,6 @@ import { ...@@ -3,7 +3,6 @@ import {
Box, Box,
Flex, Flex,
Icon, Icon,
Link,
Text, Text,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
...@@ -20,6 +19,7 @@ import Address from 'ui/shared/address/Address'; ...@@ -20,6 +19,7 @@ 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 InOutTag from 'ui/shared/InOutTag'; import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -88,7 +88,7 @@ const TxsListItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement }: ...@@ -88,7 +88,7 @@ const TxsListItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement }:
{ showBlockInfo && tx.block !== null && ( { showBlockInfo && tx.block !== null && (
<Box mt={ 2 }> <Box mt={ 2 }>
<Text as="span">Block </Text> <Text as="span">Block </Text>
<Link href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</Link> <LinkInternal href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</LinkInternal>
</Box> </Box>
) } ) }
<Flex alignItems="center" height={ 6 } mt={ 6 }> <Flex alignItems="center" height={ 6 } mt={ 6 }>
......
...@@ -3,7 +3,6 @@ import { ...@@ -3,7 +3,6 @@ import {
Tr, Tr,
Td, Td,
Tag, Tag,
Link,
Icon, Icon,
VStack, VStack,
Text, Text,
...@@ -23,6 +22,7 @@ import AddressIcon from 'ui/shared/address/AddressIcon'; ...@@ -23,6 +22,7 @@ import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import InOutTag from 'ui/shared/InOutTag'; import InOutTag from 'ui/shared/InOutTag';
import LinkInternal from 'ui/shared/LinkInternal';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip'; import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -99,7 +99,7 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement } ...@@ -99,7 +99,7 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement }
</Td> </Td>
{ showBlockInfo && ( { showBlockInfo && (
<Td> <Td>
{ tx.block && <Link href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</Link> } { tx.block && <LinkInternal href={ link('block', { id: tx.block.toString() }) }>{ tx.block }</LinkInternal> }
</Td> </Td>
) } ) }
<Show above="xl" ssr={ false }> <Show above="xl" ssr={ false }>
......
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