Skip to content

Commit 90dea67

Browse files
fixes
1 parent 2c7ae5c commit 90dea67

File tree

1 file changed

+69
-52
lines changed

1 file changed

+69
-52
lines changed

apps/portal/src/components/others/AllSupportedWallets.tsx

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
"use client";
22

3+
import {
4+
QueryClient,
5+
QueryClientProvider,
6+
useQuery,
7+
} from "@tanstack/react-query";
8+
import { ChevronLeftIcon, ChevronRightIcon, SearchIcon } from "lucide-react";
39
import Image from "next/image";
4-
import { useState, useEffect, useMemo } from "react";
10+
import { useMemo, useState } from "react";
511
import {
612
getAllWalletsList,
713
getWalletInfo,
814
type WalletId,
915
} from "thirdweb/wallets";
10-
import { DocLink, InlineCode } from "../Document";
16+
import { DocLink } from "../Document/DocLink";
17+
import { InlineCode } from "../Document/InlineCode";
1118
import { Table, TBody, Td, Th, Tr } from "../Document/Table";
12-
import { Input } from "../ui/input";
1319
import { Button } from "../ui/button";
14-
import { ChevronLeftIcon, ChevronRightIcon, SearchIcon } from "lucide-react";
20+
import { Input } from "../ui/input";
1521

