mirror of
https://github.com/luxfhe/research-ocp-fhe.git
synced 2026-11-03 06:05:38 +00:00
205 lines
7.1 KiB
TypeScript
205 lines
7.1 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { ChevronsUpDown, Plus, Wallet, LogOut } from 'lucide-react';
|
|
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '@/components/ui/dropdown-menu';
|
|
import {
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
useSidebar,
|
|
} from '@/components/ui/sidebar';
|
|
import { PREDEFINED_WALLETS, getWalletIcon } from '@/lib/constants/wallets';
|
|
import { useRole } from '@/hooks/use-role';
|
|
import { useAccount, useConnect, useDisconnect } from 'wagmi';
|
|
import { useAppKit, useAppKitEvents } from '@reown/appkit/react';
|
|
|
|
export function WalletSwitcher() {
|
|
const { isMobile } = useSidebar();
|
|
const {
|
|
selectedWallet,
|
|
isOwnWallet,
|
|
switchToPredefinedWallet,
|
|
switchToOwnWallet,
|
|
} = useRole();
|
|
const { address: connectedAddress, isConnected } = useAccount();
|
|
const { disconnect } = useDisconnect();
|
|
const { open: openAppKitModal } = useAppKit();
|
|
|
|
const events = useAppKitEvents();
|
|
|
|
const {} = useConnect({
|
|
mutation: {
|
|
onSuccess: () => {
|
|
console.log('Wallet connected successfully');
|
|
},
|
|
},
|
|
});
|
|
|
|
// Determine the active wallet display
|
|
const getActiveWallet = () => {
|
|
if (isOwnWallet && isConnected && connectedAddress) {
|
|
return {
|
|
name: 'Your Wallet',
|
|
company: `${connectedAddress.slice(0, 6)}...${connectedAddress.slice(-4)}`,
|
|
icon: Wallet,
|
|
};
|
|
}
|
|
|
|
if (selectedWallet) {
|
|
const IconComponent = getWalletIcon(selectedWallet.icon);
|
|
return {
|
|
name: selectedWallet.name,
|
|
company: selectedWallet.company,
|
|
icon: IconComponent,
|
|
};
|
|
}
|
|
|
|
// Default to first predefined wallet if nothing is selected
|
|
const defaultWallet = PREDEFINED_WALLETS[0];
|
|
const IconComponent = getWalletIcon(defaultWallet.icon);
|
|
return {
|
|
name: defaultWallet.name,
|
|
company: defaultWallet.company,
|
|
icon: IconComponent,
|
|
};
|
|
};
|
|
|
|
const activeWallet = getActiveWallet();
|
|
|
|
const handleWalletSelect = (wallet: (typeof PREDEFINED_WALLETS)[0]) => {
|
|
switchToPredefinedWallet(wallet);
|
|
};
|
|
|
|
const handleConnectOwnWallet = () => {
|
|
if (isConnected) {
|
|
switchToOwnWallet();
|
|
} else {
|
|
openAppKitModal({ view: 'Connect', namespace: 'eip155' });
|
|
// Note: We'll need to handle the connection success in a useEffect
|
|
}
|
|
};
|
|
|
|
const handleDisconnectWallet = () => {
|
|
// Disconnect the wallet
|
|
console.log('Disconnecting wallet...');
|
|
disconnect();
|
|
// Switch back to the default predefined wallet (first one)
|
|
switchToPredefinedWallet(PREDEFINED_WALLETS[0]);
|
|
};
|
|
|
|
React.useEffect(() => {
|
|
// Listen for connection events from AppKit
|
|
// When user connects via "Connect your wallet", automatically switch to own wallet
|
|
if (events && events.data.event === 'CONNECT_SUCCESS') {
|
|
switchToOwnWallet();
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [events]);
|
|
|
|
return (
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<SidebarMenuButton
|
|
size="lg"
|
|
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
|
>
|
|
<div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
|
|
<activeWallet.icon className="size-4" />
|
|
</div>
|
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
|
<span className="truncate font-medium">
|
|
{activeWallet.name}
|
|
</span>
|
|
<span className="truncate text-xs">{activeWallet.company}</span>
|
|
</div>
|
|
<ChevronsUpDown className="ml-auto" />
|
|
</SidebarMenuButton>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent
|
|
className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
|
|
align="start"
|
|
side={isMobile ? 'bottom' : 'right'}
|
|
sideOffset={4}
|
|
>
|
|
<DropdownMenuLabel className="text-muted-foreground text-xs">
|
|
Wallets
|
|
</DropdownMenuLabel>
|
|
{PREDEFINED_WALLETS.map(wallet => {
|
|
const IconComponent = getWalletIcon(wallet.icon);
|
|
const isActive = selectedWallet?.id === wallet.id && !isOwnWallet;
|
|
return (
|
|
<DropdownMenuItem
|
|
key={wallet.id}
|
|
onClick={() => handleWalletSelect(wallet)}
|
|
className={`gap-2 p-2 ${isActive ? 'bg-accent text-accent-foreground' : ''}`}
|
|
>
|
|
<div
|
|
className={`flex size-6 items-center justify-center rounded-md border ${isActive ? 'border-accent-foreground/20 bg-accent' : ''}`}
|
|
>
|
|
<IconComponent className="size-3.5 shrink-0" />
|
|
</div>
|
|
<div className="flex flex-col flex-1">
|
|
<div className="flex items-center justify-between">
|
|
<span className="font-medium">{wallet.name}</span>
|
|
</div>
|
|
<span className="text-xs text-muted-foreground">
|
|
{wallet.company}
|
|
</span>
|
|
</div>
|
|
</DropdownMenuItem>
|
|
);
|
|
})}
|
|
<DropdownMenuSeparator />
|
|
{/* Connect/Use Your Wallet Option */}
|
|
<DropdownMenuItem
|
|
className={`gap-2 p-2 ${isOwnWallet && isConnected ? 'bg-accent text-accent-foreground' : ''}`}
|
|
onClick={handleConnectOwnWallet}
|
|
>
|
|
<div
|
|
className={`flex size-6 items-center justify-center rounded-md border bg-transparent ${isOwnWallet && isConnected ? 'border-accent-foreground/20 bg-accent' : ''}`}
|
|
>
|
|
{isConnected ? (
|
|
<Wallet className="size-4" />
|
|
) : (
|
|
<Plus className="size-4" />
|
|
)}
|
|
</div>
|
|
<div className="flex items-center justify-between flex-1">
|
|
<div
|
|
className={`font-medium ${isOwnWallet && isConnected ? '' : 'text-muted-foreground'}`}
|
|
>
|
|
{isConnected ? 'Use Your Wallet' : 'Connect Your Wallet'}
|
|
</div>
|
|
</div>
|
|
</DropdownMenuItem>
|
|
|
|
{/* Disconnect Option - only show when connected and using own wallet */}
|
|
{isConnected && isOwnWallet && (
|
|
<DropdownMenuItem
|
|
className="gap-2 p-2 text-destructive focus:text-destructive"
|
|
onClick={handleDisconnectWallet}
|
|
>
|
|
<div className="flex size-6 items-center justify-center rounded-md border bg-transparent">
|
|
<LogOut className="size-4" />
|
|
</div>
|
|
<div className="font-medium">Disconnect Wallet</div>
|
|
</DropdownMenuItem>
|
|
)}
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
);
|
|
}
|