@@ -6,6 +6,8 @@ import { Button } from "@/components/ui/button";
66import { Checkbox , CheckboxWithLabel } from "@/components/ui/checkbox" ;
77import { FormItem } from "@/components/ui/form" ;
88import { Skeleton } from "@/components/ui/skeleton" ;
9+ import { ToolTipLabel } from "@/components/ui/tooltip" ;
10+ import { engineKeys } from "@3rdweb-sdk/react" ;
911import {
1012 type BackendWallet ,
1113 useEngineBackendWalletBalance ,
@@ -30,7 +32,7 @@ import {
3032 type UseDisclosureReturn ,
3133 useDisclosure ,
3234} from "@chakra-ui/react" ;
33- import { useQuery } from "@tanstack/react-query" ;
35+ import { useQuery , useQueryClient } from "@tanstack/react-query" ;
3436import { type ColumnDef , createColumnHelper } from "@tanstack/react-table" ;
3537import { ChainIcon } from "components/icons/ChainIcon" ;
3638import { TWTable } from "components/shared/TWTable" ;
@@ -40,18 +42,21 @@ import { EngineBackendWalletOptions } from "lib/engine";
4042import { useV5DashboardChain } from "lib/v5-adapter" ;
4143import {
4244 DownloadIcon ,
45+ ExternalLinkIcon ,
4346 PencilIcon ,
47+ RefreshCcwIcon ,
4448 TrashIcon ,
4549 TriangleAlertIcon ,
4650 UploadIcon ,
4751} from "lucide-react" ;
52+ import Link from "next/link" ;
4853import QRCode from "qrcode" ;
4954import { useMemo , useState } from "react" ;
5055import { useForm } from "react-hook-form" ;
5156import { toast } from "sonner" ;
5257import { getAddress } from "thirdweb" ;
5358import { shortenAddress } from "thirdweb/utils" ;
54- import { FormHelperText , FormLabel , LinkButton , Text } from "tw-components" ;
59+ import { FormHelperText , FormLabel , Text } from "tw-components" ;
5560import { prettyPrintCurrency } from "./utils" ;
5661
5762interface BackendWalletsTableProps {
@@ -83,41 +88,40 @@ const BackendWalletBalanceCell: React.FC<BackendWalletBalanceCellProps> = ({
8388 authToken,
8489 chainId,
8590} ) => {
86- const { data : backendWalletBalance } = useEngineBackendWalletBalance ( {
87- instanceUrl : instanceUrl ,
88- address,
89- authToken,
90- chainId,
91- } ) ;
91+ const { data : backendWalletBalance , isFetching } =
92+ useEngineBackendWalletBalance ( {
93+ instanceUrl : instanceUrl ,
94+ address,
95+ authToken,
96+ chainId,
97+ } ) ;
9298 const chain = useV5DashboardChain ( chainId ) ;
9399
94- if ( ! backendWalletBalance ) {
95- return < Skeleton className = "h-5 w-32 rounded-lg" /> ;
100+ if ( ! backendWalletBalance || isFetching ) {
101+ return < Skeleton className = "h-6 w-36 rounded-lg" /> ;
96102 }
97103
98104 const balanceDisplay = prettyPrintCurrency ( {
99105 amount : backendWalletBalance . displayValue ,
100106 symbol : backendWalletBalance . symbol || chain . nativeCurrency ?. symbol ,
101107 } ) ;
102108
103- const balanceComponent = (
104- < div className = "text-muted-foreground" > { balanceDisplay } </ div >
105- ) ;
109+ const balanceComponent = < span > { balanceDisplay } </ span > ;
106110
107111 const explorer = chain . blockExplorers ?. [ 0 ] ;
108112 if ( ! explorer ) {
109113 return balanceComponent ;
110114 }
111115
112116 return (
113- < LinkButton
114- variant = "ghost"
115- isExternal
116- size = "xs"
117+ < Link
118+ target = "_blank"
117119 href = { `${ explorer . url } /address/${ address } ` }
120+ className = "inline-flex items-center gap-2.5 rounded-lg px-2 py-1 text-muted-foreground hover:bg-muted hover:text-foreground"
118121 >
119122 { balanceComponent }
120- </ LinkButton >
123+ < ExternalLinkIcon className = "size-4" />
124+ </ Link >
121125 ) ;
122126} ;
123127
@@ -133,6 +137,7 @@ export const BackendWalletsTable: React.FC<BackendWalletsTableProps> = ({
133137 const receiveDisclosure = useDisclosure ( ) ;
134138 const sendDisclosure = useDisclosure ( ) ;
135139 const deleteDisclosure = useDisclosure ( ) ;
140+ const queryClient = useQueryClient ( ) ;
136141
137142 const columns = useMemo ( ( ) => {
138143 return [
@@ -160,7 +165,31 @@ export const BackendWalletsTable: React.FC<BackendWalletsTableProps> = ({
160165 } ,
161166 } ) ,
162167 columnHelper . accessor ( "address" , {
163- header : "Balance" ,
168+ header : ( ) => (
169+ < div className = "flex w-[180px] items-center gap-1.5" >
170+ Balance
171+ < ToolTipLabel
172+ label = "Refresh Balance"
173+ contentClassName = "capitalize font-normal tracking-normal leading-normal"
174+ >
175+ < Button
176+ className = "z-20 h-auto p-1.5 [&[data-pending='true']_svg]:animate-spin"
177+ variant = "ghost"
178+ size = "sm"
179+ onClick = { async ( e ) => {
180+ const buttonEl = e . currentTarget ;
181+ buttonEl . setAttribute ( "data-pending" , "true" ) ;
182+ await queryClient . invalidateQueries ( {
183+ queryKey : engineKeys . backendWalletBalanceAll ( ) ,
184+ } ) ;
185+ buttonEl . setAttribute ( "data-pending" , "false" ) ;
186+ } }
187+ >
188+ < RefreshCcwIcon className = "size-4" />
189+ </ Button >
190+ </ ToolTipLabel >
191+ </ div >
192+ ) ,
164193 cell : ( cell ) => {
165194 const address = cell . getValue ( ) ;
166195 return (
@@ -175,7 +204,7 @@ export const BackendWalletsTable: React.FC<BackendWalletsTableProps> = ({
175204 id : "balance" ,
176205 } ) ,
177206 ] ;
178- } , [ instanceUrl , authToken , chainId ] ) ;
207+ } , [ instanceUrl , authToken , chainId , queryClient ] ) ;
179208
180209 const [ selectedBackendWallet , setSelectedBackendWallet ] =
181210 useState < BackendWallet > ( ) ;
0 commit comments