Commit ad71c2b3 authored by tom's avatar tom

prev next block

parent ac627348
......@@ -5,7 +5,7 @@ import type { Block } from 'types/api/block';
export default function getBlockReward(block: Block) {
const txFees = utils.parseUnits(block.tx_fees || '0', 'wei');
const burntFees = utils.parseUnits(String(block.burnt_fees || '0'), 'wei');
const totalReward = utils.parseUnits(String(block.rewards?.find(({ type }) => type === 'Miner Reward' || type === 'Validator Reward')?.reward) || '0', 'wei');
const totalReward = utils.parseUnits(String(block.rewards?.find(({ type }) => type === 'Miner Reward' || type === 'Validator Reward')?.reward || '0'), 'wei');
const staticReward = totalReward.sub(txFees).add(burntFees);
return {
......
......@@ -136,6 +136,10 @@ const variantSubtle = defineStyle((props) => {
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
_hover: {
color: 'blue.400',
_disabled: {
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
bg: mode('blackAlpha.200', 'whiteAlpha.200')(props),
},
},
};
}
......
import { Grid, GridItem, Text, Icon, Link, Box, Tooltip } from '@chakra-ui/react';
import { Grid, GridItem, Text, Icon, Link, Box, Tooltip, Alert } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import { utils } from 'ethers';
import { useRouter } from 'next/router';
......@@ -11,6 +11,7 @@ import clockIcon from 'icons/clock.svg';
import flameIcon from 'icons/flame.svg';
import getBlockReward from 'lib/block/getBlockReward';
import dayjs from 'lib/date/dayjs';
import type { ErrorType } from 'lib/hooks/useFetch';
import useFetch from 'lib/hooks/useFetch';
import useNetwork from 'lib/hooks/useNetwork';
import { space } from 'lib/html-entities';
......@@ -33,7 +34,7 @@ const BlockDetails = () => {
const network = useNetwork();
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, Block>(
const { data, isLoading, isError, error } = useQuery<unknown, ErrorType<{ status: number }>, Block>(
[ 'block', router.query.id ],
async() => await fetch(`/api/blocks/${ router.query.id }`),
{
......@@ -49,12 +50,19 @@ const BlockDetails = () => {
});
}, []);
const handlePrevNextClick = React.useCallback((direction: 'prev' | 'next') => {
const increment = direction === 'next' ? +1 : -1;
const url = link('block_index', { id: String(Number(router.query.id) + increment) });
router.push(url, undefined, { shallow: true });
}, [ link, router ]);
if (isLoading) {
return <BlockDetailsSkeleton/>;
}
if (isError) {
return <DataFetchAlert/>;
const is404 = error?.error?.status === 404;
return is404 ? <Alert>This block has not been processed yet.</Alert> : <DataFetchAlert/>;
}
const sectionGap = <GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>;
......@@ -67,7 +75,13 @@ const BlockDetails = () => {
hint="The block height of a particular block is defined as the number of blocks preceding it in the blockchain."
>
{ data.height }
<PrevNext ml={ 6 }/>
<PrevNext
ml={ 6 }
onClick={ handlePrevNextClick }
prevLabel="View previous block"
nextLabel="View next block"
isPrevDisabled={ router.query.id === '0' }
/>
</DetailsInfoItem>
<DetailsInfoItem
title="Size"
......@@ -235,6 +249,7 @@ const BlockDetails = () => {
</Box>
<CopyToClipboard text={ data.hash }/>
</DetailsInfoItem>
{ data.height > 0 && (
<DetailsInfoItem
title="Parent hash"
hint="The hash of the block from which this block was generated."
......@@ -243,6 +258,7 @@ const BlockDetails = () => {
<AddressLink hash={ data.parent_hash } type="block" id={ String(data.height - 1) }/>
<CopyToClipboard text={ data.parent_hash }/>
</DetailsInfoItem>
) }
{ /* api doesn't support state root yet */ }
{ /* <DetailsInfoItem
title="State root"
......
import { Box, Icon, IconButton, chakra } from '@chakra-ui/react';
import { Box, Icon, IconButton, chakra, Tooltip } from '@chakra-ui/react';
import React from 'react';
import eastArrow from 'icons/arrows/east-mini.svg';
interface Props {
className?: string;
onClick: (direction: 'prev' | 'next') => void;
prevLabel?: string;
nextLabel?: string;
isPrevDisabled?: boolean;
isNextDisabled?: boolean;
}
const PrevNext = ({ className }: Props) => {
const PrevNext = ({ className, onClick, prevLabel, nextLabel, isPrevDisabled, isNextDisabled }: Props) => {
const handelPrevClick = React.useCallback(() => {
onClick('prev');
}, [ onClick ]);
const handelNextClick = React.useCallback(() => {
onClick('next');
}, [ onClick ]);
return (
<Box className={ className }>
<Tooltip label={ prevLabel }>
<IconButton
aria-label="prev"
icon={ <Icon as={ eastArrow } boxSize={ 6 }/> }
......@@ -17,7 +31,11 @@ const PrevNext = ({ className }: Props) => {
borderRadius="sm"
variant="subtle"
colorScheme="gray"
onClick={ handelPrevClick }
disabled={ isPrevDisabled }
/>
</Tooltip>
<Tooltip label={ nextLabel }>
<IconButton
aria-label="next"
icon={ <Icon as={ eastArrow }boxSize={ 6 } transform="rotate(180deg)"/> }
......@@ -26,7 +44,10 @@ const PrevNext = ({ className }: Props) => {
variant="subtle"
colorScheme="gray"
ml="10px"
onClick={ handelNextClick }
disabled={ isNextDisabled }
/>
</Tooltip>
</Box>
);
};
......
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