Commit 4c61233e authored by tom's avatar tom

custom tab set based on address tab

parent b8575a7a
import { Box, Hide, Show, Table, Tbody, Th, Tr } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';
import type { UseQueryResult } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import React from 'react';
import type { SocketMessage } from 'lib/socket/types';
import type { Address, AddressBlocksValidatedResponse } from 'types/api/address';
import type { AddressBlocksValidatedResponse } from 'types/api/address';
import appConfig from 'configs/app/config';
import { getResourceKey } from 'lib/api/useApiQuery';
......@@ -22,20 +22,15 @@ import { default as Thead } from 'ui/shared/TheadSticky';
import AddressBlocksValidatedListItem from './blocksValidated/AddressBlocksValidatedListItem';
import AddressBlocksValidatedTableItem from './blocksValidated/AddressBlocksValidatedTableItem';
interface Props {
addressQuery: UseQueryResult<Address>;
}
const AddressBlocksValidated = ({ addressQuery }: Props) => {
const AddressBlocksValidated = () => {
const [ socketAlert, setSocketAlert ] = React.useState(false);
const queryClient = useQueryClient();
const router = useRouter();
const addressHash = String(router.query?.id);
const query = useQueryWithPages({
resourceName: 'address_blocks_validated',
pathParams: { id: addressQuery.data?.hash },
options: {
enabled: Boolean(addressQuery.data),
},
pathParams: { id: addressHash },
});
const handleSocketError = React.useCallback(() => {
......@@ -46,7 +41,7 @@ const AddressBlocksValidated = ({ addressQuery }: Props) => {
setSocketAlert(false);
queryClient.setQueryData(
getResourceKey('address_blocks_validated', { pathParams: { id: addressQuery.data?.hash } }),
getResourceKey('address_blocks_validated', { pathParams: { id: addressHash } }),
(prevData: AddressBlocksValidatedResponse | undefined) => {
if (!prevData) {
return;
......@@ -57,13 +52,13 @@ const AddressBlocksValidated = ({ addressQuery }: Props) => {
items: [ payload.block, ...prevData.items ],
};
});
}, [ addressQuery.data?.hash, queryClient ]);
}, [ addressHash, queryClient ]);
const channel = useSocketChannel({
topic: `blocks:${ addressQuery.data?.hash.toLowerCase() }`,
topic: `blocks:${ addressHash.toLowerCase() }`,
onSocketClose: handleSocketError,
onSocketError: handleSocketError,
isDisabled: addressQuery.isLoading || addressQuery.isError || !addressQuery.data.hash || query.pagination.page !== 1,
isDisabled: !addressHash || query.pagination.page !== 1,
});
useSocketMessage({
channel,
......
import { useQueryClient } from '@tanstack/react-query';
import type { UseQueryResult } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import React from 'react';
import type { SocketMessage } from 'lib/socket/types';
import type { Address, AddressCoinBalanceHistoryResponse } from 'types/api/address';
import type { AddressCoinBalanceHistoryResponse } from 'types/api/address';
import { getResourceKey } from 'lib/api/useApiQuery';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
......@@ -14,20 +14,15 @@ import SocketAlert from 'ui/shared/SocketAlert';
import AddressCoinBalanceChart from './coinBalance/AddressCoinBalanceChart';
import AddressCoinBalanceHistory from './coinBalance/AddressCoinBalanceHistory';
interface Props {
addressQuery: UseQueryResult<Address>;
}
const AddressCoinBalance = ({ addressQuery }: Props) => {
const AddressCoinBalance = () => {
const [ socketAlert, setSocketAlert ] = React.useState(false);
const queryClient = useQueryClient();
const router = useRouter();
const addressHash = String(router.query?.id);
const coinBalanceQuery = useQueryWithPages({
resourceName: 'address_coin_balance',
pathParams: { id: addressQuery.data?.hash },
options: {
enabled: Boolean(addressQuery.data),
},
pathParams: { id: addressHash },
});
const handleSocketError = React.useCallback(() => {
......@@ -38,7 +33,7 @@ const AddressCoinBalance = ({ addressQuery }: Props) => {
setSocketAlert(false);
queryClient.setQueryData(
getResourceKey('address_coin_balance', { pathParams: { id: addressQuery.data?.hash } }),
getResourceKey('address_coin_balance', { pathParams: { id: addressHash } }),
(prevData: AddressCoinBalanceHistoryResponse | undefined) => {
if (!prevData) {
return;
......@@ -52,13 +47,13 @@ const AddressCoinBalance = ({ addressQuery }: Props) => {
],
};
});
}, [ addressQuery.data?.hash, queryClient ]);
}, [ addressHash, queryClient ]);
const channel = useSocketChannel({
topic: `addresses:${ addressQuery.data?.hash.toLowerCase() }`,
topic: `addresses:${ addressHash.toLowerCase() }`,
onSocketClose: handleSocketError,
onSocketError: handleSocketError,
isDisabled: addressQuery.isLoading || addressQuery.isError || !addressQuery.data.hash || coinBalanceQuery.pagination.page !== 1,
isDisabled: !addressHash || coinBalanceQuery.pagination.page !== 1,
});
useSocketMessage({
channel,
......@@ -69,7 +64,7 @@ const AddressCoinBalance = ({ addressQuery }: Props) => {
return (
<>
{ socketAlert && <SocketAlert mb={ 6 }/> }
<AddressCoinBalanceChart addressQuery={ addressQuery }/>
<AddressCoinBalanceChart addressHash={ addressHash }/>
<AddressCoinBalanceHistory query={ coinBalanceQuery }/>
</>
);
......
import type { UseQueryResult } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { Address } from 'types/api/address';
import appConfig from 'configs/app/config';
import useApiQuery from 'lib/api/useApiQuery';
import ChartWidget from 'ui/shared/chart/ChartWidget';
interface Props {
addressQuery: UseQueryResult<Address>;
addressHash: string;
}
const AddressCoinBalanceChart = ({ addressQuery }: Props) => {
const AddressCoinBalanceChart = ({ addressHash }: Props) => {
const { data, isLoading, isError } = useApiQuery('address_coin_balance_chart', {
pathParams: { id: addressQuery.data?.hash },
queryOptions: { enabled: Boolean(addressQuery.data?.hash) },
pathParams: { id: addressHash },
});
const items = React.useMemo(() => data?.map(({ date, value }) => ({
......
import { Box } from '@chakra-ui/react';
import React from 'react';
const AddressLogs = () => {
return <Box>FOO BAR</Box>;
};
export default AddressLogs;
......@@ -5,15 +5,18 @@ import React from 'react';
import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
import useApiQuery from 'lib/api/useApiQuery';
import notEmpty from 'lib/notEmpty';
import AddressBlocksValidated from 'ui/address/AddressBlocksValidated';
import AddressCoinBalance from 'ui/address/AddressCoinBalance';
import AddressDetails from 'ui/address/AddressDetails';
import AddressInternalTxs from 'ui/address/AddressInternalTxs';
import AddressTokenTransfers from 'ui/address/AddressTokenTransfers';
import AddressTxs from 'ui/address/AddressTxs';
import AddressLogs from 'ui/address/logs/AddressLogs';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
import SkeletonTabs from 'ui/shared/skeletons/SkeletonTabs';
const AddressPageContent = () => {
const router = useRouter();
......@@ -29,16 +32,21 @@ const AddressPageContent = () => {
...(addressQuery.data?.watchlist_names || []),
].map((tag) => <Tag key={ tag.label }>{ tag.display_name }</Tag>);
const tabs: Array<RoutedTab> = [
{ id: 'txs', title: 'Transactions', component: <AddressTxs/> },
{ id: 'token_transfers', title: 'Token transfers', component: <AddressTokenTransfers/> },
{ id: 'tokens', title: 'Tokens', component: null },
{ id: 'internal_txns', title: 'Internal txns', component: <AddressInternalTxs/> },
{ id: 'coin_balance_history', title: 'Coin balance history', component: <AddressCoinBalance addressQuery={ addressQuery }/> },
// temporary show this tab in all address
// later api will return info about available tabs
{ id: 'blocks_validated', title: 'Blocks validated', component: <AddressBlocksValidated addressQuery={ addressQuery }/> },
];
const isContract = addressQuery.data?.is_contract;
const tabs: Array<RoutedTab> = React.useMemo(() => {
return [
{ id: 'txs', title: 'Transactions', component: <AddressTxs/> },
{ id: 'token_transfers', title: 'Token transfers', component: <AddressTokenTransfers/> },
{ id: 'tokens', title: 'Tokens', component: null },
{ id: 'internal_txns', title: 'Internal txns', component: <AddressInternalTxs/> },
{ id: 'coin_balance_history', title: 'Coin balance history', component: <AddressCoinBalance/> },
// temporary show this tab in all address
// later api will return info about available tabs
{ id: 'blocks_validated', title: 'Blocks validated', component: <AddressBlocksValidated/> },
isContract ? { id: 'logs', title: 'Logs', component: <AddressLogs/> } : undefined,
].filter(notEmpty);
}, [ isContract ]);
return (
<Page>
......@@ -51,7 +59,7 @@ const AddressPageContent = () => {
) }
</Flex>
<AddressDetails addressQuery={ addressQuery }/>
<RoutedTabs tabs={ tabs } tabListProps={{ mt: 8 }}/>
{ addressQuery.isLoading ? <SkeletonTabs/> : <RoutedTabs tabs={ tabs } tabListProps={{ mt: 8 }}/> }
</Page>
);
};
......
import { Flex, Skeleton, chakra } from '@chakra-ui/react';
import React from 'react';
interface Props {
className?: string;
}
const SkeletonTabs = ({ className }: Props) => {
return (
<Flex my={ 8 } className={ className }>
<Skeleton h={ 6 } my={ 2 } mx={ 4 } w="100px"/>
<Skeleton h={ 6 } my={ 2 } mx={ 4 } w="120px"/>
<Skeleton h={ 6 } my={ 2 } mx={ 4 } w="80px" display={{ base: 'none', lg: 'block' }}/>
<Skeleton h={ 6 } my={ 2 } mx={ 4 } w="100px" display={{ base: 'none', lg: 'block' }}/>
<Skeleton h={ 6 } my={ 2 } mx={ 4 } w="140px" display={{ base: 'none', lg: 'block' }}/>
</Flex>
);
};
export default chakra(SkeletonTabs);
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