diff --git a/src/components/shared/account-actions-popover.tsx b/src/components/shared/account-actions-popover.tsx
index e0120df6..3e7fe38c 100644
--- a/src/components/shared/account-actions-popover.tsx
+++ b/src/components/shared/account-actions-popover.tsx
@@ -1,8 +1,7 @@
'use client';
-import { useState, useCallback, type ReactNode } from 'react';
-import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover';
-import { motion, AnimatePresence } from 'framer-motion';
+import { useCallback, type ReactNode } from 'react';
+import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@/components/ui/dropdown-menu';
import { LuCopy, LuUser } from 'react-icons/lu';
import { SiEthereum } from 'react-icons/si';
import { useStyledToast } from '@/hooks/useStyledToast';
@@ -16,20 +15,18 @@ type AccountActionsPopoverProps = {
};
/**
- * Minimal popover showing account actions:
+ * Dropdown menu showing account actions:
* - Copy address
* - View account (positions page)
* - View on Etherscan
*/
export function AccountActionsPopover({ address, children }: AccountActionsPopoverProps) {
- const [isOpen, setIsOpen] = useState(false);
const toast = useStyledToast();
const handleCopy = useCallback(async () => {
try {
await navigator.clipboard.writeText(address);
toast.success('Address copied', `${address.slice(0, 6)}...${address.slice(-4)}`);
- setIsOpen(false);
} catch (error) {
console.error('Failed to copy address', error);
}
@@ -37,72 +34,38 @@ export function AccountActionsPopover({ address, children }: AccountActionsPopov
const handleViewAccount = useCallback(() => {
window.location.href = `/positions/${address}`;
- setIsOpen(false);
}, [address]);
const handleViewExplorer = useCallback(() => {
const explorerUrl = getExplorerURL(address, SupportedNetworks.Mainnet);
window.open(explorerUrl, '_blank', 'noopener,noreferrer');
- setIsOpen(false);
}, [address]);
return (
-
-
- {children}
-
-
-
- {isOpen && (
-
- {/* Copy Address */}
- void handleCopy()}
- className="flex items-center gap-3 px-4 py-2.5 text-sm text-secondary transition-colors hover:bg-hovered hover:text-primary"
- whileHover={{ x: 2 }}
- whileTap={{ scale: 0.98 }}
- >
-
- Copy Address
-
-
- {/* View Account */}
-
-
- View Account
-
-
- {/* View on Explorer */}
-
-
- View on Explorer
-
-
- )}
-
-
-
+
+
+ {children}
+
+
+ void handleCopy()}
+ startContent={}
+ >
+ Copy Address
+
+ }
+ >
+ View Account
+
+ }
+ >
+ View on Explorer
+
+
+
);
}
diff --git a/src/features/markets/components/market-id-actions-popover.tsx b/src/features/markets/components/market-id-actions-popover.tsx
new file mode 100644
index 00000000..96656c78
--- /dev/null
+++ b/src/features/markets/components/market-id-actions-popover.tsx
@@ -0,0 +1,64 @@
+'use client';
+
+import { useCallback, type ReactNode } from 'react';
+import { useRouter } from 'next/navigation';
+import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@/components/ui/dropdown-menu';
+import { LuCopy } from 'react-icons/lu';
+import { GoGraph } from 'react-icons/go';
+import { useStyledToast } from '@/hooks/useStyledToast';
+
+type MarketIdActionsPopoverProps = {
+ marketId: string;
+ chainId: number;
+ children: ReactNode;
+};
+
+/**
+ * Dropdown menu showing market ID actions:
+ * - Copy ID
+ * - View Market
+ */
+export function MarketIdActionsPopover({ marketId, chainId, children }: MarketIdActionsPopoverProps) {
+ const toast = useStyledToast();
+ const router = useRouter();
+
+ const handleCopy = useCallback(async () => {
+ try {
+ await navigator.clipboard.writeText(marketId);
+ toast.success('Market ID copied', `${marketId.slice(0, 10)}...${marketId.slice(-6)}`);
+ } catch (error) {
+ console.error('Failed to copy market ID', error);
+ }
+ }, [marketId, toast]);
+
+ const handleViewMarket = useCallback(() => {
+ router.push(`/market/${chainId}/${marketId}`);
+ }, [chainId, marketId, router]);
+
+ return (
+
e.stopPropagation()}
+ onKeyDown={(e) => e.stopPropagation()}
+ >
+
+
+ {children}
+
+
+ void handleCopy()}
+ startContent={}
+ >
+ Copy ID
+
+ }
+ >
+ View Market
+
+
+
+
+ );
+}
diff --git a/src/features/markets/components/market-id-badge.tsx b/src/features/markets/components/market-id-badge.tsx
index 657d0e75..f507f8cb 100644
--- a/src/features/markets/components/market-id-badge.tsx
+++ b/src/features/markets/components/market-id-badge.tsx
@@ -1,6 +1,8 @@
-import Link from 'next/link';
+'use client';
+
import Image from 'next/image';
import { getNetworkImg } from '@/utils/networks';
+import { MarketIdActionsPopover } from './market-id-actions-popover';
type MarketIdBadgeProps = {
marketId: string;
@@ -13,7 +15,7 @@ export function MarketIdBadge({ marketId, chainId, showNetworkIcon = false, show
const displayId = marketId.slice(2, 8);
const chainImg = getNetworkImg(chainId);
- return (
+ const badge = (
{showNetworkIcon && chainImg && (
)}
- {showLink ? (
-
- {displayId}
-
- ) : (
- {displayId}
- )}
+ {displayId}
);
+
+ if (showLink) {
+ return (
+
+ {badge}
+
+ );
+ }
+
+ return badge;
}