Skip to content

Commit

Permalink
feat: adding transactions page and transaction details page (#42)
Browse files Browse the repository at this point in the history
* add transaction page

* update block page with clickable

* update info display to support clickable links
  • Loading branch information
Mautjee authored Sep 19, 2024
1 parent 455a7b7 commit f80c835
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { KeyValueDisplay } from "./key-value-display";

interface InfoDisplayProps {
blockData: {
key: string;
label: string;
value: string;
isClickable?: boolean;
}[];
}

const InfoDisplay: FC<InfoDisplayProps> = ({ blockData }) => {
export const InfoDisplay: FC<InfoDisplayProps> = ({ blockData }) => {
return (
<div className="p-4">
<KeyValueDisplay data={blockData} />
Expand Down
Original file line number Diff line number Diff line change
@@ -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<KeyValueDisplayProps> = ({ data }) => (
<div className="bg-white rounded-lg shadow-md p-4">
<>
{data.map((item, index) => (
<KeyValueRow
key={index}
label={item.key}
label={item.label}
value={item.value}
isLast={index === data.length - 1}
isClickable={item.isClickable}
/>
))}
</div>
</>
);
17 changes: 15 additions & 2 deletions services/explorer-ui/src/components/info-display/key-value-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,29 @@ import { FC } from "react";
interface KeyValueRowProps {
label: string;
value: string;
isClickable?: boolean;
isLast?: boolean;
}

export const KeyValueRow: FC<KeyValueRowProps> = ({ label, value, isLast }) => (
export const KeyValueRow: FC<KeyValueRowProps> = ({
label,
value,
isLast,
isClickable = false,
}) => (
<div
className={`flex items-center py-3 ${
!isLast ? "border-b border-gray-200" : ""
}`}
>
<span className="text-gray-600 w-1/5">{label}</span>
<span className="font-medium text-right">{value}</span>
<span
className={`text-sm flex-grow ${
isClickable ? "text-blue-600 cursor-pointer" : ""
}`}
>
{value}
{isClickable && <span className="ml-1">🔗</span>}
</span>
</div>
);
63 changes: 44 additions & 19 deletions services/explorer-ui/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -69,27 +82,34 @@ 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'
fullPath: '/blocks/$blockNumber'
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'
fullPath: '/blocks'
preLoaderRoute: typeof BlocksIndexLazyImport
parentRoute: typeof rootRoute
}
'/transactions/': {
id: '/transactions/'
path: '/transactions'
fullPath: '/transactions'
preLoaderRoute: typeof TransactionsIndexLazyImport
parentRoute: typeof rootRoute
}
}
}

Expand All @@ -98,9 +118,10 @@ declare module '@tanstack/react-router' {
export const routeTree = rootRoute.addChildren({
IndexLazyRoute,
ContractsLazyRoute,
TransactionsLazyRoute,
BlocksBlockNumberLazyRoute,
TransactionsTransactionIdLazyRoute,
BlocksIndexLazyRoute,
TransactionsIndexLazyRoute,
})

/* prettier-ignore-end */
Expand All @@ -113,9 +134,10 @@ export const routeTree = rootRoute.addChildren({
"children": [
"/",
"/contracts",
"/transactions",
"/blocks/$blockNumber",
"/blocks/"
"/transactions/$transactionId",
"/blocks/",
"/transactions/"
]
},
"/": {
Expand All @@ -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"
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions services/explorer-ui/src/routes/blocks/$blockNumber.lazy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
];
Expand Down Expand Up @@ -92,7 +92,7 @@ function Block() {
<p>{bn}</p>
</div>
<div className="flex flex-col gap-4 mt-8">
<div className="">
<div className="bg-white rounded-lg shadow-md p-4">
<KeyValueDisplay data={blockData} />
</div>
<div className="flex flex-row gap-4 w-10 mb-4">
Expand Down
17 changes: 0 additions & 17 deletions services/explorer-ui/src/routes/transactions.lazy.tsx

This file was deleted.

106 changes: 106 additions & 0 deletions services/explorer-ui/src/routes/transactions/$transactionId.lazy.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="mx-auto px-[70px] max-w-[1440px]">
{transactionId ? (
<div>
<div>
<h2>Transaction details</h2>
<p>{transactionId}</p>
</div>
<div className="flex flex-col gap-4 mt-8">
<div className="bg-white rounded-lg shadow-md p-4">
<KeyValueDisplay data={transactionData} />
</div>
<div className="flex flex-row gap-4 w-10 mb-4">
<Button
variant={"primary"}
onClick={() => setSelectedButton("transactionEffects")}
>
Transaction effects
</Button>
<Button
variant={"primary"}
onClick={() => setSelectedButton("feeDetails")}
>
View Transactions
</Button>
</div>
{selectedButton === "transactionEffects" && (
<div className="bg-white rounded-lg shadow-md p-4">
<h3>Transaction Effects</h3>
</div>
)}
{selectedButton === "feeDetails" && (
<div className="bg-white rounded-lg shadow-md p-4">
<div className="flex flex-col mt-8">
<h3>Fee Details</h3>
<KeyValueDisplay data={feeData} />
</div>
<div className="flex flex-col mt-8">
<h3>Public fee Details</h3>
<KeyValueDisplay data={feeData} />
</div>
</div>
)}
</div>
</div>
) : (
//TODO: create reusable component
<div>
<h2>Invalid Transaction Id</h2>
<p>transaction {transactionId} not found</p>
</div>
)}
</div>
);
}

Loading

0 comments on commit f80c835

Please sign in to comment.