mirror of
https://github.com/logos-messaging/OpChan.git
synced 2026-01-03 13:23:08 +00:00
218 lines
7.7 KiB
TypeScript
218 lines
7.7 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { useAuth } from '@/contexts/useAuth';
|
|
import { useForum } from '@/contexts/useForum';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { LogOut, Terminal, Wifi, WifiOff, AlertTriangle, CheckCircle, Key, RefreshCw, CircleSlash } from 'lucide-react';
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
|
import { useToast } from '@/components/ui/use-toast';
|
|
import { useAppKitAccount, useDisconnect } from '@reown/appkit/react';
|
|
import { WalletWizard } from '@/components/ui/wallet-wizard';
|
|
|
|
const Header = () => {
|
|
const {
|
|
currentUser,
|
|
isAuthenticated,
|
|
verificationStatus,
|
|
verifyOwnership,
|
|
delegateKey,
|
|
isDelegationValid,
|
|
delegationTimeRemaining,
|
|
isWalletAvailable
|
|
} = useAuth();
|
|
const { isNetworkConnected, isRefreshing } = useForum();
|
|
const { toast } = useToast();
|
|
// Use AppKit hooks for multi-chain support
|
|
const bitcoinAccount = useAppKitAccount({ namespace: "bip122" });
|
|
const ethereumAccount = useAppKitAccount({ namespace: "eip155" });
|
|
const { disconnect } = useDisconnect();
|
|
|
|
// Determine which account is connected
|
|
const isBitcoinConnected = bitcoinAccount.isConnected;
|
|
const isEthereumConnected = ethereumAccount.isConnected;
|
|
const isConnected = isBitcoinConnected || isEthereumConnected;
|
|
const address = isConnected ? (isBitcoinConnected ? bitcoinAccount.address : ethereumAccount.address) : undefined;
|
|
|
|
const [walletWizardOpen, setWalletWizardOpen] = useState(false);
|
|
const [hasShownWizard, setHasShownWizard] = useState(false);
|
|
|
|
// Auto-open wizard when wallet connects for the first time
|
|
React.useEffect(() => {
|
|
if (isConnected && !hasShownWizard) {
|
|
setWalletWizardOpen(true);
|
|
setHasShownWizard(true);
|
|
}
|
|
}, [isConnected, hasShownWizard]);
|
|
|
|
const handleConnect = async () => {
|
|
setWalletWizardOpen(true);
|
|
};
|
|
|
|
const handleDisconnect = async () => {
|
|
await disconnect();
|
|
setHasShownWizard(false); // Reset so wizard can show again on next connection
|
|
toast({
|
|
title: "Wallet Disconnected",
|
|
description: "Your wallet has been disconnected successfully.",
|
|
});
|
|
};
|
|
|
|
|
|
|
|
const getAccountStatusText = () => {
|
|
switch (verificationStatus) {
|
|
case 'unverified':
|
|
return 'Setup Required';
|
|
case 'verifying':
|
|
return 'Verifying...';
|
|
case 'verified-none':
|
|
return 'Read-Only Access';
|
|
case 'verified-owner':
|
|
return isDelegationValid() ? 'Full Access' : 'Setup Key';
|
|
default:
|
|
return 'Setup Account';
|
|
}
|
|
};
|
|
|
|
const getAccountStatusIcon = () => {
|
|
switch (verificationStatus) {
|
|
case 'unverified':
|
|
return <AlertTriangle className="w-3 h-3" />;
|
|
case 'verifying':
|
|
return <RefreshCw className="w-3 h-3 animate-spin" />;
|
|
case 'verified-none':
|
|
return <CircleSlash className="w-3 h-3" />;
|
|
case 'verified-owner':
|
|
return isDelegationValid() ? <CheckCircle className="w-3 h-3" /> : <Key className="w-3 h-3" />;
|
|
default:
|
|
return <AlertTriangle className="w-3 h-3" />;
|
|
}
|
|
};
|
|
|
|
const getAccountStatusVariant = () => {
|
|
switch (verificationStatus) {
|
|
case 'unverified':
|
|
return 'destructive';
|
|
case 'verifying':
|
|
return 'outline';
|
|
case 'verified-none':
|
|
return 'secondary';
|
|
case 'verified-owner':
|
|
return isDelegationValid() ? 'default' : 'outline';
|
|
default:
|
|
return 'outline';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<header className="border-b border-cyber-muted bg-cyber-dark fixed top-0 left-0 right-0 z-50 h-16">
|
|
<div className="container mx-auto px-4 h-full flex justify-between items-center">
|
|
<div className="flex items-center gap-2">
|
|
<Terminal className="text-cyber-accent w-6 h-6" />
|
|
<Link to="/" className="text-xl font-bold text-glow text-cyber-accent">
|
|
OpChan
|
|
</Link>
|
|
|
|
</div>
|
|
|
|
<div className="flex gap-3 items-center">
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Badge
|
|
variant={isNetworkConnected ? "default" : "destructive"}
|
|
className="flex items-center gap-1 text-xs px-2 h-7 cursor-help"
|
|
>
|
|
{isNetworkConnected ? (
|
|
<>
|
|
<Wifi className="w-3 h-3" />
|
|
<span>WAKU: Connected</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<WifiOff className="w-3 h-3" />
|
|
<span>WAKU: Offline</span>
|
|
</>
|
|
)}
|
|
</Badge>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="text-sm">
|
|
<p>{isNetworkConnected ? "Waku network connection active." : "Waku network connection lost."}</p>
|
|
{isRefreshing && <p>Refreshing data...</p>}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
|
|
{!isConnected ? (
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={handleConnect}
|
|
className="text-xs px-2 h-7"
|
|
>
|
|
Connect Wallet
|
|
</Button>
|
|
) : (
|
|
<div className="flex gap-2 items-center">
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
variant={getAccountStatusVariant()}
|
|
size="sm"
|
|
onClick={() => setWalletWizardOpen(true)}
|
|
className="flex items-center gap-1 text-xs px-2 h-7"
|
|
>
|
|
{getAccountStatusIcon()}
|
|
<span>{getAccountStatusText()}</span>
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="max-w-[260px] text-sm">
|
|
<p className="font-semibold mb-1">Account Setup</p>
|
|
<p>Click to view and manage your wallet connection, verification status, and key delegation.</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<span className="hidden md:flex items-center text-xs text-muted-foreground cursor-default px-2 h-7">
|
|
{currentUser?.ensName || `${address?.slice(0, 5)}...${address?.slice(-4)}`}
|
|
</span>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="text-sm">
|
|
<p>{currentUser?.ensName ? `${currentUser.ensName} (${address})` : address}</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={handleDisconnect}
|
|
className="w-7 h-7"
|
|
>
|
|
<LogOut className="w-4 h-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="text-sm">Disconnect Wallet</TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<WalletWizard
|
|
open={walletWizardOpen}
|
|
onOpenChange={setWalletWizardOpen}
|
|
onComplete={() => {
|
|
toast({
|
|
title: "Setup Complete",
|
|
description: "You can now use all OpChan features!",
|
|
});
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Header;
|