From 6506cb1d7f07a4c69088b2360b23a85432c93d22 Mon Sep 17 00:00:00 2001 From: He1DAr Date: Tue, 2 Jan 2024 16:17:54 -0500 Subject: [PATCH] feat: mempool txs sort menu --- package.json | 4 +- pnpm-lock.yaml | 16 +- src/app/_components/Stats/StatSection.tsx | 16 +- src/app/transactions/MempoolFeeStats.tsx | 139 ++++++++++++++++++ src/app/transactions/loading.tsx | 32 +++- src/app/transactions/page.tsx | 36 ++++- .../txid/[txId]/TenureChange/TxDetails.tsx | 106 ++++++------- src/app/txid/[txId]/TenureChange/index.tsx | 34 ++--- src/app/txid/[txId]/Tx.tsx | 4 +- src/common/api/client.ts | 3 + src/common/components/TabsContainer.tsx | 21 ++- src/common/components/TxIcon.tsx | 4 +- src/common/components/TxTypeTag.tsx | 1 - src/common/components/transaction-item.tsx | 6 +- src/common/queries/usMempoolFee.ts | 38 +++++ src/common/queries/useCurrentPrices.ts | 9 ++ src/common/utils/utils.ts | 4 +- .../txs-list/ListItem/MempoolTxListItem.tsx | 6 + src/features/txs-list/ListItem/TxListItem.tsx | 7 +- src/features/txs-list/TxTitle.tsx | 18 +-- .../txs-list/tabs/CSVDownloadButton.tsx | 2 + src/features/txs-list/tabs/TxListTabsBase.tsx | 47 +++++- src/features/txs-list/utils.ts | 4 +- 23 files changed, 432 insertions(+), 125 deletions(-) create mode 100644 src/app/transactions/MempoolFeeStats.tsx create mode 100644 src/common/queries/usMempoolFee.ts diff --git a/package.json b/package.json index 0301397e3..e204178f9 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@segment/analytics-next": "1.60.0", "@segment/snippet": "4.16.2", "@stacks/auth": "6.9.0", - "@stacks/blockchain-api-client": "7.3.2", + "@stacks/blockchain-api-client": "v7.4.0-beta.2", "@stacks/common": "6.8.1", "@stacks/connect": "7.4.0", "@stacks/connect-react": "22.2.0", @@ -112,7 +112,7 @@ "@playwright/test": "1.40.0", "@stacks/eslint-config": "2.0.0", "@stacks/prettier-config": "0.0.10", - "@stacks/stacks-blockchain-api-types": "7.4.0-nakamoto.6", + "@stacks/stacks-blockchain-api-types": "v7.4.0-beta.2", "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8dd81a2a4..40ea480cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,8 +76,8 @@ dependencies: specifier: 6.9.0 version: 6.9.0 '@stacks/blockchain-api-client': - specifier: 7.3.2 - version: 7.3.2 + specifier: v7.4.0-beta.2 + version: 7.4.0-beta.2 '@stacks/common': specifier: 6.8.1 version: 6.8.1 @@ -279,8 +279,8 @@ devDependencies: specifier: 0.0.10 version: 0.0.10 '@stacks/stacks-blockchain-api-types': - specifier: 7.4.0-nakamoto.6 - version: 7.4.0-nakamoto.6 + specifier: v7.4.0-beta.2 + version: 7.4.0-beta.2 '@testing-library/jest-dom': specifier: 5.16.5 version: 5.16.5 @@ -4491,8 +4491,8 @@ packages: - encoding dev: false - /@stacks/blockchain-api-client@7.3.2: - resolution: {integrity: sha512-nhFDpA2d5mN2YCmllIUrmkQzd5CEtqAR9XUUrvVOKsLw7pdkF21grbd8ZbKARFLR/l0rYwHB8YW2sL2fv8Ty/A==} + /@stacks/blockchain-api-client@7.4.0-beta.2: + resolution: {integrity: sha512-pysIQWBfFzVYTwsHSt87E7+ELe/yvHOwq4E02HS4KghLtpb+q92QYi9eqRw9MUkJNDhmYyQpPq83dc3OmCzAAQ==} dependencies: '@stacks/stacks-blockchain-api-types': 7.3.2 '@types/ws': 7.4.7 @@ -4618,8 +4618,8 @@ packages: resolution: {integrity: sha512-1r0+eqEWOOo7UYrFq9HGbc02DVME3NVCW/45sNKPN31PkOMMaK59DHragPJ2QbxPFiutVDUCS924+48+o3+0Tw==} dev: false - /@stacks/stacks-blockchain-api-types@7.4.0-nakamoto.6: - resolution: {integrity: sha512-8muZdkquqVBvHboa8eWBr1bMerhfcAjjWawGWMRAHmAGBN87QUhY6IM5Hbsd+T9gWgqsPVccs1UKx7jxy795IA==} + /@stacks/stacks-blockchain-api-types@7.4.0-beta.2: + resolution: {integrity: sha512-zwjtSWPhfpRSxsKVfC2A87WaVuWWGLEOCRXw4kthBc5/PvlxvlLiCbs9yzdPBXmdQ+Q4OVj5MYhO8qEsnB+SBA==} dev: true /@stacks/transactions@6.9.0: diff --git a/src/app/_components/Stats/StatSection.tsx b/src/app/_components/Stats/StatSection.tsx index 4645f7237..9be7544fc 100644 --- a/src/app/_components/Stats/StatSection.tsx +++ b/src/app/_components/Stats/StatSection.tsx @@ -4,16 +4,18 @@ import { FC, ReactNode } from 'react'; import * as React from 'react'; import { Box } from '../../../ui/Box'; -import { Flex } from '../../../ui/Flex'; +import { Flex, FlexProps } from '../../../ui/Flex'; import { Grid } from '../../../ui/Grid'; import { Text } from '../../../ui/Text'; -export const StatSection: FC<{ - title: ReactNode; - bodyMainText: ReactNode; - bodySecondaryText: ReactNode; - caption: ReactNode; -}> = ({ title, bodyMainText, bodySecondaryText, caption, ...rest }) => ( +export const StatSection: FC< + { + title: ReactNode; + bodyMainText: ReactNode; + bodySecondaryText: ReactNode; + caption: ReactNode; + } & Omit +> = ({ title, bodyMainText, bodySecondaryText, caption, ...rest }) => ( |} gap={1}> + + + + + {`${Number((mempoolFeeTokenTransfer / MICROSTACKS_IN_STACKS).toFixed(3))}`} STX + + + + + + + + {`${Number((mempoolFeeContractCall / MICROSTACKS_IN_STACKS).toFixed(3))}`} STX + + + + + + + + {`${Number((mempoolFeeSmartContract / MICROSTACKS_IN_STACKS).toFixed(3))}`} STX + + + + + ); +} + +function MempoolFeeSection({ + mempoolFeeResponse, + priority, + stxPrice, + ...rest +}: { + mempoolFeeResponse: MempoolFeePriorities; + priority: keyof MempoolFeePrioritiesAll; + stxPrice: number; +} & FlexProps) { + const mempoolFeeAll = mempoolFeeResponse?.all?.[priority] || 0; + const mempoolFeeTokenTransfer = mempoolFeeResponse?.token_transfer?.[priority] || 0; + const mempoolFeeContractCall = mempoolFeeResponse?.contract_call?.[priority] || 0; + const mempoolFeeSmartContract = mempoolFeeResponse?.smart_contract?.[priority] || 0; + return ( + + } + borderColor={'border'} + {...rest} + /> + ); +} + +export function MempoolFeeStats() { + const mempoolFeeResponse = useSuspenseMempoolFee().data as MempoolFeePriorities; + const { data: stxPrice } = useCurrentStxPrice(); + console.log(mempoolFeeResponse); + return ( + + + + + + + ); +} + +export function MempoolFeeStatsWithErrorBoundary() { + return ( + null}> + + + ); +} diff --git a/src/app/transactions/loading.tsx b/src/app/transactions/loading.tsx index ce2f9461d..4e3f635d1 100644 --- a/src/app/transactions/loading.tsx +++ b/src/app/transactions/loading.tsx @@ -1,20 +1,42 @@ 'use client'; -import React from 'react'; +import * as React from 'react'; +import { TabsContainer } from '../../common/components/TabsContainer'; import { SkeletonTxsList } from '../../features/txs-list/SkeletonTxsList'; -import { TxListTabsBase } from '../../features/txs-list/tabs/TxListTabsBase'; import { Flex } from '../../ui/Flex'; import { Skeleton } from '../../ui/Skeleton'; import { PageTitle } from '../_components/PageTitle'; +import { SkeletonStatSection } from '../_components/Stats/SkeletonStatSection'; +import { Wrapper as StatsWrapper } from '../_components/Stats/Wrapper'; export default function Loading() { return ( - + <> - } mempoolList={} /> - + + + + + + + + , + }, + { + title: 'Pending', + content: , + }, + ]} + actions={null} + gridColumnEnd={'3'} + /> + ); } diff --git a/src/app/transactions/page.tsx b/src/app/transactions/page.tsx index 1c17fe1c9..799c6f0ed 100644 --- a/src/app/transactions/page.tsx +++ b/src/app/transactions/page.tsx @@ -2,14 +2,46 @@ import { NextPage } from 'next'; import React from 'react'; +import { BsChevronDown, BsCodeSlash } from 'react-icons/bs'; +import { RxCube } from 'react-icons/rx'; +import { numberToString } from '../../common/utils/utils'; import { TxListTabs } from '../../features/txs-list/tabs/TxListTabs'; -import { PageTitle } from '../_components/PageTitle'; +import { Button } from '../../ui/Button'; +import { Flex } from '../../ui/Flex'; +import { Icon } from '../../ui/Icon'; +import { Menu } from '../../ui/Menu'; +import { MenuButton } from '../../ui/MenuButton'; +import { MenuDivider } from '../../ui/MenuDivider'; +import { MenuItem } from '../../ui/MenuItem'; +import { MenuList } from '../../ui/MenuList'; +import { Tag } from '../../ui/Tag'; +import { TagLabel } from '../../ui/TagLabel'; +import { useColorMode } from '../../ui/hooks/useColorMode'; +import { FunctionIcon } from '../../ui/icons'; +import { CubeSparkleIcon } from '../../ui/icons/CubeSparkleIcon'; +import { PageTitle, PageTitleWithTags } from '../_components/PageTitle'; +import { StatSection } from '../_components/Stats/StatSection'; +import { + CurrentStackingCycle, + LastBlock, + NextStackingCycle, + StxSupply, +} from '../_components/Stats/Stats'; +import { Wrapper } from '../_components/Stats/Wrapper'; +import { LinksGroup } from '../token/[tokenId]/LinksGroup'; +import { LinksMenu } from '../token/[tokenId]/LinksMenu'; +import { Tabs } from '../token/[tokenId]/Tabs'; +import { TokenInfo } from '../token/[tokenId]/TokenInfo'; +import { MempoolFeeStats, MempoolFeeStatsWithErrorBoundary } from './MempoolFeeStats'; const TransactionsPage: NextPage = () => { return ( <> - Transactions + + Transactions + + ); diff --git a/src/app/txid/[txId]/TenureChange/TxDetails.tsx b/src/app/txid/[txId]/TenureChange/TxDetails.tsx index 7aa61dc17..79d218c88 100644 --- a/src/app/txid/[txId]/TenureChange/TxDetails.tsx +++ b/src/app/txid/[txId]/TenureChange/TxDetails.tsx @@ -1,53 +1,53 @@ -import * as React from 'react'; - -import { - MempoolTenureChangeTransaction, - TenureChangeTransaction, -} from '@stacks/stacks-blockchain-api-types'; - -import { KeyValueHorizontal } from '../../../../common/components/KeyValueHorizontal'; -import { Section } from '../../../../common/components/Section'; -import { Value } from '../../../../common/components/Value'; -import { capitalize } from '../../../../common/utils/utils'; -import { Box } from '../../../../ui/Box'; -import { Flex } from '../../../../ui/Flex'; -import { BlockHash } from '../TxDetails/BlockHash'; -import { BlockHeight } from '../TxDetails/BlockHeight'; -import { Fees } from '../TxDetails/Fees'; -import { ID } from '../TxDetails/ID'; -import { NonCanonical } from '../TxDetails/NonCanonical'; -import { Nonce } from '../TxDetails/Nonce'; -import { Sender } from '../TxDetails/Sender'; - -interface TxDetailsProps { - tx: TenureChangeTransaction | MempoolTenureChangeTransaction; -} - -export const TxDetails: React.FC = ({ tx }) => { - const tenureChangePayload: Record = tx.tenure_change_payload || {}; - return ( - <> -
- - - - - - - - - - {Object.keys(tenureChangePayload).map(key => { - return ( - {tenureChangePayload[key]}} - /> - ); - })} - - -
- - ); -}; +// import * as React from 'react'; +// +// import { +// MempoolTenureChangeTransaction, +// TenureChangeTransaction, +// } from '@stacks/stacks-blockchain-api-types'; +// +// import { KeyValueHorizontal } from '../../../../common/components/KeyValueHorizontal'; +// import { Section } from '../../../../common/components/Section'; +// import { Value } from '../../../../common/components/Value'; +// import { capitalize } from '../../../../common/utils/utils'; +// import { Box } from '../../../../ui/Box'; +// import { Flex } from '../../../../ui/Flex'; +// import { BlockHash } from '../TxDetails/BlockHash'; +// import { BlockHeight } from '../TxDetails/BlockHeight'; +// import { Fees } from '../TxDetails/Fees'; +// import { ID } from '../TxDetails/ID'; +// import { NonCanonical } from '../TxDetails/NonCanonical'; +// import { Nonce } from '../TxDetails/Nonce'; +// import { Sender } from '../TxDetails/Sender'; +// +// interface TxDetailsProps { +// tx: TenureChangeTransaction | MempoolTenureChangeTransaction; +// } +// +// export const TxDetails: React.FC = ({ tx }) => { +// const tenureChangePayload: Record = tx.tenure_change_payload || {}; +// return ( +// <> +//
+// +// +// +// +// +// +// +// +// +// {Object.keys(tenureChangePayload).map(key => { +// return ( +// {tenureChangePayload[key]}} +// /> +// ); +// })} +// +// +//
+// +// ); +// }; diff --git a/src/app/txid/[txId]/TenureChange/index.tsx b/src/app/txid/[txId]/TenureChange/index.tsx index daaf8cc39..da9facc13 100644 --- a/src/app/txid/[txId]/TenureChange/index.tsx +++ b/src/app/txid/[txId]/TenureChange/index.tsx @@ -1,17 +1,17 @@ -import * as React from 'react'; - -import { - MempoolTenureChangeTransaction, - TenureChangeTransaction, -} from '@stacks/stacks-blockchain-api-types'; - -import { TxPage } from '../TxPage'; -import { TxDetails } from './TxDetails'; - -export function TenureChangePage({ - tx, -}: { - tx: TenureChangeTransaction | MempoolTenureChangeTransaction; -}) { - return } />; -} +// import * as React from 'react'; +// +// import { +// MempoolTenureChangeTransaction, +// TenureChangeTransaction, +// } from '@stacks/stacks-blockchain-api-types'; +// +// import { TxPage } from '../TxPage'; +// import { TxDetails } from './TxDetails'; +// +// export function TenureChangePage({ +// tx, +// }: { +// tx: TenureChangeTransaction | MempoolTenureChangeTransaction; +// }) { +// return } />; +// } diff --git a/src/app/txid/[txId]/Tx.tsx b/src/app/txid/[txId]/Tx.tsx index 18914339a..43e77675d 100644 --- a/src/app/txid/[txId]/Tx.tsx +++ b/src/app/txid/[txId]/Tx.tsx @@ -5,7 +5,7 @@ import { CoinbasePage } from './CoinbasePage'; import { ContractCallPage } from './ContractCall'; import { PoisonMicroblock } from './PoisonMicroblock'; import { SmartContractTx } from './SmartContract/SmartContractTx'; -import { TenureChangePage } from './TenureChange'; +// import { TenureChangePage } from './TenureChange'; import { TokenTransferPage } from './TokenTransfer'; export function Tx({ txId }: { txId: string }) { @@ -21,7 +21,7 @@ export function Tx({ txId }: { txId: string }) { if (tx.tx_type === 'smart_contract') return ; - if (tx.tx_type === 'tenure_change') return ; + // if (tx.tx_type === 'tenure_change') return ; return null; } diff --git a/src/common/api/client.ts b/src/common/api/client.ts index c29c987f9..a0f65d2a8 100644 --- a/src/common/api/client.ts +++ b/src/common/api/client.ts @@ -11,6 +11,7 @@ import { FeesApi, FungibleTokensApi, InfoApi, + MempoolApi, MicroblocksApi, Middleware, NonFungibleTokensApi, @@ -40,6 +41,7 @@ export function apiClients( const rosettaApi = new RosettaApi(config); const fungibleTokensApi = new FungibleTokensApi(config); const nonFungibleTokensApi = new NonFungibleTokensApi(config); + const mempoolApi = new MempoolApi(config); const tokenMetadataApi = tokenMetadataApiConfig ? new TokensApi(tokenMetadataApiConfig) : undefined; @@ -57,6 +59,7 @@ export function apiClients( rosettaApi, fungibleTokensApi, nonFungibleTokensApi, + mempoolApi, tokenMetadataApi, config, }; diff --git a/src/common/components/TabsContainer.tsx b/src/common/components/TabsContainer.tsx index a84c4ffc3..7d74e12e3 100644 --- a/src/common/components/TabsContainer.tsx +++ b/src/common/components/TabsContainer.tsx @@ -1,6 +1,8 @@ import { FC, ReactNode } from 'react'; -import { FlexProps } from '../../ui/Flex'; +import { Box } from '../../ui/Box'; +import { Flex, FlexProps } from '../../ui/Flex'; +import { Stack } from '../../ui/Stack'; import { Tab } from '../../ui/Tab'; import { TabList } from '../../ui/TabList'; import { TabPanel } from '../../ui/TabPanel'; @@ -10,6 +12,7 @@ import { Section } from './Section'; export const TabsContainer: FC< { + setTabIndex?: (index: number) => void; title?: string | ReactNode; tabs: { title: string; @@ -17,14 +20,18 @@ export const TabsContainer: FC< }[]; actions?: ReactNode; } & FlexProps -> = ({ title, tabs, actions, ...props }) => ( +> = ({ setTabIndex, title, tabs, actions, ...props }) => (
- + setTabIndex?.(index)}> - {tabs.map(tab => ( - {tab.title} - ))} - {actions} + + + {tabs.map(tab => ( + {tab.title} + ))} + + {actions} + {tabs.map(tab => ( diff --git a/src/common/components/TxIcon.tsx b/src/common/components/TxIcon.tsx index 25e341cbf..b67a93f00 100644 --- a/src/common/components/TxIcon.tsx +++ b/src/common/components/TxIcon.tsx @@ -28,8 +28,8 @@ export const getTxTypeIcon = (txType: Transaction['tx_type']): FC => { case 'poison_microblock': return RxCube; - case 'tenure_change': - return PiArrowBendDownRight; + // case 'tenure_change': + // return PiArrowBendDownRight; default: return StxIcon; diff --git a/src/common/components/TxTypeTag.tsx b/src/common/components/TxTypeTag.tsx index 55fa00483..847f28faa 100644 --- a/src/common/components/TxTypeTag.tsx +++ b/src/common/components/TxTypeTag.tsx @@ -8,7 +8,6 @@ import { Transaction } from '@stacks/stacks-blockchain-api-types'; import { FlexProps } from '../../ui/Flex'; import { Icon } from '../../ui/Icon'; import { TransactionType } from '../constants/constants'; -import { Badge } from './Badge'; import { getTxTypeIcon } from './TxIcon'; import { StyledBadge } from './status'; diff --git a/src/common/components/transaction-item.tsx b/src/common/components/transaction-item.tsx index a58237902..5d90e4354 100644 --- a/src/common/components/transaction-item.tsx +++ b/src/common/components/transaction-item.tsx @@ -113,9 +113,9 @@ export const AddressArea = React.memo( ); } - if (tx.tx_type === 'tenure_change') { - return Cause: {tx.tenure_change_payload?.cause}; - } + // if (tx.tx_type === 'tenure_change') { + // return Cause: {tx.tenure_change_payload?.cause}; + // } return null; } ); diff --git a/src/common/queries/usMempoolFee.ts b/src/common/queries/usMempoolFee.ts new file mode 100644 index 000000000..5a05fd231 --- /dev/null +++ b/src/common/queries/usMempoolFee.ts @@ -0,0 +1,38 @@ +import { + UseQueryOptions, + UseSuspenseQueryOptions, + useQuery, + useSuspenseQuery, +} from '@tanstack/react-query'; +import { address } from 'bitcoinjs-lib'; + +import { MempoolFeePriorities } from '@stacks/blockchain-api-client/src/generated/models'; +import { AddressBalanceResponse } from '@stacks/stacks-blockchain-api-types'; + +import { useApi } from '../api/useApi'; +import { ONE_MINUTE } from './query-stale-time'; + +export function useMempoolFee(options: any = {}) { + const api = useApi(); + return useQuery({ + queryKey: ['mempoolFee'], + queryFn: () => { + return api.mempoolApi.getMempoolFeePriorities(); + }, + staleTime: ONE_MINUTE, + ...options, + }); +} + +export function useSuspenseMempoolFee(options: any = {}) { + const api = useApi(); + if (!address) throw new Error('Address is required'); + return useSuspenseQuery({ + queryKey: ['mempoolFee'], + queryFn: () => { + return api.mempoolApi.getMempoolFeePriorities(); + }, + staleTime: ONE_MINUTE, + ...options, + }); +} diff --git a/src/common/queries/useCurrentPrices.ts b/src/common/queries/useCurrentPrices.ts index b92c7937c..3d0696c1e 100644 --- a/src/common/queries/useCurrentPrices.ts +++ b/src/common/queries/useCurrentPrices.ts @@ -25,6 +25,15 @@ const getCurrentStxPrice = async () => .then(res => res.json()) .then(data => data?.blockstack?.usd || 0); +export const useCurrentStxPrice = (options?: UseQueryOptions) => + useQuery({ + queryKey: ['current-stx-price'], + queryFn: getCurrentStxPrice, + staleTime: 30 * 60 * 1000, + retry: false, + ...options, + }); + export const useSuspenseCurrentStxPrice = (options?: UseQueryOptions) => useSuspenseQuery({ queryKey: ['current-stx-price'], diff --git a/src/common/utils/utils.ts b/src/common/utils/utils.ts index e4d07fb67..dda387c2e 100644 --- a/src/common/utils/utils.ts +++ b/src/common/utils/utils.ts @@ -320,7 +320,7 @@ export const getTxTitle = (transaction: Transaction | MempoolTransaction) => { : 'Coinbase'; case 'poison_microblock': return `Poison microblock transaction`; - case 'tenure_change': - return `Tenure change`; + // case 'tenure_change': + // return `Tenure change`; } }; diff --git a/src/features/txs-list/ListItem/MempoolTxListItem.tsx b/src/features/txs-list/ListItem/MempoolTxListItem.tsx index 06d9986aa..bed4c6142 100644 --- a/src/features/txs-list/ListItem/MempoolTxListItem.tsx +++ b/src/features/txs-list/ListItem/MempoolTxListItem.tsx @@ -9,6 +9,7 @@ import { AddressArea, Nonce, TxTimestamp } from '../../../common/components/tran import { useGlobalContext } from '../../../common/context/useAppContext'; import { buildUrl } from '../../../common/utils/buildUrl'; import { getTransactionStatus } from '../../../common/utils/transactions'; +import { MICROSTACKS_IN_STACKS } from '../../../common/utils/utils'; import { FlexProps } from '../../../ui/Flex'; import { HStack } from '../../../ui/HStack'; import { Caption, Title } from '../../../ui/typography'; @@ -75,6 +76,11 @@ export const MempoolTxListItem: FC = memo(({ tx, ...res {didFail && 'Failed'} {isPending && } + {Number(tx.fee_rate) > 0 ? ( + + fee: {`${Number(tx.fee_rate) / MICROSTACKS_IN_STACKS} STX`} + + ) : null} ), [didFail, isPending, tx.nonce] diff --git a/src/features/txs-list/ListItem/TxListItem.tsx b/src/features/txs-list/ListItem/TxListItem.tsx index 11255b4ae..71a758239 100644 --- a/src/features/txs-list/ListItem/TxListItem.tsx +++ b/src/features/txs-list/ListItem/TxListItem.tsx @@ -11,7 +11,7 @@ import { AddressArea, TxTimestamp } from '../../../common/components/transaction import { useGlobalContext } from '../../../common/context/useAppContext'; import { buildUrl } from '../../../common/utils/buildUrl'; import { getTransactionStatus } from '../../../common/utils/transactions'; -import { truncateMiddle } from '../../../common/utils/utils'; +import { MICROSTACKS_IN_STACKS, truncateMiddle } from '../../../common/utils/utils'; import { FlexProps } from '../../../ui/Flex'; import { HStack } from '../../../ui/HStack'; import { Caption } from '../../../ui/typography'; @@ -77,6 +77,11 @@ const RightSubtitle: FC<{ tx: Transaction }> = memo(({ tx }) => { {truncateMiddle(hash, 4)} )} + {Number(tx.fee_rate) > 0 ? ( + + fee: {`${Number(tx.fee_rate) / MICROSTACKS_IN_STACKS} STX`} + + ) : null} ); }); diff --git a/src/features/txs-list/TxTitle.tsx b/src/features/txs-list/TxTitle.tsx index a6473b4a6..7ab18e9a0 100644 --- a/src/features/txs-list/TxTitle.tsx +++ b/src/features/txs-list/TxTitle.tsx @@ -70,15 +70,15 @@ export const TxTitle = ( {showPrice && } ); - case 'tenure_change': - return ( - - - Tenure change - : {tx.tx_id} - - - ); + // case 'tenure_change': + // return ( + // + // + // Tenure change + // : {tx.tx_id} + // + // + // ); case 'coinbase': return ( diff --git a/src/features/txs-list/tabs/CSVDownloadButton.tsx b/src/features/txs-list/tabs/CSVDownloadButton.tsx index b67f8fefb..dc97dcece 100644 --- a/src/features/txs-list/tabs/CSVDownloadButton.tsx +++ b/src/features/txs-list/tabs/CSVDownloadButton.tsx @@ -35,6 +35,8 @@ export function CSVDownloadButton({ address }: { address: string }) { _hover={{ cursor: 'pointer', color: 'textTitle' }} data-test="csv-download-button" onClick={downloadCSV} + flexWrap={'nowrap'} + whiteSpace={'nowrap'} > Export as CSV diff --git a/src/features/txs-list/tabs/TxListTabsBase.tsx b/src/features/txs-list/tabs/TxListTabsBase.tsx index 377377d90..26c1df188 100644 --- a/src/features/txs-list/tabs/TxListTabsBase.tsx +++ b/src/features/txs-list/tabs/TxListTabsBase.tsx @@ -1,15 +1,31 @@ 'use client'; +import { useColorModeValue } from '@chakra-ui/react'; +import ChevronDownIcon from 'mdi-react/ChevronDownIcon'; import { useParams } from 'next/navigation'; import * as React from 'react'; -import { FC, ReactNode } from 'react'; +import { FC, ReactNode, useState } from 'react'; +import { BsChevronDown } from 'react-icons/bs'; import { TabsContainer } from '../../../common/components/TabsContainer'; import { Box } from '../../../ui/Box'; +import { Button } from '../../../ui/Button'; import { FlexProps } from '../../../ui/Flex'; +import { Icon } from '../../../ui/Icon'; +import { Menu } from '../../../ui/Menu'; +import { MenuButton } from '../../../ui/MenuButton'; +import { MenuItem } from '../../../ui/MenuItem'; +import { MenuList } from '../../../ui/MenuList'; +import { Select } from '../../../ui/Select'; import { FilterButton } from '../../txs-filter/FilterButton'; import { CSVDownloadButton } from './CSVDownloadButton'; +enum Sort { + receiptTime = 'Receipt Time', + feeRate = 'Fee rate', + size = 'Size', +} + export const TxListTabsBase: FC< { confirmedList: ReactNode; @@ -17,9 +33,15 @@ export const TxListTabsBase: FC< } & FlexProps > = ({ confirmedList, mempoolList, ...props }) => { const principal = useParams().principal; + const [tabIndex, setTabIndex] = useState(0); + const [sort, setSort] = useState(); + const bg = useColorModeValue('white', 'black'); + const color = useColorModeValue('slate.700', 'slate.400'); + const borderColor = useColorModeValue('slate.300', 'slate.900'); return ( + {!!principal && } + {/*{tabIndex === 1 && (*/} + {/* */} + {/* }*/} + {/* fontSize={'sm'}*/} + {/* bg={bg}*/} + {/* color={color}*/} + {/* fontWeight={'semibold'}*/} + {/* border={'1px'}*/} + {/* borderColor={borderColor}*/} + {/* >*/} + {/* {sort || 'Sort by'}*/} + {/* */} + {/* */} + {/* setSort(Sort.receiptTime)}>{Sort.receiptTime}*/} + {/* setSort(Sort.feeRate)}>{Sort.feeRate}*/} + {/* setSort(Sort.size)}>{Sort.size}*/} + {/* */} + {/* */} + {/*)}*/} } diff --git a/src/features/txs-list/utils.ts b/src/features/txs-list/utils.ts index 809c2f227..7155e0007 100644 --- a/src/features/txs-list/utils.ts +++ b/src/features/txs-list/utils.ts @@ -12,7 +12,7 @@ export const getTransactionTypeLabel = (value: TransactionType) => { return 'Contract deploy'; case 'poison_microblock': return 'Poison microblock'; - case 'tenure_change': - return 'Tenure change'; + // case 'tenure_change': + // return 'Tenure change'; } };