diff --git a/apps/portal/src/components/others/AllSupportedWallets.tsx b/apps/portal/src/components/others/AllSupportedWallets.tsx
index c9982d4c726..81150e640f7 100644
--- a/apps/portal/src/components/others/AllSupportedWallets.tsx
+++ b/apps/portal/src/components/others/AllSupportedWallets.tsx
@@ -1,11 +1,23 @@
+"use client";
+
+import {
+ QueryClient,
+ QueryClientProvider,
+ useQuery,
+} from "@tanstack/react-query";
+import { ChevronLeftIcon, ChevronRightIcon, SearchIcon } from "lucide-react";
import Image from "next/image";
+import { useMemo, useState } from "react";
import {
getAllWalletsList,
getWalletInfo,
type WalletId,
} from "thirdweb/wallets";
-import { DocLink, InlineCode } from "../Document";
+import { DocLink } from "../Document/DocLink";
+import { InlineCode } from "../Document/InlineCode";
import { Table, TBody, Td, Th, Tr } from "../Document/Table";
+import { Button } from "../ui/button";
+import { Input } from "../ui/input";
const specialWallets: {
[key in WalletId]?: boolean;
@@ -14,44 +26,215 @@ const specialWallets: {
smart: true,
};
-export async function AllSupportedWallets() {
- const wallets = await getAllWalletsList();
+const ITEMS_PER_PAGE = 20;
+
+const queryClient = new QueryClient();
+
+export function AllSupportedWallets() {
+ return (
+
+
+
+ );
+}
+
+function AllSupportedWalletsContent() {
+ const [searchQuery, setSearchQuery] = useState("");
+ const [currentPage, setCurrentPage] = useState(1);
+
+ const { data: wallets, isLoading: loading } = useQuery({
+ queryKey: ["allWalletsList"],
+ queryFn: async () => {
+ const allWallets = await getAllWalletsList();
+ return allWallets
+ .filter((w) => !(w.id in specialWallets))
+ .map((w) => ({
+ id: w.id,
+ name: w.name,
+ }));
+ },
+ staleTime: 1000 * 60 * 5, // 5 minutes
+ });
+
+ const filteredWallets = useMemo(() => {
+ if (!searchQuery) return wallets || [];
+ if (!wallets) return [];
+
+ setCurrentPage(1);
+ const query = searchQuery.toLowerCase();
+ return wallets.filter(
+ (wallet) =>
+ wallet.name.toLowerCase().includes(query) ||
+ wallet.id.toLowerCase().includes(query),
+ );
+ }, [wallets, searchQuery]);
+
+ const totalPages = Math.ceil(filteredWallets.length / ITEMS_PER_PAGE);
+ const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
+ const endIndex = startIndex + ITEMS_PER_PAGE;
+ const currentWallets = filteredWallets.slice(startIndex, endIndex);
+
+ const handlePreviousPage = () => {
+ setCurrentPage((prev) => Math.max(prev - 1, 1));
+ };
+
+ const handleNextPage = () => {
+ setCurrentPage((prev) => Math.min(prev + 1, totalPages));
+ };
+
+ const handlePageClick = (page: number) => {
+ setCurrentPage(page);
+ };
+
+ if (loading) {
+ return (
+
+ );
+ }
return (
-
-
-
- | Wallet |
- ID |
-
-
- {wallets
- .filter((w) => !(w.id in specialWallets))
- .map((w) => {
- return (
-
+
+ {/* Search Input */}
+
+
+ setSearchQuery(e.target.value)}
+ className="pl-10"
+ />
+
+
+ {/* Results count */}
+
+ {filteredWallets.length === wallets?.length
+ ? `Showing ${filteredWallets.length} wallets`
+ : `Found ${filteredWallets.length} of ${wallets?.length} wallets`}
+
+
+ {/* Table */}
+
+
+
+ | Wallet |
+ ID |
+
+
+ {currentWallets.length === 0 ? (
+
+ |
+ {searchQuery
+ ? "No wallets found matching your search."
+ : "No wallets available."}
+ |
+
+ ) : (
+ currentWallets.map((wallet) => (
+
|
-
- {w.name}
+
+ {wallet.name}
|
-
+
|
- );
- })}
-
-
+ ))
+ )}
+
+
+
+ {/* Pagination */}
+ {totalPages > 1 && (
+
+
+ Page {currentPage} of {totalPages}
+ {filteredWallets.length > 0 && (
+
+ (showing {startIndex + 1}-
+ {Math.min(endIndex, filteredWallets.length)} of{" "}
+ {filteredWallets.length})
+
+ )}
+
+
+
+
+
+ {/* Page numbers */}
+
+ {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
+ let pageNumber: number;
+
+ if (totalPages <= 5) {
+ pageNumber = i + 1;
+ } else if (currentPage <= 3) {
+ pageNumber = i + 1;
+ } else if (currentPage >= totalPages - 2) {
+ pageNumber = totalPages - 4 + i;
+ } else {
+ pageNumber = currentPage - 2 + i;
+ }
+
+ return (
+
+ );
+ })}
+
+
+
+
+
+ )}
+
);
}
-async function WalletImage(props: { id: WalletId }) {
- const img = await getWalletInfo(props.id, true);
+function WalletImage(props: { id: WalletId }) {
+ const { data: img } = useQuery({
+ queryKey: ["wallet-image", props.id],
+ queryFn: () => getWalletInfo(props.id, true),
+ staleTime: 1000 * 60 * 60 * 24, // 24 hours
+ });
+
+ if (!img) {
+ return (
+
+ );
+ }
+
return (
);