1622
const specialWallets: {
1723
[key in WalletId]?: boolean;
@@ -22,46 +28,44 @@ const specialWallets: {
2228

2329
const ITEMS_PER_PAGE = 20;
2430

25-
interface WalletInfo {
26-
id: string;
27-
name: string;
28-
}
31+
const queryClient = new QueryClient();
2932

3033
export function AllSupportedWallets() {
31-
const [wallets, setWallets] = useState<WalletInfo[]>([]);
32-
const [loading, setLoading] = useState(true);
34+
return (
35+
<QueryClientProvider client={queryClient}>
36+
<AllSupportedWalletsContent />
37+
</QueryClientProvider>
38+
);
39+
}
40+
41+
function AllSupportedWalletsContent() {
3342
const [searchQuery, setSearchQuery] = useState("");
3443
const [currentPage, setCurrentPage] = useState(1);
3544

36-
useEffect(() => {
37-
async function loadWallets() {
38-
try {
39-
const allWallets = await getAllWalletsList();
40-
const filteredWallets = allWallets
41-
.filter((w) => !(w.id in specialWallets))
42-
.map((w) => ({
43-
id: w.id,
44-
name: w.name,
45-
}));
46-
setWallets(filteredWallets);
47-
} catch (error) {
48-
console.error("Failed to load wallets:", error);
49-
} finally {
50-
setLoading(false);
51-
}
52-
}
53-
54-
loadWallets();
55-
}, []);
45+
const { data: wallets, isLoading: loading } = useQuery({
46+
queryKey: ["allWalletsList"],
47+
queryFn: async () => {
48+
const allWallets = await getAllWalletsList();
49+
return allWallets
50+
.filter((w) => !(w.id in specialWallets))
51+
.map((w) => ({
52+
id: w.id,
53+
name: w.name,
54+
}));
55+
},
56+
staleTime: 1000 * 60 * 5, // 5 minutes
57+
});
5658

5759
const filteredWallets = useMemo(() => {
58-
if (!searchQuery) return wallets;
59-
60+
if (!searchQuery) return wallets || [];
61+
if (!wallets) return [];
62+
63+
setCurrentPage(1);
6064
const query = searchQuery.toLowerCase();
6165
return wallets.filter(
6266
(wallet) =>
6367
wallet.name.toLowerCase().includes(query) ||
64-
wallet.id.toLowerCase().includes(query)
68+
wallet.id.toLowerCase().includes(query),
6569
);
6670
}, [wallets, searchQuery]);
6771

@@ -70,11 +74,6 @@ export function AllSupportedWallets() {
7074
const endIndex = startIndex + ITEMS_PER_PAGE;
7175
const currentWallets = filteredWallets.slice(startIndex, endIndex);
7276

73-
// Reset to first page when search changes
74-
useEffect(() => {
75-
setCurrentPage(1);
76-
}, [searchQuery]);
77-
7877
const handlePreviousPage = () => {
7978
setCurrentPage((prev) => Math.max(prev - 1, 1));
8079
};
@@ -99,7 +98,7 @@ export function AllSupportedWallets() {
9998
<div className="space-y-6">
10099
{/* Search Input */}
101100
<div className="relative">
102-
<SearchIcon className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
101+
<SearchIcon className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
103102
<Input
104103
type="text"
105104
placeholder="Search wallets by name or ID..."
@@ -111,9 +110,9 @@ export function AllSupportedWallets() {
111110

112111
{/* Results count */}
113112
<div className="text-sm text-muted-foreground">
114-
{filteredWallets.length === wallets.length
113+
{filteredWallets.length === wallets?.length
115114
? `Showing ${filteredWallets.length} wallets`
116-
: `Found ${filteredWallets.length} of ${wallets.length} wallets`}
115+
: `Found ${filteredWallets.length} of ${wallets?.length} wallets`}
117116
</div>
118117

119118
{/* Table */}
@@ -126,8 +125,13 @@ export function AllSupportedWallets() {
126125

127126
{currentWallets.length === 0 ? (
128127
<Tr>
129-
<Td colSpan={2} className="text-center text-muted-foreground py-8">
130-
{searchQuery ? "No wallets found matching your search." : "No wallets available."}
128+
<Td
129+
colSpan={2}
130+
className="text-center text-muted-foreground py-8"
131+
>
132+
{searchQuery
133+
? "No wallets found matching your search."
134+
: "No wallets available."}
131135
</Td>
132136
</Tr>
133137
) : (
@@ -155,30 +159,32 @@ export function AllSupportedWallets() {
155159
{totalPages > 1 && (
156160
<div className="flex items-center justify-between">
157161
<div className="text-sm text-muted-foreground">
158-
Page {currentPage} of {totalPages}
162+
Page {currentPage} of {totalPages}
159163
{filteredWallets.length > 0 && (
160164
<span className="ml-2">
161-
(showing {startIndex + 1}-{Math.min(endIndex, filteredWallets.length)} of {filteredWallets.length})
165+
(showing {startIndex + 1}-
166+
{Math.min(endIndex, filteredWallets.length)} of{" "}
167+
{filteredWallets.length})
162168
</span>
163169
)}
164170
</div>
165-
171+
166172
<div className="flex items-center space-x-2">
167173
<Button
168174
variant="outline"
169175
size="sm"
170176
onClick={handlePreviousPage}
171177
disabled={currentPage === 1}
172178
>
173-
<ChevronLeftIcon className="h-4 w-4" />
179+
<ChevronLeftIcon className="size-4" />
174180
Previous
175181
</Button>
176182

177183
{/* Page numbers */}
178184
<div className="flex items-center space-x-1">
179185
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
180-
let pageNumber;
181-
186+
let pageNumber: number;
187+
182188
if (totalPages <= 5) {
183189
pageNumber = i + 1;
184190
} else if (currentPage <= 3) {
@@ -210,7 +216,7 @@ export function AllSupportedWallets() {
210216
disabled={currentPage === totalPages}
211217
>
212218
Next
213-
<ChevronRightIcon className="h-4 w-4" />
219+
<ChevronRightIcon className="size-4" />
214220
</Button>
215221
</div>
216222
</div>
@@ -219,8 +225,19 @@ export function AllSupportedWallets() {
219225
);
220226
}
221227

222-
async function WalletImage(props: { id: WalletId }) {
223-
const img = await getWalletInfo(props.id, true);
228+
function WalletImage(props: { id: WalletId }) {
229+
const { data: img } = useQuery({
230+
queryKey: ["wallet-image", props.id],
231+
queryFn: () => getWalletInfo(props.id, true),
232+
staleTime: 1000 * 60 * 60 * 24, // 24 hours
233+
});
234+
235+
if (!img) {
236+
return (
237+
<div className="rounded-lg bg-muted" style={{ width: 44, height: 44 }} />
238+
);
239+
}
240+
224241
return (
225242
<Image alt="" className="rounded-lg" height={44} src={img} width={44} />
226243
);

0 commit comments

Comments
 (0)