diff --git a/packages/app-explorer/src/systems/Block/components/BlockEfficiencyItem.tsx b/packages/app-explorer/src/systems/Block/components/BlockEfficiencyItem.tsx index e145d1ec..f40ffdde 100644 --- a/packages/app-explorer/src/systems/Block/components/BlockEfficiencyItem.tsx +++ b/packages/app-explorer/src/systems/Block/components/BlockEfficiencyItem.tsx @@ -9,16 +9,14 @@ export default function BlockEfficiencyItem({ current, total, }: BlockEfficiencyItemProps) { - // Convert current and total to millions const currentInMillions = current / 1_000_000; const totalInMillions = total / 1_000_000; - // Calculate progress percentage const progress = (current / total) * 100; return ( - + {/* Format current and total as M (millions) */} @@ -39,7 +37,7 @@ export default function BlockEfficiencyItem({
100 ? 100 : progress}%` }} />
diff --git a/packages/app-explorer/src/systems/Block/components/BlockItem.tsx b/packages/app-explorer/src/systems/Block/components/BlockItem.tsx index f566d2ac..252c7770 100644 --- a/packages/app-explorer/src/systems/Block/components/BlockItem.tsx +++ b/packages/app-explorer/src/systems/Block/components/BlockItem.tsx @@ -1,4 +1,5 @@ import { Box, Copyable, HStack, Text, VStack } from '@fuels/ui'; +import Link from 'next/link'; export interface BlockItemProps { blockId: string; @@ -7,20 +8,44 @@ export interface BlockItemProps { export default function BlockItem({ blockId, ethValue }: BlockItemProps) { return ( - - + + #{blockId} - - {ethValue} ETH - + +
+ { + + + + + + + + } + + {ethValue} ETH + +
+
); } diff --git a/packages/app-explorer/src/systems/Block/components/BlockTimeItem.tsx b/packages/app-explorer/src/systems/Block/components/BlockTimeItem.tsx index 711346e1..4941d2db 100644 --- a/packages/app-explorer/src/systems/Block/components/BlockTimeItem.tsx +++ b/packages/app-explorer/src/systems/Block/components/BlockTimeItem.tsx @@ -1,28 +1,25 @@ -import { Text, VStack } from '@fuels/ui'; +import { Box, Text, VStack, useBreakpoints } from '@fuels/ui'; type BlockTimeItemProps = { - time: Date; timeAgo: string; }; -export default function BlockTimeItem({ time, timeAgo }: BlockTimeItemProps) { - const timeDate = new Date(time); - - const formattedTime = timeDate.toLocaleString('en-US', { - year: 'numeric', - month: 'short', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - hour12: true, - }); +export default function BlockTimeItem({ timeAgo }: BlockTimeItemProps) { + const { isMobile } = useBreakpoints(); return ( - - {timeAgo} - - {formattedTime} - - + + + + {timeAgo} + + + ); } diff --git a/packages/app-explorer/src/systems/Block/components/BlocksTable.tsx b/packages/app-explorer/src/systems/Block/components/BlocksTable.tsx index 4c709d93..8e46ed1d 100644 --- a/packages/app-explorer/src/systems/Block/components/BlocksTable.tsx +++ b/packages/app-explorer/src/systems/Block/components/BlocksTable.tsx @@ -1,194 +1,18 @@ import { GQLBlocksQuery } from '@fuel-explorer/graphql'; -import { GridTable } from '@fuels/ui'; -import { Link } from '@fuels/ui'; -import NextLink from 'next/link'; +import { + GridTable, + HStack, + Text, + Tooltip, + VStack, + useBreakpoints, +} from '@fuels/ui'; +import { IconPointFilled } from '@tabler/icons-react'; +import Link from 'next/link'; +import { Alignment } from 'react-data-table-component'; import BlockEfficiencyItem from './BlockEfficiencyItem'; -import BlockHashItem from './BlockHashItem'; import BlockItem from './BlockItem'; import BlockTimeItem from './BlockTimeItem'; -import BlockValidatorItem from './BlockValidatorItem'; - -const columns = [ - { - name: ( -
- Block -
- ), - cell: (row: any) => { - const totalGasUsed = ( - parseFloat(row.node.totalGasUsed) / - 10 ** 9 - ).toString(); - return ( - - ); - }, - sortable: false, - }, - { - name: ( -
-
- Blockhash - - - - - -
-
- A unique identifier for this block, generated by hashing its data. -
-
-
- ), - cell: (row: any) => ( - - ), - sortable: false, - }, - { - name: ( -
- Transactions -
- ), - cell: (row: any) => ( -
- {row.node.header.transactionsCount} -
- ), - sortable: false, - }, - { - name: ( -
-
- Rewards - - - - - -
-
- The total reward distributed to the validator for producing this - block. -
-
-
- ), - cell: (row: any) => { - const mintTransaction = row.node.transactions.find( - (trans: any) => trans.mintAmount != null, - ); - return ( -
- {mintTransaction ? mintTransaction.mintAmount : 'No mint amount'}{' '} -
- ); - }, - sortable: false, - }, - - { - name: ( -
- Producer -
- ), - cell: (row: any) => ( -
- -
- ), - sortable: false, - }, - { - name: ( -
-
- Efficiency - - - - - -
-
- The percentage of block resources utilized by transactions. -
-
-
- ), - cell: (row: any) => ( -
- -
- ), - sortable: false, - }, - { - name: ( -
- Time -
- ), - cell: (row: any) => { - const unixTimestamp = row.node.time.rawUnix; - const date = new Date(unixTimestamp * 1000); - - return ( -
- -
- ); - }, - sortable: false, - }, - { - name: '', - cell: (row: any) => ( - - View - - ), - sortable: false, - }, -]; type BlocksTableProps = { blocks: GQLBlocksQuery['blocks']; @@ -208,11 +32,268 @@ function BlocksTable({ const handlePageChanged = (pageNumber: number) => { onPageChanged(pageNumber); }; + const { isMobile, isTablet, isLaptop } = useBreakpoints(); + const columns = [ + { + name: ( +
+ Block +
+ ), + cell: (row: any) => { + const totalGasUsed = ( + parseFloat(row.node.totalGasUsed) / + 10 ** 9 + ).toString(); + return ( + <> +
+ +
+ + ); + }, + sortable: false, + }, + + { + name: ( +
+ +
+ Transactions {' '} + + {isLaptop && ( + + + + )} + +
+
+
+ ), + cell: (row: any) => ( + + + {row.node.header.transactionsCount} + + + ), + sortable: false, + }, + { + name: ( +
+ +
+ daHeight + + {isLaptop && ( + + + + )} + +
+
+
+ ), + cell: (row: any) => { + return ( + + + {row.node.header.daHeight} + + + ); + }, + sortable: false, + }, + { + name: ( +
+ +
+ Rewards + + {isLaptop && ( + + + + )} + +
+
+
+ ), + cell: (row: any) => { + const mintTransaction = row.node.transactions.find( + (trans: any) => trans.mintAmount != null, + ); + return ( + +
+ {mintTransaction + ? `${ + mintTransaction.mintAmount > 0 + ? (mintTransaction.mintAmount / 10 ** 9).toFixed(9) + : 0 + } ETH` + : 'No mint amount'}{' '} +
+ + ); + }, + sortable: false, + }, + + { + name: ( +
+ +
+ Efficiency + + {isLaptop && ( + + + + )} + +
+
+
+ ), + cell: (row: any) => ( + +
+ +
+ + ), + sortable: false, + }, + { + name: ( +
+ Time +
+ ), + cell: (row: any) => { + return ( + + {!isMobile ? ( + + ) : ( + + + + + Txn Count + + +
+ {row.node.header.transactionsCount} +
+
+
+ )} + + ); + }, + sortable: false, + }, + ]; + if (isMobile) { + columns.splice(1, 4); + } + if (isTablet && !isLaptop) { + columns.splice(4, 1); + } return (
- + Blocks - - -

Home

-
- -

View All Blocks

-
); diff --git a/packages/app-explorer/src/systems/Block/screens/BlockScreen.tsx b/packages/app-explorer/src/systems/Block/screens/BlockScreen.tsx index 527883f7..757af1f1 100644 --- a/packages/app-explorer/src/systems/Block/screens/BlockScreen.tsx +++ b/packages/app-explorer/src/systems/Block/screens/BlockScreen.tsx @@ -3,13 +3,14 @@ import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect, useState } from 'react'; import { GQLBlocksQuery } from '@fuel-explorer/graphql'; +import { LoadingBox, LoadingWrapper } from '@fuels/ui'; import { getBlocks } from '../actions/get-blocks'; import BlocksTable from '../components/BlocksTable'; import { Hero } from '../components/Hero'; export const BlocksScreen = () => { const router = useRouter(); - const searchParams = useSearchParams(); + const _searchParams = useSearchParams(); const [data, setData] = useState( undefined, @@ -18,7 +19,7 @@ export const BlocksScreen = () => { const [totalPages, setTotalPages] = useState(null); const [currentPage, setCurrentPage] = useState(1); const [currentCursor, setCurrentCursor] = useState(null); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const limit = 10; const fetchBlockData = async ( @@ -72,42 +73,49 @@ export const BlocksScreen = () => { setCurrentPage(newPageNumber); setCurrentCursor(newCursor); if (newPageNumber === 1) { - router.push('/blocks'); + router.push('/blocks', { scroll: false }); return; } - router.push(`/blocks?page=${newPageNumber}&cursor=${newCursor}`); + router.push(`/blocks?page=${newPageNumber}&cursor=${newCursor}`, { + scroll: false, + }); } }; - useEffect(() => { - const page = parseInt(searchParams.get('page') || '1'); - const cursor = searchParams.get('cursor') || null; - - setCurrentPage(page); - setCurrentCursor(cursor); - setDir(page > currentPage ? 'after' : 'before'); - }, [searchParams]); - useEffect(() => { fetchBlockData(currentCursor, dir); }, [currentCursor, dir]); return ( - + - {loading ? ( -

Loading blocks...

- ) : ( - data && ( - - ) - )} + + {[...Array(10)].map((_, index) => ( + + ))} + +
+ } + regularEl={ + data && ( + <> + + + ) + } + />
); }; diff --git a/packages/app-explorer/src/systems/Home/components/Hero/Hero.tsx b/packages/app-explorer/src/systems/Home/components/Hero/Hero.tsx index a2101549..a5a80d8d 100644 --- a/packages/app-explorer/src/systems/Home/components/Hero/Hero.tsx +++ b/packages/app-explorer/src/systems/Home/components/Hero/Hero.tsx @@ -173,10 +173,10 @@ function Hero() {
} + loadingEl={} regularEl={ } + fallback={} > @@ -185,11 +185,11 @@ function Hero() {
} + fallback={} > } + loadingEl={} regularEl={} /> diff --git a/packages/ui/src/components/GridTable/GridTable.tsx b/packages/ui/src/components/GridTable/GridTable.tsx index ded48a18..2a115fce 100644 --- a/packages/ui/src/components/GridTable/GridTable.tsx +++ b/packages/ui/src/components/GridTable/GridTable.tsx @@ -26,6 +26,7 @@ export const GridTable = ({ tableWrapper: { style: { borderRadius: '0', + padding: '2px', }, }, table: { @@ -39,6 +40,8 @@ export const GridTable = ({ color: '#9f9f9f', fontWeight: '600', textAlign: 'left', + justifyContent: 'left', + borderBottom: 'none', }, }, headCells: { @@ -48,17 +51,19 @@ export const GridTable = ({ fontWeight: '600', fontSize: '16px', textAlign: 'left', + justifyContent: 'left', }, }, rows: { style: { cursor: 'pointer', - backgroundColor: 'var(--gray-2)', + backgroundColor: 'var(--gray-13)', fontWeight: '400', borderRadius: '12px', - marginBottom: '8px', - '&:hover': { - backgroundColor: 'var(--gray-a1)', + border: '1px solid var(--gray-5)', + margin: '0.7rem 0', + '&:not(:last-of-type)': { + borderBottomColor: 'tranparent', }, }, }, @@ -69,29 +74,29 @@ export const GridTable = ({ paddingLeft: '0.5rem', paddingRight: '0.5rem', color: 'var(--gray-table-text)', - paddingTop: '0.4rem', - paddingBottom: '0.4rem', + paddingTop: '0.6rem', + paddingBottom: '0.6rem', backgroundColor: 'transparent', fontWeight: '400', }, }, pagination: { style: { - backgroundColor: 'var(--gray-2)', - color: '#f0f0f0', + backgroundColor: 'var(--gray-3)', + color: 'var(--gray-2)', }, pageButtonsStyle: { padding: '8px 16px', - margin: '0 4px', - color: '#f0f0f0', + margin: '0 2px', + color: 'var(--gray-2)', borderRadius: '4px', - backgroundColor: 'var(--gray-2)', + backgroundColor: 'var(--gray-4)', '&.selected': { - backgroundColor: 'rgba(255, 255, 255, 0.1)', + backgroundColor: 'var(--gray-4)', fontWeight: 'bold', }, '&:hover': { - backgroundColor: 'rgba(255, 255, 255, 0.2)', + backgroundColor: 'var(--gray-4)', }, }, }, @@ -100,17 +105,75 @@ export const GridTable = ({ const Pagination: React.FC = () => { return ( ← Previous} // Left Arrow - nextLabel={Next →} // Right Arrow - breakLabel={'...'} + previousLabel={ + <> + {currentPage > 1 && ( + + )} + + + } + nextLabel={ + + } + breakLabel={''} pageCount={pageCount} - marginPagesDisplayed={2} - pageRangeDisplayed={5} + marginPagesDisplayed={0} + pageRangeDisplayed={0} onPageChange={(page) => handlePagination(page)} containerClassName={'pagination'} activeClassName={'selected'} disabledClassName={'disabled'} - pageLinkClassName={'page-link'} + previousLinkClassName={'previous-link'} + nextLinkClassName={'next-link'} forcePage={currentPage !== 0 ? currentPage - 1 : 0} /> ); @@ -124,6 +187,21 @@ export const GridTable = ({ return (