Skip to content

Commit 91d83fe

Browse files
authored
Merge pull request #55 from Trovic1/fix/balancelist-accountcard-walletscreen
fix(ux): BalanceList disconnected state, AccountCard badge gating, WalletScreen InfoCell tooltip+copy
2 parents c889ead + 7f7a579 commit 91d83fe

4 files changed

Lines changed: 63 additions & 14 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
node-version: [18.x, 20.x, 22.x]
14+
node-version: [20.x, 22.x]
1515

1616
steps:
1717
- uses: actions/checkout@v4

src/components/AccountCard.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ export function AccountCard() {
1717
Stellar account details
1818
</p>
1919
</div>
20-
<Badge variant="success" dot>
21-
Active
22-
</Badge>
20+
{isLoadingAccount ? (
21+
<Badge variant="default">Loading</Badge>
22+
) : (
23+
account && (
24+
<Badge variant="success" dot>
25+
Active
26+
</Badge>
27+
)
28+
)}
2329
</div>
2430
<div className="px-5 py-5">
2531
{isLoadingAccount ? (

src/components/BalanceList.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ function AssetRow({ b }: { b: Balance }) {
2020

2121
export function BalanceList() {
2222
const { balances, isLoadingAccount, isConnected } = useSorokit();
23-
if (!isConnected) return null;
2423

2524
return (
2625
<div className="rounded-xl border border-line bg-surface overflow-hidden">
@@ -29,12 +28,16 @@ export function BalanceList() {
2928
<h3 className="text-[14px] font-semibold text-ink">Assets</h3>
3029
<p className="text-[12px] text-ink-3 mt-0.5">Token balances</p>
3130
</div>
32-
{!isLoadingAccount && (
31+
{isConnected && !isLoadingAccount && (
3332
<Badge variant="default">{balances.length} assets</Badge>
3433
)}
3534
</div>
3635

37-
{isLoadingAccount ? (
36+
{!isConnected ? (
37+
<p className="text-[13px] text-ink-3 text-center py-10">
38+
Connect your wallet to view assets
39+
</p>
40+
) : isLoadingAccount ? (
3841
<div className="px-5 py-5 flex flex-col gap-4">
3942
{[1, 2, 3].map((i) => (
4043
<SkeletonRow key={i} />

src/screens/WalletScreen.tsx

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { useState } from "react";
12
import { useSorokit } from "@/context/useSorokit";
23
import { AccountCard } from "@/components/AccountCard";
34
import { Button } from "@/components/ui/Button";
45
import { Badge } from "@/components/ui/Badge";
5-
import { truncateAddress } from "@/lib/utils";
6+
import { cn, truncateAddress } from "@/lib/utils";
7+
import { HugeiconsIcon } from "@hugeicons/react";
8+
import { Copy01Icon, Tick01Icon } from "@hugeicons/core-free-icons";
69

710
export function WalletScreen() {
811
const { address, isConnected, disconnectWallet, network } = useSorokit();
@@ -41,7 +44,7 @@ export function WalletScreen() {
4144
{network && (
4245
<div className="grid grid-cols-1 sm:grid-cols-2 divide-y sm:divide-y-0 sm:divide-x divide-line">
4346
<InfoCell label="Network" value={network.name} />
44-
<InfoCell label="RPC Endpoint" value={network.rpcUrl} mono />
47+
<InfoCell label="RPC Endpoint" value={network.rpcUrl} mono copyable />
4548
</div>
4649
)}
4750
</div>
@@ -55,21 +58,58 @@ function InfoCell({
5558
label,
5659
value,
5760
mono,
61+
copyable,
5862
}: {
5963
label: string;
6064
value: string;
6165
mono?: boolean;
66+
copyable?: boolean;
6267
}) {
68+
const [copied, setCopied] = useState(false);
69+
70+
async function copy() {
71+
try {
72+
await navigator.clipboard.writeText(value);
73+
setCopied(true);
74+
setTimeout(() => setCopied(false), 2000);
75+
} catch {
76+
/* fallback */
77+
}
78+
}
79+
6380
return (
6481
<div className="px-6 py-4 flex flex-col gap-1.5">
6582
<span className="text-[10px] font-semibold uppercase tracking-[0.1em] text-ink-4">
6683
{label}
6784
</span>
68-
<span
69-
className={`text-[13px] text-ink-2 break-all ${mono ? "font-mono text-[12px]" : ""}`}
70-
>
71-
{value}
72-
</span>
85+
<div className="flex items-center gap-2 group">
86+
<span
87+
title={value}
88+
className={`text-[13px] text-ink-2 break-all ${mono ? "font-mono text-[12px]" : ""}`}
89+
>
90+
{value}
91+
</span>
92+
{copyable && (
93+
<button
94+
onClick={copy}
95+
aria-label={copied ? "Copied" : "Copy value"}
96+
className={cn(
97+
"shrink-0 p-1 rounded-md transition-all",
98+
copied
99+
? "text-green bg-[rgba(34,197,94,0.1)]"
100+
: "text-ink-3 hover:text-ink-2 hover:bg-surface-2 opacity-50 hover:opacity-100",
101+
)}
102+
title={copied ? "Copied!" : "Copy value"}
103+
>
104+
<HugeiconsIcon
105+
icon={copied ? Tick01Icon : Copy01Icon}
106+
size={12}
107+
color="currentColor"
108+
strokeWidth={2}
109+
/>
110+
</button>
111+
)}
112+
</div>
73113
</div>
74114
);
75115
}

0 commit comments

Comments
 (0)