diff --git a/services/explorer-ui/src/components/info-display/info-display.tsx b/services/explorer-ui/src/components/info-display/info-display.tsx index 4d6e6635..26b3c1b0 100644 --- a/services/explorer-ui/src/components/info-display/info-display.tsx +++ b/services/explorer-ui/src/components/info-display/info-display.tsx @@ -3,12 +3,13 @@ import { KeyValueDisplay } from "./key-value-display"; interface InfoDisplayProps { blockData: { - key: string; + label: string; value: string; + isClickable?: boolean; }[]; } -const InfoDisplay: FC = ({ blockData }) => { +export const InfoDisplay: FC = ({ blockData }) => { return (
diff --git a/services/explorer-ui/src/components/info-display/key-value-display.tsx b/services/explorer-ui/src/components/info-display/key-value-display.tsx index e7d182f9..5ab36f47 100644 --- a/services/explorer-ui/src/components/info-display/key-value-display.tsx +++ b/services/explorer-ui/src/components/info-display/key-value-display.tsx @@ -1,22 +1,26 @@ import { FC } from "react"; import { KeyValueRow } from "./key-value-row"; +interface DetailItem { + label: string; + value: string; + isClickable?: boolean; +} + interface KeyValueDisplayProps { - data: { - key: string; - value: string; - }[]; + data: DetailItem[]; } export const KeyValueDisplay: FC = ({ data }) => ( -
+ <> {data.map((item, index) => ( ))} -
+ ); diff --git a/services/explorer-ui/src/components/info-display/key-value-row.tsx b/services/explorer-ui/src/components/info-display/key-value-row.tsx index e75da9b4..40369dc5 100644 --- a/services/explorer-ui/src/components/info-display/key-value-row.tsx +++ b/services/explorer-ui/src/components/info-display/key-value-row.tsx @@ -3,16 +3,29 @@ import { FC } from "react"; interface KeyValueRowProps { label: string; value: string; + isClickable?: boolean; isLast?: boolean; } -export const KeyValueRow: FC = ({ label, value, isLast }) => ( +export const KeyValueRow: FC = ({ + label, + value, + isLast, + isClickable = false, +}) => (
{label} - {value} + + {value} + {isClickable && 🔗} +
); diff --git a/services/explorer-ui/src/routeTree.gen.ts b/services/explorer-ui/src/routeTree.gen.ts index 080b569a..b573f9bf 100644 --- a/services/explorer-ui/src/routeTree.gen.ts +++ b/services/explorer-ui/src/routeTree.gen.ts @@ -16,19 +16,17 @@ import { Route as rootRoute } from './routes/__root' // Create Virtual Routes -const TransactionsLazyImport = createFileRoute('/transactions')() const ContractsLazyImport = createFileRoute('/contracts')() const IndexLazyImport = createFileRoute('/')() +const TransactionsIndexLazyImport = createFileRoute('/transactions/')() const BlocksIndexLazyImport = createFileRoute('/blocks/')() +const TransactionsTransactionIdLazyImport = createFileRoute( + '/transactions/$transactionId', +)() const BlocksBlockNumberLazyImport = createFileRoute('/blocks/$blockNumber')() // Create/Update Routes -const TransactionsLazyRoute = TransactionsLazyImport.update({ - path: '/transactions', - getParentRoute: () => rootRoute, -} as any).lazy(() => import('./routes/transactions.lazy').then((d) => d.Route)) - const ContractsLazyRoute = ContractsLazyImport.update({ path: '/contracts', getParentRoute: () => rootRoute, @@ -39,11 +37,26 @@ const IndexLazyRoute = IndexLazyImport.update({ getParentRoute: () => rootRoute, } as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route)) +const TransactionsIndexLazyRoute = TransactionsIndexLazyImport.update({ + path: '/transactions/', + getParentRoute: () => rootRoute, +} as any).lazy(() => + import('./routes/transactions/index.lazy').then((d) => d.Route), +) + const BlocksIndexLazyRoute = BlocksIndexLazyImport.update({ path: '/blocks/', getParentRoute: () => rootRoute, } as any).lazy(() => import('./routes/blocks/index.lazy').then((d) => d.Route)) +const TransactionsTransactionIdLazyRoute = + TransactionsTransactionIdLazyImport.update({ + path: '/transactions/$transactionId', + getParentRoute: () => rootRoute, + } as any).lazy(() => + import('./routes/transactions/$transactionId.lazy').then((d) => d.Route), + ) + const BlocksBlockNumberLazyRoute = BlocksBlockNumberLazyImport.update({ path: '/blocks/$blockNumber', getParentRoute: () => rootRoute, @@ -69,13 +82,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ContractsLazyImport parentRoute: typeof rootRoute } - '/transactions': { - id: '/transactions' - path: '/transactions' - fullPath: '/transactions' - preLoaderRoute: typeof TransactionsLazyImport - parentRoute: typeof rootRoute - } '/blocks/$blockNumber': { id: '/blocks/$blockNumber' path: '/blocks/$blockNumber' @@ -83,6 +89,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof BlocksBlockNumberLazyImport parentRoute: typeof rootRoute } + '/transactions/$transactionId': { + id: '/transactions/$transactionId' + path: '/transactions/$transactionId' + fullPath: '/transactions/$transactionId' + preLoaderRoute: typeof TransactionsTransactionIdLazyImport + parentRoute: typeof rootRoute + } '/blocks/': { id: '/blocks/' path: '/blocks' @@ -90,6 +103,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof BlocksIndexLazyImport parentRoute: typeof rootRoute } + '/transactions/': { + id: '/transactions/' + path: '/transactions' + fullPath: '/transactions' + preLoaderRoute: typeof TransactionsIndexLazyImport + parentRoute: typeof rootRoute + } } } @@ -98,9 +118,10 @@ declare module '@tanstack/react-router' { export const routeTree = rootRoute.addChildren({ IndexLazyRoute, ContractsLazyRoute, - TransactionsLazyRoute, BlocksBlockNumberLazyRoute, + TransactionsTransactionIdLazyRoute, BlocksIndexLazyRoute, + TransactionsIndexLazyRoute, }) /* prettier-ignore-end */ @@ -113,9 +134,10 @@ export const routeTree = rootRoute.addChildren({ "children": [ "/", "/contracts", - "/transactions", "/blocks/$blockNumber", - "/blocks/" + "/transactions/$transactionId", + "/blocks/", + "/transactions/" ] }, "/": { @@ -124,14 +146,17 @@ export const routeTree = rootRoute.addChildren({ "/contracts": { "filePath": "contracts.lazy.tsx" }, - "/transactions": { - "filePath": "transactions.lazy.tsx" - }, "/blocks/$blockNumber": { "filePath": "blocks/$blockNumber.lazy.tsx" }, + "/transactions/$transactionId": { + "filePath": "transactions/$transactionId.lazy.tsx" + }, "/blocks/": { "filePath": "blocks/index.lazy.tsx" + }, + "/transactions/": { + "filePath": "transactions/index.lazy.tsx" } } } diff --git a/services/explorer-ui/src/routes/blocks/$blockNumber.lazy.tsx b/services/explorer-ui/src/routes/blocks/$blockNumber.lazy.tsx index adcbd82f..f70495b6 100644 --- a/services/explorer-ui/src/routes/blocks/$blockNumber.lazy.tsx +++ b/services/explorer-ui/src/routes/blocks/$blockNumber.lazy.tsx @@ -9,20 +9,20 @@ export const Route = createLazyFileRoute("/blocks/$blockNumber")({ }); const blockData = [ - { key: "BLOCK NUMBER", value: "348540" }, + { label: "BLOCK NUMBER", value: "348540" }, { - key: "BLOCK HASH", + label: "BLOCK HASH", value: "0x995542b01a706c56d3a962ba819e765ree057egtr4311562cdf6286147fbf9cf51", }, - { key: "STATUS", value: "FINALISED" }, - { key: "TIMESTAMP", value: "1 min ago (Jun-07-2024 08:47:23 AM UTC)" }, - { key: "TRANSACTIONS", value: "155 transactions" }, - { key: "TOTAL FEES", value: "0.000122453 ETH ($0.05)" }, - { key: "SIZE", value: "46,377 bytes" }, - { key: "LOGS", value: "323 logs" }, + { label: "STATUS", value: "FINALISED" }, + { label: "TIMESTAMP", value: "1 min ago (Jun-07-2024 08:47:23 AM UTC)" }, + { label: "TRANSACTIONS", value: "155 transactions" }, + { label: "TOTAL FEES", value: "0.000122453 ETH ($0.05)" }, + { label: "SIZE", value: "46,377 bytes" }, + { label: "LOGS", value: "323 logs" }, { - key: "PARENT HASH", + label: "PARENT HASH", value: "0xebe7fuy7655b6506fe587hj7c2ad1237b242b9adc60ci8u7y972728ce63b526b", }, ]; @@ -92,7 +92,7 @@ function Block() {

{bn}

-
+
diff --git a/services/explorer-ui/src/routes/transactions.lazy.tsx b/services/explorer-ui/src/routes/transactions.lazy.tsx deleted file mode 100644 index f6dd492f..00000000 --- a/services/explorer-ui/src/routes/transactions.lazy.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createLazyFileRoute } from "@tanstack/react-router"; - -export const Route = createLazyFileRoute("/transactions")({ - component: Transactions, -}); - -function Transactions() { - return ( -
-

{text.title}

-
- ); -} - -const text = { - title: "All transactions", -} \ No newline at end of file diff --git a/services/explorer-ui/src/routes/transactions/$transactionId.lazy.tsx b/services/explorer-ui/src/routes/transactions/$transactionId.lazy.tsx new file mode 100644 index 00000000..d5c8fc5a --- /dev/null +++ b/services/explorer-ui/src/routes/transactions/$transactionId.lazy.tsx @@ -0,0 +1,106 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import { FC, useState } from "react"; +import { KeyValueDisplay } from "~/components/info-display/key-value-display"; +import { Button } from "~/components/ui"; + +export const Route = createLazyFileRoute("/transactions/$transactionId")({ + component: TransactionDetails, +}); + +const transactionData = [ + { + label: "HASH", + value: "0xb950b8ba84a4f35f85d5f62a0e3f8b161d8733479c14d426dc36ae30f7e96246", + isClickable: true, + }, + { label: "STATUS", value: "SUCCESS" }, + { + label: "BLOCK NUMBER", + value: "348540 (confirmed by sequencer)", + isClickable: true, + }, + { label: "TIMESTAMP", value: "1 min ago (Jun-07-2024 08:47:23 AM UTC)" }, + { + label: "L1 BATCH TX", + value: "0xb950b8ba84a4f35f85d5f62a0e3f8b161d8733479c14d426dc36ae30f7e92341", + isClickable: true, + }, + { label: "TRANSACTION FEE", value: "0.000012245344159887766 ETH ($0.05)" }, +]; + +const feeData = [ + { label: "TRANSACTION FEE", value: "0.000012453 ETH" }, + { label: "FPA USED", value: "ETHER" }, + { label: "GAS PRICE", value: "0.000012453 ETH" }, + { label: "GAS", value: "0.000012453 ETH" }, + { label: "FEE USED FOR L2 GAS", value: "0.000012453 ETH" }, + { label: "L1 GAS", value: "0.000012453 ETH" }, + { label: "DATA AVAILABILITY FEE", value: "0.000012453 ETH" }, + { label: "COINBASE", value: "0.000012453 ETH" }, + { + label: "FEE RECIPIENT", + value: "0xb950b8ba84a4f35f85d5f62a0e3f8b161d8733479c14d426dc36ae30f7e96246", + isClickable: true, + }, +]; + +function TransactionDetails() { + const [selectedButton, setSelectedButton] = useState("transactionEffects"); + const { transactionId } = Route.useParams(); + + return ( +
+ {transactionId ? ( +
+
+

Transaction details

+

{transactionId}

+
+
+
+ +
+
+ + +
+ {selectedButton === "transactionEffects" && ( +
+

Transaction Effects

+
+ )} + {selectedButton === "feeDetails" && ( +
+
+

Fee Details

+ +
+
+

Public fee Details

+ +
+
+ )} +
+
+ ) : ( + //TODO: create reusable component +
+

Invalid Transaction Id

+

transaction {transactionId} not found

+
+ )} +
+ ); +} + diff --git a/services/explorer-ui/src/routes/transactions/index.lazy.tsx b/services/explorer-ui/src/routes/transactions/index.lazy.tsx new file mode 100644 index 00000000..a00f1501 --- /dev/null +++ b/services/explorer-ui/src/routes/transactions/index.lazy.tsx @@ -0,0 +1,30 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import { TransactionsTable } from "~/components/transactions/transactions-table"; + +export const Route = createLazyFileRoute("/transactions/")({ + component: Transactions, +}); + +function Transactions() { + return ( +
+
+
+

Transactions in the last 24 hours

+

33952

+
+ +
+

Pending transactions in last hour

+

342

+
+
+

average transaction fee (eth)

+

0.000012245

+
+
+ +
+ ); +} +