import { useState } from "react"; import { cn } from "~/lib/utils"; import { TrendingUp, TrendingDown, CheckCircle, XCircle, AlertTriangle, RefreshCw, ExternalLink, Shield, Users, Droplet, BarChart3, MessageSquare, } from "lucide-react"; import { Button } from "@/routes/ui/button"; import { ChainIcon } from "../components/shared/ChainIcon"; export interface TokenAnalysisData { tokenAddress: string; tokenSymbol: string; tokenName: string; chain: string; timestamp: Date; contract: { verified: boolean; renounced: boolean; isProxy: boolean; sourceCode: boolean; }; holders: { count: number; top10Percent: number; distribution: { address: string; percent: number }[]; }; liquidity: { totalUSD: number; lpLocked: boolean; lpLockDuration?: number; liquidityMcapRatio: number; }; volume: { volume24h: number; trend: "increasing" | "decreasing" | "stable"; volumeLiquidityRatio: number; }; price: { current: number; ath: number; atl: number; change7d: number; change30d: number; volatility: number; }; social: { twitterMentions: number; telegramActivity: number; redditDiscussions: number; sentimentScore: number; // -1 to 1 sentiment: "positive" | "negative" | "neutral"; }; aiSummary: string; recommendation: "buy" | "hold" | "sell" | "avoid"; confidence: number; // 0-100 } export interface TokenAnalysisPanelProps { /** Token analysis data */ analysis: TokenAnalysisData; /** Callback when refresh is clicked */ onRefresh?: () => void; /** Callback when "View Full Report" is clicked */ onViewFullReport?: () => void; /** Whether data is loading */ isLoading?: boolean; /** Additional class names */ className?: string; } /** * TokenAnalysisPanel - Comprehensive token analysis display * * Features: * - AI-generated summary with recommendation * - Contract analysis (verified, renounced, proxy) * - Holder distribution analysis * - Liquidity analysis with LP lock status * - Volume trends and trading activity * - Price history and volatility * - Social sentiment analysis */ export function TokenAnalysisPanel({ analysis, onRefresh, onViewFullReport, isLoading = false, className, }: TokenAnalysisPanelProps) { const [isRefreshing, setIsRefreshing] = useState(false); const handleRefresh = async () => { setIsRefreshing(true); await onRefresh?.(); setTimeout(() => setIsRefreshing(false), 1000); }; const formatTimeAgo = (date: Date) => { const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000); if (seconds < 60) return `${seconds}s ago`; const minutes = Math.floor(seconds / 60); if (minutes < 60) return `${minutes}m ago`; return `${Math.floor(minutes / 60)}h ago`; }; const formatCurrency = (value: number) => { if (value >= 1000000) return `$${(value / 1000000).toFixed(2)}M`; if (value >= 1000) return `$${(value / 1000).toFixed(1)}K`; return `$${value.toFixed(0)}`; }; const getRecommendationColor = (rec: string) => { switch (rec) { case "buy": return "text-green-600 dark:text-green-400"; case "hold": return "text-yellow-600 dark:text-yellow-400"; case "sell": return "text-orange-600 dark:text-orange-400"; case "avoid": return "text-red-600 dark:text-red-400"; default: return "text-muted-foreground"; } }; const getSentimentEmoji = (sentiment: string) => { switch (sentiment) { case "positive": return "😊"; case "negative": return "😟"; case "neutral": return "😐"; default: return "🤔"; } }; return (
{/* Header */}

Token Analysis

{analysis.tokenSymbol} •

{/* Content */}
{/* AI Summary */}
🤖

AI Summary

{analysis.aiSummary}

{/* Recommendation */}
Recommendation: {analysis.recommendation}
Confidence: {analysis.confidence}%
{/* Contract Analysis */}

Contract

{analysis.contract.verified ? ( ) : ( )} Verified
{analysis.contract.renounced ? ( ) : ( )} Renounced
{!analysis.contract.isProxy ? ( ) : ( )} {analysis.contract.isProxy ? "Proxy" : "Direct"}
{analysis.contract.sourceCode ? ( ) : ( )} Source Code
{/* Holder Distribution */}

Holders

Total Holders {analysis.holders.count.toLocaleString()}
Top 10 Holdings 50 ? "text-red-600" : analysis.holders.top10Percent > 30 ? "text-yellow-600" : "text-green-600" )}> {analysis.holders.top10Percent}%
{/* Liquidity */}

Liquidity

Total Liquidity {formatCurrency(analysis.liquidity.totalUSD)}
LP Lock Status
{analysis.liquidity.lpLocked ? ( <> {analysis.liquidity.lpLockDuration ? `${analysis.liquidity.lpLockDuration}d` : "Locked"} ) : ( <> Unlocked )}
{/* Volume & Price */}

Volume 24h

{formatCurrency(analysis.volume.volume24h)} {analysis.volume.trend === "increasing" ? ( ) : analysis.volume.trend === "decreasing" ? ( ) : null}

Price

${analysis.price.current.toFixed(8)}
= 0 ? "text-green-600" : "text-red-600" )}> 7d: {analysis.price.change7d >= 0 ? "+" : ""}{analysis.price.change7d.toFixed(1)}% = 0 ? "text-green-600" : "text-red-600" )}> 30d: {analysis.price.change30d >= 0 ? "+" : ""}{analysis.price.change30d.toFixed(1)}%
{/* Social Sentiment */}

Social Sentiment

{getSentimentEmoji(analysis.social.sentiment)} {analysis.social.sentiment.charAt(0).toUpperCase() + analysis.social.sentiment.slice(1)} Score: {(analysis.social.sentimentScore * 100).toFixed(0)}
Twitter
{analysis.social.twitterMentions}
Telegram
{analysis.social.telegramActivity}
Reddit
{analysis.social.redditDiscussions}
{/* Last Updated */}
Last updated: {formatTimeAgo(analysis.timestamp)}
{/* Footer */}
); }