From fa30e4a5c318429ec9abced465e2d796da48c653 Mon Sep 17 00:00:00 2001 From: Joseph Chalabi Date: Wed, 4 Dec 2024 16:07:53 -0700 Subject: [PATCH] feat: add pagination to token list --- components/bank/components/historyBox.tsx | 14 +- components/bank/components/tokenList.tsx | 297 +++++++++++++--------- pages/bank.tsx | 14 +- 3 files changed, 193 insertions(+), 132 deletions(-) diff --git a/components/bank/components/historyBox.tsx b/components/bank/components/historyBox.tsx index af9091dc..3471c2c0 100644 --- a/components/bank/components/historyBox.tsx +++ b/components/bank/components/historyBox.tsx @@ -3,13 +3,9 @@ import { TruncatedAddressWithCopy } from '@/components/react/addressCopy'; import TxInfoModal from '../modals/txInfo'; import { shiftDigits, truncateString } from '@/utils'; import { BurnIcon, DenomImage, formatDenom, MintIcon } from '@/components'; -import { - HistoryTxType, - useGetFilteredTxAndSuccessfulProposals, - useTokenFactoryDenomsMetadata, -} from '@/hooks'; +import { HistoryTxType, useTokenFactoryDenomsMetadata } from '@/hooks'; import { ReceiveIcon, SendIcon } from '@/components/icons'; -import { useEndpointStore } from '@/store/endpointStore'; + import useIsMobile from '@/hooks/useIsMobile'; interface Transaction { @@ -75,8 +71,8 @@ export function HistoryBox({ const { metadatas } = useTokenFactoryDenomsMetadata(); const isMobile = useIsMobile(); - const skeletonGroupCount = isMobile ? 1 : 2; - const skeletonTxCount = isMobile ? 5 : 7; + const skeletonGroupCount = 1; + const skeletonTxCount = isMobile ? 5 : 9; function formatDateShort(dateString: string): string { const date = new Date(dateString); @@ -169,7 +165,7 @@ export function HistoryBox({ return (
-
+

Transaction History

diff --git a/components/bank/components/tokenList.tsx b/components/bank/components/tokenList.tsx index 2b717756..82ec2b63 100644 --- a/components/bank/components/tokenList.tsx +++ b/components/bank/components/tokenList.tsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo } from 'react'; +import React, { useState, useMemo, useEffect } from 'react'; import { DenomImage } from '@/components/factory'; import { shiftDigits } from '@/utils'; import { CombinedBalanceInfo } from '@/utils/types'; @@ -27,26 +27,95 @@ export default function TokenList({ const [searchTerm, setSearchTerm] = useState(''); const [selectedDenom, setSelectedDenom] = useState(null); const [isSendModalOpen, setIsSendModalOpen] = useState(false); + const [currentPage, setCurrentPage] = useState(1); + + const isMobile = useIsMobile(); + + const pageSize = isMobile ? 4 : 9; + const filteredBalances = useMemo(() => { if (!Array.isArray(balances)) return []; return balances.filter(balance => balance.metadata?.display.toLowerCase().includes(searchTerm.toLowerCase()) ); }, [balances, searchTerm]); - const isMobile = useIsMobile(); - const skeletonCount = isMobile ? 5 : 9; + + const totalPages = Math.max(1, Math.ceil(filteredBalances.length / pageSize)); + + useEffect(() => { + setCurrentPage(1); + }, [searchTerm]); + + const paginatedBalances = useMemo(() => { + const startIndex = (currentPage - 1) * pageSize; + return filteredBalances.slice(startIndex, startIndex + pageSize); + }, [filteredBalances, currentPage, pageSize]); return (
-
-

- Your Assets -

-
+
+
+

+ Your Assets +

+ + {totalPages > 1 && ( +
+ + + {[...Array(totalPages)].map((_, index) => { + const pageNum = index + 1; + if ( + pageNum === 1 || + pageNum === totalPages || + (pageNum >= currentPage - 1 && pageNum <= currentPage + 1) + ) { + return ( + + ); + } else if (pageNum === currentPage - 2 || pageNum === currentPage + 2) { + return ( + + ... + + ); + } + return null; + })} + + +
+ )} +
+ +
setSearchTerm(e.target.value)} @@ -54,122 +123,116 @@ export default function TokenList({
-
-
- {isLoading ? ( -
- {[...Array(skeletonCount)].map(i => ( -
-
-
-
-
-
-
-
-
-
-
-
+
+ {isLoading ? ( +
+ {[...Array(pageSize)].map((_, i) => ( +
+
+
+
+
+
- ))} -
- ) : filteredBalances.length === 0 ? ( -
-

No tokens found!

-
- ) : ( -
- {filteredBalances.map(balance => ( -
{ - setSelectedDenom(balance?.denom); - ( - document?.getElementById(`denom-info-modal`) as HTMLDialogElement - )?.showModal(); - }} - > -
-
- -
-
-

- {truncateString(balance.metadata?.display ?? '', 12)} -

-

- {balance.metadata?.denom_units[0]?.denom.split('/').pop()} -

-
+
+
+
+
+
+
+ ))} +
+ ) : paginatedBalances.length === 0 ? ( +
+

No tokens found!

+
+ ) : ( +
+ {paginatedBalances.map(balance => ( +
{ + setSelectedDenom(balance?.denom); + (document?.getElementById(`denom-info-modal`) as HTMLDialogElement)?.showModal(); + }} + > +
+
+
-
+

- {Number( - shiftDigits( - balance.amount, - -(balance.metadata?.denom_units[1]?.exponent ?? 6) - ) - ).toLocaleString(undefined, { - maximumFractionDigits: balance.metadata?.denom_units[1]?.exponent ?? 6, - })}{' '} - - {truncateString(balance.metadata?.display ?? '', 12).toUpperCase()} - + {truncateString(balance.metadata?.display ?? '', 12)} +

+

+ {balance.metadata?.denom_units[0]?.denom.split('/').pop()}

-
-
- -
- ))} -
- )} - {/* DenomInfoModal */} - b.denom === selectedDenom)?.metadata ?? null} - modalId="denom-info-modal" - /> - -
+
+

+ {Number( + shiftDigits( + balance.amount, + -(balance.metadata?.denom_units[1]?.exponent ?? 6) + ) + ).toLocaleString(undefined, { + maximumFractionDigits: balance.metadata?.denom_units[1]?.exponent ?? 6, + })}{' '} + {truncateString(balance.metadata?.display ?? '', 12).toUpperCase()} +

+
+
+ + +
+
+ ))} +
+ )}
+ + b.denom === selectedDenom)?.metadata ?? null} + modalId="denom-info-modal" + /> +
); } diff --git a/pages/bank.tsx b/pages/bank.tsx index a8710698..fe631302 100644 --- a/pages/bank.tsx +++ b/pages/bank.tsx @@ -4,6 +4,7 @@ import TokenList from '@/components/bank/components/tokenList'; import { chainName } from '@/config'; import { useGetFilteredTxAndSuccessfulProposals, + useIsMobile, useTokenBalances, useTokenBalancesResolved, useTokenFactoryDenomsMetadata, @@ -33,7 +34,9 @@ export default function Bank() { const { metadatas, isMetadatasLoading } = useTokenFactoryDenomsMetadata(); const [currentPage, setCurrentPage] = useState(1); - const pageSize = 10; + const isMobile = useIsMobile(); + + const pageSize = isMobile ? 4 : 9; const { sendTxs, @@ -139,15 +142,14 @@ export default function Bank() {
{!isWalletConnected ? ( } /> ) : ( isWalletConnected && combinedBalances && ( -
-
+
+
-
+