From 978ee9266710d401715af2012e3e80bc73be2200 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Thu, 15 Jan 2026 12:17:48 +0800 Subject: [PATCH] misc: ui badges --- .../components/market-header.tsx | 21 +++++- .../components/market-id-actions-popover.tsx | 64 ------------------- .../markets/components/market-id-badge.tsx | 51 ++++++++++++--- 3 files changed, 63 insertions(+), 73 deletions(-) delete mode 100644 src/features/markets/components/market-id-actions-popover.tsx diff --git a/src/features/market-detail/components/market-header.tsx b/src/features/market-detail/components/market-header.tsx index bf2e6239..215d6335 100644 --- a/src/features/market-detail/components/market-header.tsx +++ b/src/features/market-detail/components/market-header.tsx @@ -10,6 +10,7 @@ import { IoWarningOutline, IoEllipsisVertical } from 'react-icons/io5'; import { MdError } from 'react-icons/md'; import { BsArrowUpCircle, BsArrowDownLeftCircle } from 'react-icons/bs'; import { FiExternalLink } from 'react-icons/fi'; +import { LuCopy } from 'react-icons/lu'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@/components/ui/dropdown-menu'; import { TokenIcon } from '@/components/shared/token-icon'; @@ -20,6 +21,7 @@ import { CampaignBadge } from '@/features/market-detail/components/campaign-badg import { PositionPill } from '@/features/market-detail/components/position-pill'; import { OracleTypeInfo } from '@/features/markets/components/oracle/MarketOracle/OracleTypeInfo'; import { useRateLabel } from '@/hooks/useRateLabel'; +import { useStyledToast } from '@/hooks/useStyledToast'; import { useAppSettings } from '@/stores/useAppSettings'; import { convertApyToApr } from '@/utils/rateMath'; import { getIRMTitle } from '@/utils/morpho'; @@ -134,8 +136,18 @@ export function MarketHeader({ const [isExpanded, setIsExpanded] = useState(false); const { short: rateLabel } = useRateLabel(); const { isAprDisplay } = useAppSettings(); + const toast = useStyledToast(); const networkImg = getNetworkImg(network); + const handleCopyMarketId = async () => { + try { + await navigator.clipboard.writeText(marketId); + toast.success('Market ID copied', `${marketId.slice(0, 10)}...${marketId.slice(-6)}`); + } catch { + // Clipboard API not available + } + }; + const formatRate = (rate: number) => { const displayRate = isAprDisplay ? convertApyToApr(rate) : rate; return `${(displayRate * 100).toFixed(2)}%`; @@ -236,8 +248,15 @@ export function MarketHeader({
-
+
{market.loanAsset.symbol}/{market.collateralAsset.symbol} +
{networkImg && ( diff --git a/src/features/markets/components/market-id-actions-popover.tsx b/src/features/markets/components/market-id-actions-popover.tsx deleted file mode 100644 index 96656c78..00000000 --- a/src/features/markets/components/market-id-actions-popover.tsx +++ /dev/null @@ -1,64 +0,0 @@ -'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 f507f8cb..30f019f8 100644 --- a/src/features/markets/components/market-id-badge.tsx +++ b/src/features/markets/components/market-id-badge.tsx @@ -1,8 +1,11 @@ 'use client'; import Image from 'next/image'; +import Link from 'next/link'; +import { LuCopy } from 'react-icons/lu'; +import { Tooltip } from '@/components/ui/tooltip'; +import { useStyledToast } from '@/hooks/useStyledToast'; import { getNetworkImg } from '@/utils/networks'; -import { MarketIdActionsPopover } from './market-id-actions-popover'; type MarketIdBadgeProps = { marketId: string; @@ -12,11 +15,19 @@ type MarketIdBadgeProps = { }; export function MarketIdBadge({ marketId, chainId, showNetworkIcon = false, showLink = true }: MarketIdBadgeProps) { + const toast = useStyledToast(); const displayId = marketId.slice(2, 8); const chainImg = getNetworkImg(chainId); + const handleCopy = async (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + await navigator.clipboard.writeText(marketId); + toast.success('Market ID copied', `${marketId.slice(0, 10)}...${marketId.slice(-6)}`); + }; + const badge = ( -
+
{showNetworkIcon && chainImg && ( )} - {displayId} + + {displayId} +
); if (showLink) { + const tooltipContent = ( +
+
+

Market ID

+ {`${marketId.slice(0, 10)}...`} +
+ +
+ ); + return ( - - {badge} - + e.stopPropagation()} + > + {badge} + + ); }