From 9b2c25cebda513efd249e2d8df8d31e289fa3d22 Mon Sep 17 00:00:00 2001 From: ArtemkaDev Date: Sun, 24 Nov 2024 14:05:04 +0200 Subject: [PATCH] extra menu --- src/components/crypto/charts.tsx | 17 +-- src/components/crypto/info.tsx | 195 +++++++++++++++++++++++-------- src/components/crypto/utils.ts | 12 ++ 3 files changed, 162 insertions(+), 62 deletions(-) create mode 100644 src/components/crypto/utils.ts diff --git a/src/components/crypto/charts.tsx b/src/components/crypto/charts.tsx index 156f102..86f4e50 100644 --- a/src/components/crypto/charts.tsx +++ b/src/components/crypto/charts.tsx @@ -28,19 +28,8 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { formatHashrate } from "./utils"; -function formatHashrate(difficulty: any): string { - const units = ["H/s", "KH/s", "MH/s", "GH/s", "TH/s", "PH/s"]; - let value = Number(difficulty); - let unitIndex = 0; - - while (value >= 1000 && unitIndex < units.length - 1) { - value /= 1000; - unitIndex++; - } - - return `${value.toFixed(2)} ${units[unitIndex]}`; -} const chartConfig = { difficulty: { label: "Difficulty", @@ -89,7 +78,7 @@ export const Charts = () => { gasUsed: ( (Number(block.gasUsed) / Number(block.gasLimit)) * 100 - ).toString(), + ).toFixed(2), transactions: block.transactions.length, }; } @@ -111,7 +100,7 @@ export const Charts = () => { const gasData = blocks.map((block) => ({ name: `${block.number}`, - gasused: Math.min(100, parseFloat(Number(block.gasUsed).toFixed(2))), + gasused: block.gasUsed , transactions: block.transactions, })); return ( diff --git a/src/components/crypto/info.tsx b/src/components/crypto/info.tsx index 9cb277a..5764203 100644 --- a/src/components/crypto/info.tsx +++ b/src/components/crypto/info.tsx @@ -5,10 +5,14 @@ import { useEffect, useState, useCallback } from "react"; import { ethers } from "ethers"; import { ColumnDef, + ColumnFiltersState, SortingState, + VisibilityState, flexRender, getCoreRowModel, + getFilteredRowModel, getPaginationRowModel, + getSortedRowModel, useReactTable, } from "@tanstack/react-table"; import { ChevronDown, MoreHorizontal } from "lucide-react"; @@ -16,10 +20,16 @@ import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, + DropdownMenuPortal, DropdownMenuSeparator, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, DropdownMenuTrigger, + DropdownMenuCheckboxItem, } from "@/components/ui/dropdown-menu"; import { Table, @@ -38,10 +48,14 @@ import { PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; +import { Input } from "@/components/ui/input"; import { cn } from "@/lib/utils"; +import {formatHashrate} from "./utils"; type Block = { - number: number; + number: string; + difficulty: string; + gasused: string; miner: string; timestamp: string; }; @@ -54,6 +68,20 @@ export const columns: ColumnDef[] = [
{row.getValue("number")}
), }, + { + accessorKey: "difficulty", + header: "Difficulty", + cell: ({ row }) => ( +
{row.getValue("difficulty")}
+ ), + }, + { + accessorKey: "gasused", + header: "Gas used", + cell: ({ row }) => ( +
{row.getValue("gasused")}%
+ ), + }, { accessorKey: "timestamp", header: "Timestamp", @@ -128,17 +156,31 @@ export default function Info() { const [sorting, setSorting] = useState([]); const [maxBlocks, setMaxBlocks] = useState(20); const [customBlockLimit, setCustomBlockLimit] = useState(""); + const [columnFilters, setColumnFilters] = React.useState( + [] + ); + const [columnVisibility, setColumnVisibility] = + React.useState({ + difficulty: false, + gasused: false + }); + const [rowSelection, setRowSelection] = React.useState({}); const fetchLatestBlock = useCallback(async () => { const latestBlockNumber = await provider.getBlockNumber(); const block = await provider.getBlock(latestBlockNumber); if (block) { setBlocks((prevBlocks) => { - if (prevBlocks.length && prevBlocks[0].number === block.number) { + if ( + prevBlocks.length && + Number(prevBlocks[0].number) === block.number + ) { return prevBlocks; } const newBlock = { - number: block.number, + number: block.number.toString(), + difficulty: formatHashrate(block.difficulty), + gasused: (Number(block.gasUsed) / Number(block.gasLimit) * 100).toFixed(2), miner: block.miner, timestamp: block.timestamp.toString(), }; @@ -161,7 +203,9 @@ export default function Info() { const formattedBlocks = blocks .filter((block): block is ethers.Block => block !== null) .map((block) => ({ - number: block.number, + number: block.number.toString(), + difficulty: formatHashrate(block.difficulty), + gasused: (Number(block.gasUsed) / Number(block.gasLimit) * 100).toFixed(2), miner: block.miner, timestamp: block.timestamp.toString(), })); @@ -177,10 +221,20 @@ export default function Info() { const table = useReactTable({ data: blocks, columns, - state: { sorting }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), + onColumnFiltersChange: setColumnFilters, + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + onColumnVisibilityChange: setColumnVisibility, + onRowSelectionChange: setRowSelection, + state: { + sorting, + columnFilters, + columnVisibility, + rowSelection, + }, }); return ( @@ -188,53 +242,98 @@ export default function Info() {
- + - Choose Block Limit + Settings - {[100, 500, 1000, 2000].map((limit) => ( - <> - { - setMaxBlocks(limit); - fetchInitialBlocks(); - }} - > - {limit} blocks - - - - ))} + + {table + .getAllColumns() + .filter((column) => column.getCanHide()) + .map((column) => { + return ( + + column.toggleVisibility(!!value) + } + > + {column.id} + + ); + })} + + + + + + Block Limit: {maxBlocks} + + + + Choose Block Limit + + {[100, 500, 1000, 2000].map((limit) => ( + <> + { + setMaxBlocks(limit); + fetchInitialBlocks(); + }} + > + {limit} blocks + + + + ))} -
-
- setCustomBlockLimit(e.target.value)} - placeholder="Custom limit" - className="flex h-8 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" - /> - -
-
+
+
+ setCustomBlockLimit(e.target.value)} + placeholder="Custom limit" + className="flex h-8 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" + /> + +
+
+
+
+
+
+ + { + console.log(event.target.value); + table + .getColumn("number") + ?.setFilterValue(event.target.value.toString()); + }} + className="max-w-sm" + />
diff --git a/src/components/crypto/utils.ts b/src/components/crypto/utils.ts new file mode 100644 index 0000000..51b351e --- /dev/null +++ b/src/components/crypto/utils.ts @@ -0,0 +1,12 @@ +export function formatHashrate(difficulty: any): string { + const units = ["H/s", "KH/s", "MH/s", "GH/s", "TH/s", "PH/s"]; + let value = Number(difficulty); + let unitIndex = 0; + + while (value >= 1000 && unitIndex < units.length - 1) { + value /= 1000; + unitIndex++; + } + + return `${value.toFixed(2)} ${units[unitIndex]}`; +} \ No newline at end of file