ln / components /connect-wallet-button.tsx
MoShow's picture
Upload 252 files
78d0e31 verified
"use client"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Wallet, Copy, ExternalLink, LogOut, Coins, AlertCircle } from "lucide-react"
import { useWallet } from "@/providers/wallet-provider"
import { NetworkSwitcher } from "./network-switcher"
import { toast } from "@/hooks/use-toast"
export function ConnectWalletButton() {
const { connected, address, balance, chainId, isConnecting, error, connectWallet, disconnect, requestFLBTokens } =
useWallet()
const [requesting, setRequesting] = useState(false)
const handleConnect = async () => {
try {
const success = await connectWallet()
if (success) {
toast({
title: "Wallet Connected",
description: "Successfully connected to your Celo wallet",
})
}
} catch (error) {
toast({
title: "Connection Failed",
description: "Failed to connect wallet. Please try again.",
variant: "destructive",
})
}
}
const handleDisconnect = () => {
disconnect()
toast({
title: "Wallet Disconnected",
description: "Your wallet has been disconnected",
})
}
const handleCopyAddress = () => {
if (address) {
navigator.clipboard.writeText(address)
toast({
title: "Address Copied",
description: "Wallet address copied to clipboard",
})
}
}
const handleRequestTokens = async () => {
setRequesting(true)
try {
await requestFLBTokens("100")
toast({
title: "Tokens Requested",
description: "FLB tokens have been requested. Please check your balance.",
})
} catch (error: any) {
toast({
title: "Request Failed",
description: error.message || "Failed to request FLB tokens. Please contact the team.",
variant: "destructive",
})
} finally {
setRequesting(false)
}
}
const openBlockExplorer = () => {
if (address) {
const explorerUrl =
chainId === 42220
? `https://celoscan.io/address/${address}`
: `https://alfajores.celoscan.io/address/${address}`
window.open(explorerUrl, "_blank")
}
}
const formatAddress = (addr: string) => {
return `${addr.slice(0, 6)}...${addr.slice(-4)}`
}
const formatBalance = (bal: string) => {
const num = Number.parseFloat(bal)
return num > 0 ? num.toFixed(4) : "0"
}
const isCeloNetwork = chainId === 42220 || chainId === 44787
if (!connected) {
return (
<div className="space-y-2">
<Button onClick={handleConnect} disabled={isConnecting} className="gap-2 w-full" size="lg">
<Wallet className="h-4 w-4" />
{isConnecting ? "Connecting..." : "Connect Wallet"}
</Button>
{error && (
<div className="text-sm text-red-400 bg-red-950/30 p-2 rounded border border-red-500/30 flex items-center gap-2">
<AlertCircle className="h-4 w-4 flex-shrink-0" />
<span>{error}</span>
</div>
)}
</div>
)
}
return (
<div className="flex items-center gap-2">
<NetworkSwitcher />
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="gap-2 bg-transparent">
<Wallet className="h-4 w-4" />
<div className="flex flex-col items-start">
<span className="text-sm font-medium">{address ? formatAddress(address) : "Connected"}</span>
<div className="flex gap-2 text-xs text-muted-foreground">
<span>{formatBalance(balance.celo)} CELO</span>
<span></span>
<span>{formatBalance(balance.flb)} FLB</span>
</div>
</div>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-64">
<div className="p-2">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium">Wallet Address</span>
<Button variant="ghost" size="sm" onClick={handleCopyAddress} className="h-6 w-6 p-0">
<Copy className="h-3 w-3" />
</Button>
</div>
<code className="text-xs bg-muted p-2 rounded block break-all">{address}</code>
</div>
<DropdownMenuSeparator />
<div className="p-2">
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-sm">CELO Balance:</span>
<Badge variant="outline">{formatBalance(balance.celo)} CELO</Badge>
</div>
<div className="flex justify-between">
<span className="text-sm">FLB Balance:</span>
<Badge variant="outline">{formatBalance(balance.flb)} FLB</Badge>
</div>
</div>
</div>
<DropdownMenuSeparator />
{isCeloNetwork && (
<DropdownMenuItem onClick={handleRequestTokens} disabled={requesting}>
<Coins className="h-4 w-4 mr-2" />
{requesting ? "Requesting..." : "Request Test FLB"}
</DropdownMenuItem>
)}
<DropdownMenuItem onClick={openBlockExplorer}>
<ExternalLink className="h-4 w-4 mr-2" />
View on Explorer
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleDisconnect} className="text-red-600">
<LogOut className="h-4 w-4 mr-2" />
Disconnect
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
)
}