refactor(wallet): extract WalletConnectionStatus component

- Create reusable WalletConnectionStatus component for connection indicator
- Remove rounded borders from indicator (now square)
- Export getConnectionStatusColor helper for custom usage
- Use component in both user-menu and WalletViewer
- Supports size (sm/md), showLabel, and className props

https://claude.ai/code/session_01CnJgjFMvZHZWs2ujAiWAiQ
This commit is contained in:
Claude
2026-01-29 17:00:59 +00:00
parent cc20142cc3
commit b80630adf9
3 changed files with 74 additions and 38 deletions

View File

@@ -0,0 +1,65 @@
/**
* WalletConnectionStatus Component
*
* Displays a visual indicator for wallet connection status.
* Shows different colors and animations based on status:
* - connected: green
* - connecting: yellow (pulsing)
* - error: red
* - disconnected: gray
*/
import type { NWCConnectionStatus } from "@/services/nwc";
interface WalletConnectionStatusProps {
status: NWCConnectionStatus;
/** Size of the indicator */
size?: "sm" | "md";
/** Whether to show the status label */
showLabel?: boolean;
/** Additional class names */
className?: string;
}
const sizeClasses = {
sm: "size-1.5",
md: "size-2",
};
/**
* Get the color class for a connection status
*/
export function getConnectionStatusColor(status: NWCConnectionStatus): string {
switch (status) {
case "connected":
return "bg-green-500";
case "connecting":
return "bg-yellow-500 animate-pulse";
case "error":
return "bg-red-500";
default:
return "bg-gray-500";
}
}
export function WalletConnectionStatus({
status,
size = "sm",
showLabel = false,
className = "",
}: WalletConnectionStatusProps) {
const colorClass = getConnectionStatusColor(status);
if (!showLabel) {
return (
<span className={`${sizeClasses[size]} ${colorClass} ${className}`} />
);
}
return (
<div className={`flex items-center gap-1.5 ${className}`}>
<span className={`${sizeClasses[size]} ${colorClass}`} />
<span className="text-sm font-medium capitalize">{status}</span>
</div>
);
}

View File

@@ -62,6 +62,7 @@ import { KindRenderer } from "./nostr/kinds";
import { RichText } from "./nostr/RichText";
import { UserName } from "./nostr/UserName";
import { CodeCopyButton } from "./CodeCopyButton";
import { WalletConnectionStatus } from "./WalletConnectionStatus";
import type { Transaction } from "@/types/wallet";
interface InvoiceDetails {
@@ -873,17 +874,7 @@ export default function WalletViewer() {
</span>
<Tooltip>
<TooltipTrigger asChild>
<div
className={`size-1.5 rounded-full ${
connectionStatus === "connected"
? "bg-green-500"
: connectionStatus === "connecting"
? "bg-yellow-500 animate-pulse"
: connectionStatus === "error"
? "bg-red-500"
: "bg-gray-500"
}`}
/>
<WalletConnectionStatus status={connectionStatus} size="sm" />
</TooltipTrigger>
<TooltipContent>
{connectionStatus === "connected" && "Connected"}

View File

@@ -10,6 +10,7 @@ import {
LogOut,
Settings,
} from "lucide-react";
import { WalletConnectionStatus } from "@/components/WalletConnectionStatus";
import accounts from "@/services/accounts";
import { useProfile } from "@/hooks/useProfile";
import { use$ } from "applesauce-react/hooks";
@@ -239,22 +240,11 @@ export default function UserMenu() {
{/* Connection Status */}
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">Status:</span>
<div className="flex items-center gap-2">
<span
className={`size-2 rounded-full ${
connectionStatus === "connected"
? "bg-green-500"
: connectionStatus === "connecting"
? "bg-yellow-500 animate-pulse"
: connectionStatus === "error"
? "bg-red-500"
: "bg-gray-500"
}`}
/>
<span className="text-sm font-medium capitalize">
{connectionStatus}
</span>
</div>
<WalletConnectionStatus
status={connectionStatus}
size="md"
showLabel
/>
</div>
{/* Lightning Address */}
@@ -378,17 +368,7 @@ export default function UserMenu() {
</span>
)}
</div>
<span
className={`size-1.5 rounded-full ${
connectionStatus === "connected"
? "bg-green-500"
: connectionStatus === "connecting"
? "bg-yellow-500 animate-pulse"
: connectionStatus === "error"
? "bg-red-500"
: "bg-gray-500"
}`}
/>
<WalletConnectionStatus status={connectionStatus} size="sm" />
</DropdownMenuItem>
) : (
<DropdownMenuItem