"use client"; import { useState } from "react"; import { cn } from "@/lib/utils"; import { Star, Bell, ExternalLink, MoreHorizontal, ArrowUpDown, Trash2, Settings, } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Badge } from "@/components/ui/badge"; import { ChainIcon } from "./ChainIcon"; import { SafetyBadge } from "./SafetyBadge"; import type { WatchlistToken } from "@/lib/mock/cryptoMockData"; import { formatPrice, formatPercent, formatLargeNumber } from "@/lib/mock/cryptoMockData"; interface WatchlistTableProps { tokens: WatchlistToken[]; onTokenClick?: (token: WatchlistToken) => void; onRemoveToken?: (tokenId: string) => void; onConfigureAlerts?: (token: WatchlistToken) => void; className?: string; } type SortField = "symbol" | "price" | "priceChange24h" | "volume24h" | "marketCap" | "safetyScore"; type SortDirection = "asc" | "desc"; export function WatchlistTable({ tokens, onTokenClick, onRemoveToken, onConfigureAlerts, className, }: WatchlistTableProps) { const [sortField, setSortField] = useState("priceChange24h"); const [sortDirection, setSortDirection] = useState("desc"); const handleSort = (field: SortField) => { if (sortField === field) { setSortDirection(sortDirection === "asc" ? "desc" : "asc"); } else { setSortField(field); setSortDirection("desc"); } }; const sortedTokens = [...tokens].sort((a, b) => { const aVal = a[sortField]; const bVal = b[sortField]; if (typeof aVal === "string" && typeof bVal === "string") { return sortDirection === "asc" ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal); } return sortDirection === "asc" ? (aVal as number) - (bVal as number) : (bVal as number) - (aVal as number); }); const SortableHeader = ({ field, children }: { field: SortField; children: React.ReactNode }) => ( ); return ( Watchlist {tokens.length}
Token Price 24h Volume MCap Safety {sortedTokens.map((token) => ( onTokenClick?.(token)} >
{token.symbol} {token.hasAlerts && ( )}
{token.name}
{formatPrice(token.price)} 0 && "text-green-500", token.priceChange24h < 0 && "text-red-500" )}> {formatPercent(token.priceChange24h)} {formatLargeNumber(token.volume24h)} {formatLargeNumber(token.marketCap)} e.stopPropagation()}> { e.stopPropagation(); onConfigureAlerts?.(token); }}> Configure Alerts { e.stopPropagation(); window.open(`https://dexscreener.com/${token.chain}/${token.contractAddress}`, "_blank"); }}> View on DexScreener { e.stopPropagation(); onRemoveToken?.(token.id); }} > Remove
))}
); }