mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
Merge pull request #542 from blockscout/token-logo
add token logo and back links for token and address pages
This commit is contained in:
+12
-1
@@ -7,6 +7,8 @@ import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
|
||||
|
||||
import iconSuccess from 'icons/status/success.svg';
|
||||
import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { useAppContext } from 'lib/appContext';
|
||||
import isBrowser from 'lib/isBrowser';
|
||||
import notEmpty from 'lib/notEmpty';
|
||||
import AddressBlocksValidated from 'ui/address/AddressBlocksValidated';
|
||||
import AddressCoinBalance from 'ui/address/AddressCoinBalance';
|
||||
@@ -37,6 +39,13 @@ const TOKEN_TABS = Object.values(tokenTabsByType);
|
||||
const AddressPageContent = () => {
|
||||
const router = useRouter();
|
||||
|
||||
const appProps = useAppContext();
|
||||
const isInBrowser = isBrowser();
|
||||
|
||||
const referrer = isInBrowser ? window.document.referrer : appProps.referrer;
|
||||
|
||||
const hasGoBackLink = referrer && referrer.includes('/accounts');
|
||||
|
||||
const tabsScrollRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
const addressQuery = useApiQuery('address', {
|
||||
@@ -121,7 +130,9 @@ const AddressPageContent = () => {
|
||||
) : (
|
||||
<PageTitle
|
||||
text={ `${ addressQuery.data?.is_contract ? 'Contract' : 'Address' } details` }
|
||||
additionals={ tagsNode }
|
||||
additionalsRight={ tagsNode }
|
||||
backLinkUrl={ hasGoBackLink ? referrer : undefined }
|
||||
backLinkLabel="Back to top accounts list"
|
||||
/>
|
||||
) }
|
||||
<AddressDetails addressQuery={ addressQuery } scrollRef={ tabsScrollRef }/>
|
||||
|
||||
@@ -22,6 +22,11 @@ const hooksConfig = {
|
||||
// FIXME: idk why mobile test doesn't work (it's ok locally)
|
||||
// test('base view +@mobile +@dark-mode', async({ mount, page }) => {
|
||||
test('base view +@dark-mode', async({ mount, page }) => {
|
||||
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
|
||||
status: 200,
|
||||
body: '',
|
||||
}));
|
||||
|
||||
await page.route(TOKEN_API_URL, (route) => route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(tokenInfo),
|
||||
|
||||
+30
-4
@@ -1,17 +1,21 @@
|
||||
import { Skeleton, Box } from '@chakra-ui/react';
|
||||
import { Skeleton, Box, Flex, SkeletonCircle } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
|
||||
|
||||
import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { useAppContext } from 'lib/appContext';
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
|
||||
import isBrowser from 'lib/isBrowser';
|
||||
import TextAd from 'ui/shared/ad/TextAd';
|
||||
import Page from 'ui/shared/Page/Page';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import type { Props as PaginationProps } from 'ui/shared/Pagination';
|
||||
import Pagination from 'ui/shared/Pagination';
|
||||
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
|
||||
import TokenLogo from 'ui/shared/TokenLogo';
|
||||
import TokenContractInfo from 'ui/token/TokenContractInfo';
|
||||
import TokenDetails from 'ui/token/TokenDetails';
|
||||
import TokenHolders from 'ui/token/TokenHolders/TokenHolders';
|
||||
@@ -23,6 +27,13 @@ const TokenPageContent = () => {
|
||||
const router = useRouter();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const appProps = useAppContext();
|
||||
const isInBrowser = isBrowser();
|
||||
|
||||
const referrer = isInBrowser ? window.document.referrer : appProps.referrer;
|
||||
|
||||
const hasGoBackLink = referrer && referrer.includes('/tokens');
|
||||
|
||||
const scrollRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
const tokenQuery = useApiQuery('token', {
|
||||
@@ -82,9 +93,24 @@ const TokenPageContent = () => {
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{ tokenQuery.isLoading ?
|
||||
<Skeleton w="500px" h={ 10 } mb={ 6 }/> :
|
||||
<PageTitle text={ `${ tokenQuery.data?.name } (${ tokenQuery.data?.symbol }) token` }/> }
|
||||
{ tokenQuery.isLoading ? (
|
||||
<Flex alignItems="center" mb={ 6 }>
|
||||
<SkeletonCircle w={ 6 } h={ 6 } mr={ 3 }/>
|
||||
<Skeleton w="500px" h={ 10 }/>
|
||||
</Flex>
|
||||
) : (
|
||||
<>
|
||||
<TextAd mb={ 6 }/>
|
||||
<PageTitle
|
||||
text={ `${ tokenQuery.data?.name } (${ tokenQuery.data?.symbol }) token` }
|
||||
backLinkUrl={ hasGoBackLink ? referrer : undefined }
|
||||
backLinkLabel="Back to tokens list"
|
||||
additionalsLeft={ (
|
||||
<TokenLogo hash={ tokenQuery.data?.address } name={ tokenQuery.data?.name } boxSize={ 6 }/>
|
||||
) }
|
||||
/>
|
||||
</>
|
||||
) }
|
||||
<TokenContractInfo tokenQuery={ tokenQuery }/>
|
||||
<TokenDetails tokenQuery={ tokenQuery }/>
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ const TransactionPageContent = () => {
|
||||
<TextAd mb={ 6 }/>
|
||||
<PageTitle
|
||||
text="Transaction details"
|
||||
additionals={ additionals }
|
||||
additionalsRight={ additionals }
|
||||
backLinkUrl={ hasGoBackLink ? referrer : undefined }
|
||||
backLinkLabel="Back to transactions list"
|
||||
/>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
@@ -1,6 +1,8 @@
|
||||
// import { Icon } from '@chakra-ui/react';
|
||||
import { test, expect } from '@playwright/experimental-ct-react';
|
||||
import React from 'react';
|
||||
|
||||
// import plusIcon from 'icons/plus.svg';
|
||||
import * as textAdMock from 'mocks/ad/textAd';
|
||||
import TestApp from 'playwright/TestApp';
|
||||
|
||||
@@ -32,6 +34,10 @@ test('default view +@mobile', async({ mount }) => {
|
||||
});
|
||||
|
||||
test('with text ad, back link and addons +@mobile +@dark-mode', async({ mount }) => {
|
||||
// https://github.com/microsoft/playwright/issues/15620
|
||||
// not possible to pass component as a prop in tests
|
||||
// const left = <Icon as={ plusIcon }/>;
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<PageTitle
|
||||
@@ -39,7 +45,8 @@ test('with text ad, back link and addons +@mobile +@dark-mode', async({ mount })
|
||||
withTextAd
|
||||
backLinkLabel="Back"
|
||||
backLinkUrl="back"
|
||||
additionals="Privet"
|
||||
// additionalsLeft={ left }
|
||||
additionalsRight="Privet"
|
||||
/>
|
||||
</TestApp>,
|
||||
);
|
||||
@@ -55,7 +62,7 @@ test('long title with text ad, back link and addons +@mobile', async({ mount })
|
||||
withTextAd
|
||||
backLinkLabel="Back"
|
||||
backLinkUrl="back"
|
||||
additionals="Privet, kak dela?"
|
||||
additionalsRight="Privet, kak dela?"
|
||||
/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Heading, Flex, Tooltip, Link, Icon, chakra } from '@chakra-ui/react';
|
||||
import { Heading, Flex, Grid, Tooltip, Link, Icon, chakra } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import eastArrowIcon from 'icons/arrows/east.svg';
|
||||
@@ -6,23 +6,20 @@ import TextAd from 'ui/shared/ad/TextAd';
|
||||
|
||||
type Props = {
|
||||
text: string;
|
||||
additionals?: React.ReactNode;
|
||||
additionalsLeft?: React.ReactNode;
|
||||
additionalsRight?: React.ReactNode;
|
||||
withTextAd?: boolean;
|
||||
className?: string;
|
||||
backLinkLabel?: string;
|
||||
backLinkUrl?: string;
|
||||
}
|
||||
|
||||
const PageTitle = ({ text, additionals, withTextAd, backLinkUrl, backLinkLabel, className }: Props) => {
|
||||
const PageTitle = ({ text, additionalsLeft, additionalsRight, withTextAd, backLinkUrl, backLinkLabel, className }: Props) => {
|
||||
const title = (
|
||||
<Heading
|
||||
as="h1"
|
||||
size="lg"
|
||||
flex="none"
|
||||
overflow="hidden"
|
||||
textOverflow="ellipsis"
|
||||
whiteSpace="nowrap"
|
||||
width={ backLinkUrl ? 'calc(100% - 36px)' : '100%' }
|
||||
>
|
||||
{ text }
|
||||
</Heading>
|
||||
@@ -39,22 +36,25 @@ const PageTitle = ({ text, additionals, withTextAd, backLinkUrl, backLinkLabel,
|
||||
className={ className }
|
||||
>
|
||||
<Flex flexWrap="wrap" columnGap={ 3 } alignItems="center" width={ withTextAd ? 'unset' : '100%' }>
|
||||
<Flex
|
||||
flexWrap="nowrap"
|
||||
alignItems="center"
|
||||
<Grid
|
||||
templateColumns={ [ backLinkUrl && 'auto', additionalsLeft && 'auto', '1fr' ].filter(Boolean).join(' ') }
|
||||
columnGap={ 3 }
|
||||
overflow="hidden"
|
||||
>
|
||||
{ backLinkUrl && (
|
||||
<Tooltip label={ backLinkLabel }>
|
||||
<Link display="inline-flex" href={ backLinkUrl }>
|
||||
<Icon as={ eastArrowIcon } boxSize={ 6 } transform="rotate(180deg)"/>
|
||||
<Link display="inline-flex" href={ backLinkUrl } h="40px">
|
||||
<Icon as={ eastArrowIcon } boxSize={ 6 } transform="rotate(180deg)" margin="auto"/>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
) }
|
||||
{ additionalsLeft !== undefined && (
|
||||
<Flex h="40px" alignItems="center">
|
||||
{ additionalsLeft }
|
||||
</Flex>
|
||||
) }
|
||||
{ title }
|
||||
</Flex>
|
||||
{ additionals }
|
||||
</Grid>
|
||||
{ additionalsRight }
|
||||
</Flex>
|
||||
{ withTextAd && <TextAd flexShrink={ 100 }/> }
|
||||
</Flex>
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
@@ -69,11 +69,6 @@ const TokenDetails = ({ tokenQuery }: Props) => {
|
||||
);
|
||||
}
|
||||
|
||||
// we show error in parent component, this is only for TS
|
||||
if (tokenQuery.isError) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
exchange_rate: exchangeRate,
|
||||
total_supply: totalSupply,
|
||||
|
||||
Reference in New Issue
Block a user