From ec72949bd05fe328879a9b1a2612169a85e3288d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 23 Nov 2023 14:23:19 +0100 Subject: [PATCH 1/2] Create a basic table for transaction history --- dapp/package.json | 1 + .../Overview/TransactionHistory.tsx | 10 -- .../TransactionHistory/AccountHistory.tsx | 10 ++ .../TransactionHistory/CustomCell.tsx | 74 +++++++++++ .../Overview/TransactionHistory/DataTable.tsx | 121 ++++++++++++++++++ .../TransactionHistory/ProtocolHistory.tsx | 10 ++ .../Overview/TransactionHistory/index.tsx | 23 ++++ dapp/src/constants/chains.ts | 7 + dapp/src/data/mock-transactions.ts | 95 ++++++++++++++ dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useTransactionHistoryTable.ts | 36 ++++++ dapp/src/static/icons/ArrowDown.tsx | 24 ++++ dapp/src/static/icons/ArrowUp.tsx | 24 ++++ dapp/src/static/icons/BitcoinSymbol.tsx | 35 +++++ dapp/src/static/icons/Sort.tsx | 19 +++ dapp/src/static/icons/TBTCSymbol.tsx | 37 ++++++ dapp/src/static/icons/index.ts | 5 + dapp/src/types/index.ts | 1 + dapp/src/types/transaction.ts | 14 ++ dapp/src/utils/index.ts | 1 + dapp/src/utils/time.ts | 8 ++ dapp/yarn.lock | 12 ++ 22 files changed, 558 insertions(+), 10 deletions(-) delete mode 100644 dapp/src/components/Overview/TransactionHistory.tsx create mode 100644 dapp/src/components/Overview/TransactionHistory/AccountHistory.tsx create mode 100644 dapp/src/components/Overview/TransactionHistory/CustomCell.tsx create mode 100644 dapp/src/components/Overview/TransactionHistory/DataTable.tsx create mode 100644 dapp/src/components/Overview/TransactionHistory/ProtocolHistory.tsx create mode 100644 dapp/src/components/Overview/TransactionHistory/index.tsx create mode 100644 dapp/src/data/mock-transactions.ts create mode 100644 dapp/src/hooks/useTransactionHistoryTable.ts create mode 100644 dapp/src/static/icons/ArrowDown.tsx create mode 100644 dapp/src/static/icons/ArrowUp.tsx create mode 100644 dapp/src/static/icons/BitcoinSymbol.tsx create mode 100644 dapp/src/static/icons/Sort.tsx create mode 100644 dapp/src/static/icons/TBTCSymbol.tsx create mode 100644 dapp/src/types/transaction.ts create mode 100644 dapp/src/utils/time.ts diff --git a/dapp/package.json b/dapp/package.json index e68ed741a..a827c2464 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -20,6 +20,7 @@ "@emotion/styled": "^11.11.0", "@ledgerhq/wallet-api-client": "^1.2.1", "@ledgerhq/wallet-api-client-react": "^1.1.2", + "@tanstack/react-table": "^8.10.7", "framer-motion": "^10.16.4", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/dapp/src/components/Overview/TransactionHistory.tsx b/dapp/src/components/Overview/TransactionHistory.tsx deleted file mode 100644 index 312233938..000000000 --- a/dapp/src/components/Overview/TransactionHistory.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from "react" -import { Text, Box } from "@chakra-ui/react" - -export default function TransactionHistory() { - return ( - - Transaction history - - ) -} diff --git a/dapp/src/components/Overview/TransactionHistory/AccountHistory.tsx b/dapp/src/components/Overview/TransactionHistory/AccountHistory.tsx new file mode 100644 index 000000000..2c35080e3 --- /dev/null +++ b/dapp/src/components/Overview/TransactionHistory/AccountHistory.tsx @@ -0,0 +1,10 @@ +import React from "react" + +import DataTable from "./DataTable" +import { MOCK_USER_TRANSACTIONS } from "../../../data/mock-transactions" + +export default function AccountHistory() { + // TODO: The transactions should be fetched, probably use the subgraph for this + const data = MOCK_USER_TRANSACTIONS + return +} diff --git a/dapp/src/components/Overview/TransactionHistory/CustomCell.tsx b/dapp/src/components/Overview/TransactionHistory/CustomCell.tsx new file mode 100644 index 000000000..d8ed0f667 --- /dev/null +++ b/dapp/src/components/Overview/TransactionHistory/CustomCell.tsx @@ -0,0 +1,74 @@ +import React from "react" +import { Box, Icon, Text, Link, HStack } from "@chakra-ui/react" +import { BITCOIN, ETHEREUM } from "../../../constants" +import { BitcoinSymbol, TBTCSymbol } from "../../../static/icons" + +export default function Cell({ + children1, + children2, +}: { + children1: React.ReactElement + children2: React.ReactElement +}) { + return ( + + + {children1} + + + {children2} + + + ) +} + +function AssetCell({ asset }: { asset: string }) { + return ( + + + {asset} + + ) +} + +function BlockExplorerCell({ txHash }: { txHash: string }) { + const isEthTx = txHash.includes("0x") + const blockExplorer = isEthTx ? ETHEREUM.blockExplorer : BITCOIN.blockExplorer + const text = `See on ${isEthTx ? "Etherscan" : "Blockstream"}` + return ( + + {text} + + ) +} +export function getCustomCell( + type: "text" | "asset" | "link", + value1: string, + value2: string, +) { + switch (type) { + case "text": + return ( + {value1}} + children2={{value2}} + /> + ) + case "asset": + return ( + } + children2={} + /> + ) + case "link": + return ( + } + children2={} + /> + ) + default: + return null + } +} diff --git a/dapp/src/components/Overview/TransactionHistory/DataTable.tsx b/dapp/src/components/Overview/TransactionHistory/DataTable.tsx new file mode 100644 index 000000000..104e1d519 --- /dev/null +++ b/dapp/src/components/Overview/TransactionHistory/DataTable.tsx @@ -0,0 +1,121 @@ +import React from "react" +import { Table, Thead, Tbody, Tr, Th, Td, HStack, Icon } from "@chakra-ui/react" +import { + flexRender, + ColumnDef, + SortDirection, + createColumnHelper, +} from "@tanstack/react-table" +import { useTransactionHistoryTable } from "../../../hooks" +import { TxHistory } from "../../../types" +import { getCustomCell } from "./CustomCell" +import { formatBlockTImestamp, truncateAddress } from "../../../utils" +import { ArrowDown, ArrowUp, Sort } from "../../../static/icons" + +const getSortIcon = (value: false | SortDirection) => { + if (value) return value === "desc" ? ArrowDown : ArrowUp + return Sort +} + +const columnHelper = createColumnHelper() +// When defining the columns for the table, columnHelper.accessor ts returns a type issue. +// Let's use the type any ay to avoid this error for this moment. +// More info: https://github.com/TanStack/table/issues/4241 +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const COLUMNS: ColumnDef[] = [ + // To enable the sorting of some columns let's use `columnHelper.accessor`. + // To do this, we also need to provide a key to the variable. + // Let's sort the data by the first transaction. + columnHelper.accessor("callTx.timestamp", { + header: "Date", + cell: ({ row: { original } }) => + getCustomCell( + "text", + formatBlockTImestamp(original.callTx.timestamp), + formatBlockTImestamp(original.receiptTx.timestamp), + ), + }), + columnHelper.display({ + header: "action", + cell: ({ row: { original } }) => + getCustomCell("text", original.callTx.action, original.receiptTx.action), + }), + columnHelper.display({ + header: "Asset", + cell: ({ row: { original } }) => + getCustomCell("asset", original.callTx.asset, original.receiptTx.asset), + }), + columnHelper.accessor("callTx.amount", { + cell: ({ row: { original } }) => + // TOTO:Use the correct format for the amounts + getCustomCell( + "text", + original.callTx.amount.toString(), + original.receiptTx.amount.toString(), + ), + header: "Amount", + }), + columnHelper.display({ + header: "Account", + cell: ({ row: { original } }) => + getCustomCell( + "text", + truncateAddress(original.callTx.account), + truncateAddress(original.receiptTx.account), + ), + }), + columnHelper.display({ + header: "Transaction", + cell: ({ row: { original } }) => + getCustomCell("link", original.callTx.txHash, original.receiptTx.txHash), + }), + columnHelper.display({ + header: "Status", + cell: ({ row: { original } }) => + getCustomCell("text", original.callTx.status, original.receiptTx.status), + }), +] + +export default function DataTable({ data }: { data: TxHistory[] }) { + const table = useTransactionHistoryTable({ + data, + columns: COLUMNS, + }) + + return ( + + + {table.getHeaderGroups().map(({ id, headers }) => ( + + {headers.map((header) => ( + + ))} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map(({ id, column, getContext }) => ( + + ))} + + ))} + +
+ {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + {header.column.getCanSort() && ( + + )} +
+ {flexRender(column.columnDef.cell, getContext())} +
+ ) +} diff --git a/dapp/src/components/Overview/TransactionHistory/ProtocolHistory.tsx b/dapp/src/components/Overview/TransactionHistory/ProtocolHistory.tsx new file mode 100644 index 000000000..a9b4f03bd --- /dev/null +++ b/dapp/src/components/Overview/TransactionHistory/ProtocolHistory.tsx @@ -0,0 +1,10 @@ +import React from "react" + +import DataTable from "./DataTable" +import { MOCK_ALL_TRANSACTIONS } from "../../../data/mock-transactions" + +export default function ProtocolHistory() { + // TODO: The transactions should be fetched, probably use the subgraph for this + const data = MOCK_ALL_TRANSACTIONS + return +} diff --git a/dapp/src/components/Overview/TransactionHistory/index.tsx b/dapp/src/components/Overview/TransactionHistory/index.tsx new file mode 100644 index 000000000..449236ff3 --- /dev/null +++ b/dapp/src/components/Overview/TransactionHistory/index.tsx @@ -0,0 +1,23 @@ +import React from "react" +import { Tabs, TabList, TabPanels, Tab, TabPanel } from "@chakra-ui/react" +import AccountHistory from "./AccountHistory" +import ProtocolHistory from "./ProtocolHistory" + +export default function TransactionHistory() { + return ( + + + Protocol history + Account history + + + + + + + + + + + ) +} diff --git a/dapp/src/constants/chains.ts b/dapp/src/constants/chains.ts index 626c6d07b..ad8dfe4b9 100644 --- a/dapp/src/constants/chains.ts +++ b/dapp/src/constants/chains.ts @@ -1,4 +1,11 @@ export const BITCOIN = { name: "Bitcoin", token: "BTC", + blockExplorer: "https://btcscan.org", +} + +export const ETHEREUM = { + name: "Ethereum", + token: "ETH", + blockExplorer: "https://etherscan.io", } diff --git a/dapp/src/data/mock-transactions.ts b/dapp/src/data/mock-transactions.ts new file mode 100644 index 000000000..ee48ca8f0 --- /dev/null +++ b/dapp/src/data/mock-transactions.ts @@ -0,0 +1,95 @@ +import { TxHistory } from "../types" + +export const MOCK_ALL_TRANSACTIONS: TxHistory[] = [ + { + callTx: { + timestamp: 1700179973, + action: "Stake", + asset: "BTC", + amount: 2.24, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700179973, + action: "Receive", + asset: "stBTC", + amount: 2.24, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, + { + callTx: { + timestamp: 1700578973, + action: "Unstake", + asset: "stBTC", + amount: 6.14, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700578973, + action: "Receive", + asset: "BTC", + amount: 6.14, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, + { + callTx: { + timestamp: 1700579973, + action: "Stake", + asset: "BTC", + amount: 3.11, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700579973, + action: "Receive", + asset: "stBTC", + amount: 3.11, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, +] + +export const MOCK_USER_TRANSACTIONS: TxHistory[] = [ + { + callTx: { + timestamp: 1700579973, + action: "Stake", + asset: "BTC", + amount: 3.11, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700579973, + action: "Receive", + asset: "stBTC", + amount: 3.11, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, +] diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index f07366688..8202eaff0 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -1,3 +1,4 @@ export * from "./useDetectThemeMode" export * from "./useRequestBitcoinAccount" export * from "./useRequestEthereumAccount" +export * from "./useTransactionHistoryTable" diff --git a/dapp/src/hooks/useTransactionHistoryTable.ts b/dapp/src/hooks/useTransactionHistoryTable.ts new file mode 100644 index 000000000..9c7a9837a --- /dev/null +++ b/dapp/src/hooks/useTransactionHistoryTable.ts @@ -0,0 +1,36 @@ +import { useState } from "react" +import { + ColumnDef, + SortingState, + Table, + getCoreRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table" +import { TxHistory } from "../types" + +type TransactionHistoryTable = { + data: TxHistory[] + columns: ColumnDef[] +} + +export function useTransactionHistoryTable({ + data, + columns, +}: TransactionHistoryTable): Table { + const [sorting, setSorting] = useState([]) + const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + onSortingChange: setSorting, + getSortedRowModel: getSortedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + state: { + sorting, + }, + }) + + return table +} diff --git a/dapp/src/static/icons/ArrowDown.tsx b/dapp/src/static/icons/ArrowDown.tsx new file mode 100644 index 000000000..edb29a09a --- /dev/null +++ b/dapp/src/static/icons/ArrowDown.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const ArrowDown = createIcon({ + displayName: "ArrowDown", + viewBox: "0 0 24 24", + path: ( + + + + ), +}) diff --git a/dapp/src/static/icons/ArrowUp.tsx b/dapp/src/static/icons/ArrowUp.tsx new file mode 100644 index 000000000..29592e644 --- /dev/null +++ b/dapp/src/static/icons/ArrowUp.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const ArrowUp = createIcon({ + displayName: "ArrowUp", + viewBox: "0 0 24 24", + path: ( + + + + ), +}) diff --git a/dapp/src/static/icons/BitcoinSymbol.tsx b/dapp/src/static/icons/BitcoinSymbol.tsx new file mode 100644 index 000000000..43d65f285 --- /dev/null +++ b/dapp/src/static/icons/BitcoinSymbol.tsx @@ -0,0 +1,35 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const BitcoinSymbol = createIcon({ + displayName: "BitcoinSymbol", + viewBox: "0 0 24 24", + path: ( + + + + + + + + + + ), +}) diff --git a/dapp/src/static/icons/Sort.tsx b/dapp/src/static/icons/Sort.tsx new file mode 100644 index 000000000..a834a8be1 --- /dev/null +++ b/dapp/src/static/icons/Sort.tsx @@ -0,0 +1,19 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const Sort = createIcon({ + displayName: "Sort", + viewBox: "0 0 8 16", + path: ( + + + + + ), +}) diff --git a/dapp/src/static/icons/TBTCSymbol.tsx b/dapp/src/static/icons/TBTCSymbol.tsx new file mode 100644 index 000000000..e86b627a2 --- /dev/null +++ b/dapp/src/static/icons/TBTCSymbol.tsx @@ -0,0 +1,37 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const TBTCSymbol = createIcon({ + displayName: "TBTCSymbol", + viewBox: "0 0 24 24", + path: ( + + + + + + + + + ), +}) diff --git a/dapp/src/static/icons/index.ts b/dapp/src/static/icons/index.ts index 66c6e3aa9..72155bb3b 100644 --- a/dapp/src/static/icons/index.ts +++ b/dapp/src/static/icons/index.ts @@ -2,3 +2,8 @@ export * from "./Info" export * from "./Bitcoin" export * from "./Ethereum" export * from "./ChevronRight" +export * from "./BitcoinSymbol" +export * from "./TBTCSymbol" +export * from "./Sort" +export * from "./ArrowDown" +export * from "./ArrowUp" diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 96cd9d44f..ee572fcf2 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -1 +1,2 @@ export * from "./ledger-live-app" +export * from "./transaction" diff --git a/dapp/src/types/transaction.ts b/dapp/src/types/transaction.ts new file mode 100644 index 000000000..a4bff40fa --- /dev/null +++ b/dapp/src/types/transaction.ts @@ -0,0 +1,14 @@ +type TxDetails = { + timestamp: number + action: string + asset: string + amount: number + account: string + txHash: string + status: string +} + +export type TxHistory = { + callTx: TxDetails + receiptTx: TxDetails +} diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index 613e0f071..041c3a27c 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -1,2 +1,3 @@ export * from "./numbers" export * from "./address" +export * from "./time" diff --git a/dapp/src/utils/time.ts b/dapp/src/utils/time.ts new file mode 100644 index 000000000..c464cbb1d --- /dev/null +++ b/dapp/src/utils/time.ts @@ -0,0 +1,8 @@ +export const ONE_SEC_IN_MILLISECONDS = 1000 + +// The function displays the date in the format: 21/11/2023, 16:02 +export const formatBlockTImestamp = (blockTimestamp: number) => + new Date(blockTimestamp * ONE_SEC_IN_MILLISECONDS).toLocaleString([], { + dateStyle: "short", + timeStyle: "short", + }) diff --git a/dapp/yarn.lock b/dapp/yarn.lock index dab9c6f84..12027dbec 100644 --- a/dapp/yarn.lock +++ b/dapp/yarn.lock @@ -1432,6 +1432,18 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@tanstack/react-table@^8.10.7": + version "8.10.7" + resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.10.7.tgz#733f4bee8cf5aa19582f944dd0fd3224b21e8c94" + integrity sha512-bXhjA7xsTcsW8JPTTYlUg/FuBpn8MNjiEPhkNhIGCUR6iRQM2+WEco4OBpvDeVcR9SE+bmWLzdfiY7bCbCSVuA== + dependencies: + "@tanstack/table-core" "8.10.7" + +"@tanstack/table-core@8.10.7": + version "8.10.7" + resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.10.7.tgz#577e8a635048875de4c9d6d6a3c21d26ff9f9d08" + integrity sha512-KQk5OMg5OH6rmbHZxuNROvdI+hKDIUxANaHlV+dPlNN7ED3qYQ/WkpY2qlXww1SIdeMlkIhpN/2L00rof0fXFw== + "@thesis-co/eslint-config@^0.6.1": version "0.6.1" resolved "https://registry.yarnpkg.com/@thesis-co/eslint-config/-/eslint-config-0.6.1.tgz#70e419cd02b271ae447eebdefaa5359dca301285" From 5b347a082b4ab54dd8173f507b5cd1463a7e8d69 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 24 Nov 2023 11:55:25 +0100 Subject: [PATCH 2/2] Add a basic pagination for transaction history table --- .../Overview/TransactionHistory/DataTable.tsx | 115 ++++++++++++------ dapp/src/data/mock-transactions.ts | 66 ++++++++++ dapp/src/hooks/useTransactionHistoryTable.ts | 10 +- dapp/src/static/icons/ChevronLeft.tsx | 24 ++++ dapp/src/static/icons/index.ts | 1 + 5 files changed, 179 insertions(+), 37 deletions(-) create mode 100644 dapp/src/static/icons/ChevronLeft.tsx diff --git a/dapp/src/components/Overview/TransactionHistory/DataTable.tsx b/dapp/src/components/Overview/TransactionHistory/DataTable.tsx index 104e1d519..102e8956e 100644 --- a/dapp/src/components/Overview/TransactionHistory/DataTable.tsx +++ b/dapp/src/components/Overview/TransactionHistory/DataTable.tsx @@ -1,5 +1,17 @@ import React from "react" -import { Table, Thead, Tbody, Tr, Th, Td, HStack, Icon } from "@chakra-ui/react" +import { + Table, + Thead, + Tbody, + Tr, + Th, + Td, + HStack, + Icon, + Text, + IconButton, + VStack, +} from "@chakra-ui/react" import { flexRender, ColumnDef, @@ -10,7 +22,13 @@ import { useTransactionHistoryTable } from "../../../hooks" import { TxHistory } from "../../../types" import { getCustomCell } from "./CustomCell" import { formatBlockTImestamp, truncateAddress } from "../../../utils" -import { ArrowDown, ArrowUp, Sort } from "../../../static/icons" +import { + ArrowDown, + ArrowUp, + ChevronLeft, + ChevronRight, + Sort, +} from "../../../static/icons" const getSortIcon = (value: false | SortDirection) => { if (value) return value === "desc" ? ArrowDown : ArrowUp @@ -83,39 +101,64 @@ export default function DataTable({ data }: { data: TxHistory[] }) { }) return ( - - - {table.getHeaderGroups().map(({ id, headers }) => ( - - {headers.map((header) => ( - - ))} - - ))} - - - {table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map(({ id, column, getContext }) => ( - - ))} - - ))} - -
- {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - {header.column.getCanSort() && ( - - )} -
- {flexRender(column.columnDef.cell, getContext())} -
+ + + + {table.getHeaderGroups().map(({ id, headers }) => ( + + {headers.map((header) => ( + + ))} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map(({ id, column, getContext }) => ( + + ))} + + ))} + +
+ {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + {header.column.getCanSort() && ( + + )} +
+ {flexRender(column.columnDef.cell, getContext())} +
+ + table.previousPage()} + isDisabled={!table.getCanPreviousPage()} + icon={} + /> + table.nextPage()} + isDisabled={!table.getCanNextPage()} + icon={} + /> + + {`Page ${ + table.getState().pagination.pageIndex + 1 + } of ${table.getPageCount()}`} + + +
) } diff --git a/dapp/src/data/mock-transactions.ts b/dapp/src/data/mock-transactions.ts index ee48ca8f0..1abd7df3b 100644 --- a/dapp/src/data/mock-transactions.ts +++ b/dapp/src/data/mock-transactions.ts @@ -67,6 +67,72 @@ export const MOCK_ALL_TRANSACTIONS: TxHistory[] = [ status: "Completed", }, }, + { + callTx: { + timestamp: 1700009973, + action: "Unstake", + asset: "BTC", + amount: 6.0, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700009973, + action: "Receive", + asset: "stBTC", + amount: 6.0, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, + { + callTx: { + timestamp: 1700608973, + action: "Unstake", + asset: "stBTC", + amount: 32.1, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700608973, + action: "Receive", + asset: "BTC", + amount: 32.1, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, + { + callTx: { + timestamp: 1700578973, + action: "Unstake", + asset: "stBTC", + amount: 6.14, + account: "2MsjRekULh27YSM17p8gSNkVvbXw6wc4kcZ", + txHash: + "925c8910775c1842fbcfee782104d0d9934dde6f0ca00d393858fcbe8ac90eb7", + status: "Completed", + }, + receiptTx: { + timestamp: 1700578973, + action: "Receive", + asset: "BTC", + amount: 6.14, + account: "0x208e94d5661a73360d9387d3ca169e5c130090cd", + txHash: + "0xf612b8999e765f9631c5e32a9f424a097936da1c527953e78dc8da20f65bc3ee", + status: "Completed", + }, + }, ] export const MOCK_USER_TRANSACTIONS: TxHistory[] = [ diff --git a/dapp/src/hooks/useTransactionHistoryTable.ts b/dapp/src/hooks/useTransactionHistoryTable.ts index 9c7a9837a..a1593cea9 100644 --- a/dapp/src/hooks/useTransactionHistoryTable.ts +++ b/dapp/src/hooks/useTransactionHistoryTable.ts @@ -2,6 +2,7 @@ import { useState } from "react" import { ColumnDef, SortingState, + PaginationState, Table, getCoreRowModel, getPaginationRowModel, @@ -20,15 +21,22 @@ export function useTransactionHistoryTable({ columns, }: TransactionHistoryTable): Table { const [sorting, setSorting] = useState([]) + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 4, + }) + const table = useReactTable({ columns, data, - getCoreRowModel: getCoreRowModel(), onSortingChange: setSorting, + onPaginationChange: setPagination, + getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), state: { sorting, + pagination, }, }) diff --git a/dapp/src/static/icons/ChevronLeft.tsx b/dapp/src/static/icons/ChevronLeft.tsx new file mode 100644 index 000000000..fe133ab06 --- /dev/null +++ b/dapp/src/static/icons/ChevronLeft.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const ChevronLeft = createIcon({ + displayName: "ChevronLeft", + viewBox: "0 0 24 24", + path: ( + + + + ), +}) diff --git a/dapp/src/static/icons/index.ts b/dapp/src/static/icons/index.ts index 72155bb3b..d6999161f 100644 --- a/dapp/src/static/icons/index.ts +++ b/dapp/src/static/icons/index.ts @@ -7,3 +7,4 @@ export * from "./TBTCSymbol" export * from "./Sort" export * from "./ArrowDown" export * from "./ArrowUp" +export * from "./ChevronLeft"