forked from Nova-reward/Nova-Rewards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBalanceDisplay.js
More file actions
82 lines (74 loc) · 2.58 KB
/
Copy pathBalanceDisplay.js
File metadata and controls
82 lines (74 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use client';
import { useEffect } from 'react';
import { useWalletStore } from '../store/walletStore';
import { AlertCircle, Loader2 } from 'lucide-react';
import { formatTokenAmount } from '../lib/formatting';
/**
* BalanceDisplay — Shows the authenticated user's live NOVA token balance
*
* States:
* - Loading: Shows skeleton while fetching from /api/wallet/balance
* - Error: Shows — with tooltip explaining the fetch failure
* - Success: Shows formatted balance with 7 decimal places
*
* Automatically fetches balance on mount and can be manually refreshed.
* Updates after successful transactions via parent component.
*/
export default function BalanceDisplay() {
const {
publicKey,
balance,
balanceLoading,
balanceError,
fetchBalanceFromAPI,
} = useWalletStore();
// Fetch balance when wallet is connected
useEffect(() => {
if (publicKey) {
fetchBalanceFromAPI();
}
}, [publicKey, fetchBalanceFromAPI]);
// Not connected
if (!publicKey) {
return null;
}
// Loading state - show skeleton
if (balanceLoading) {
return (
<div className="flex flex-col leading-none gap-1">
<div className="h-3 w-16 bg-gray-200 dark:bg-brand-border rounded animate-pulse" />
<div className="h-3 w-20 bg-gray-200 dark:bg-brand-border rounded animate-pulse" />
</div>
);
}
// Error state - show — with tooltip
if (balanceError) {
return (
<div className="flex flex-col leading-none gap-1 group relative">
<span className="text-xs font-mono text-neutral-500 dark:text-neutral-400">
—
</span>
<span className="text-xs font-semibold text-red-600 dark:text-red-400">
Error
</span>
{/* Tooltip */}
<div className="absolute bottom-full left-0 mb-2 hidden group-hover:block bg-gray-900 dark:bg-gray-800 text-white text-xs rounded px-2 py-1 whitespace-nowrap z-50">
{balanceError}
<div className="absolute top-full left-2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-gray-900 dark:border-t-gray-800" />
</div>
</div>
);
}
// Success state - show formatted balance with 7 decimal places
const formattedBalance = formatTokenAmount(balance);
return (
<div className="flex flex-col leading-none gap-1">
<span className="text-xs font-mono text-neutral-500 dark:text-neutral-400">
Balance
</span>
<span className="text-xs font-semibold text-primary-600 dark:text-primary-400">
{formattedBalance} NOVA
</span>
</div>
);
}