Загрузка...

Argus: страница-витрина системы дизайна Axiom. Отображает типографику, палитру цветов и UI-элементы бренда.
# Argus
You are given a task to integrate an existing React component in the codebase
~~~/README.md
# Argus Component
A high-density crypto trading terminal featuring a quad-feed layout for maximum information density.
## Layout Structure
- **Left Panel (Pulse Feed)**: Focuses on on-chain signals.
- **Radar**: Real-time new token detections.
- **Positions**: Copy-trading signals and wallet tracking.
- **Right Panel (Live Feed)**: Focuses on social sentiment and news.
- **Alpha**: High-signal tweets from key influencers ("Whale Alerts").
- **Discussion**: General community discussion and sentiment.
## Features
- **4-Column Grid**: Optimizes screen real estate for desktop trading setups.
- **Real-time Simulation**: Feeds auto-update with mock data to simulate a live environment.
- **Visuals**: Dark mode aesthetic, glassmorphism, and color-coded signals (Emerald for buys, Rose for sells, Amber for alpha).
## Usage
```tsx
import { AxiomShowcase } from '@/sd-components/1514cf7d-5dee-4fc0-a7b0-e15487169e81';
export default function Page() {
return <AxiomShowcase />;
}
```
~~~
~~~/src/App.tsx
import React from 'react';
import { ~~~/README.md
Argus
~~~ } from './Component';
export default function App() {
return <AxiomShowcase />;
}
~~~
~~~/package.json
{
"name": "crypto-screener",
"description": "Dark minimal crypto screener UI",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"framer-motion": "^10.16.4",
"lucide-react": "^0.292.0",
"clsx": "^2.0.0",
"tailwind-merge": "^2.0.0"
}
}
~~~
~~~/STYLE_GUIDE.md
User wants to rename "Pulse Feed" to "Feed", and rename columns "Alpha" -> "WATCHED", "Discussion" -> "ALPHA". Also wants to add specific metrics (followers, reach, trust score) to tweets and remove interaction buttons. The "HOT" and "New" icons reference likely maps to the column header icons (Flame -> Settings, Zap -> Settings).
~~~
~~~/src/Component.tsx
import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Search, Filter, SlidersHorizontal, Zap, Layers, Copy, MoreHorizontal, MessageCircle, Repeat, Heart, Share, Flame, User, Activity, Settings, Users, BarChart2, Shield, ImageIcon, Bot, Eye, AlertTriangle, Fish, Globe, Users2, Crown, Medal, ShieldCheck, Twitter, MessageSquare, Sparkles, CheckCircle2 } from 'lucide-react';
// Types
interface Token {
id: string;
ticker: string;
address: string;
timeAgo: string;
isNew?: boolean;
marketCap: number;
volume: number;
fees: number;
transactions: number;
buyAmount: number;
status: 'migrated' | 'bonding';
// Social Signals
social: {
admin: {
handle: string;
followers: string;
score: number;
lists: number;
ran: number; // R3
};
community: {
moderatorCount: number; // M4
moderators: Array<{ name: string; followers: string; score: number; lists: number }>;
twitterGroupMembers: number; // @gr
communityMembers: number; // @com
};
tweets: {
total: number;
bot: number;
reach: string;
unique: number;
filtered: number;
};
sentiment: {
fud: number;
team: number;
shrimp: number;
fish: number;
dolphin: number;
whale: number;
};
};
}
interface Tweet {
id: string;
user: {
name: string;
handle: string;
avatar?: string;
verified?: boolean;
avatarGradient: string;
followers: string;
reach: string;
trustScore: number;
};
content: string;
timestamp: string;
mediaUrl?: string;
highlight?: boolean;
type: 'alpha' | 'discussion';
ticker?: string;
priceChange?: number;
}
// Mock Data Generators
const TICKERS = ['SOL', 'BONK', 'WIF', 'JUP', 'PYTH', 'RAY', 'ORCA', 'HNT'];
const USERS = [
{ name: 'Solana Legend', handle: '@SolanaLegend', verified: true, followers: '142k', reach: '85k', trustScore: 92 },
{ name: 'Crypto Whale', handle: '@WhaleAlert', verified: true, followers: '2.4M', reach: '1.2M', trustScore: 98 },
{ name: 'DeFi Ignas', handle: '@DefiIgnas', verified: false, followers: '89k', reach: '45k', trustScore: 85 },
{ name: 'Vitalik (Parody)', handle: '@VitalikButerin', verified: true, followers: '500k', reach: '200k', trustScore: 75 },
{ name: 'Axiom Intern', handle: '@AxiomIntern', verified: false, followers: '12k', reach: '5k', trustScore: 65 },
];
const CONTENT_TEMPLATES = [
(ticker: string) => `Just loaded up on more $${ticker}. The chart looks absolutely primed for a breakout. 🚀`,
(ticker: string) => `🚨 $${ticker} BREAKING OUT! Volume is surging on the 15m timeframe. Don't sleep on this.`,
(ticker: string) => `Unpopular opinion: $${ticker} is undervalued relative to the rest of the ecosystem. Here's why I'm accumulating...`,
(ticker: string) => `Huge whale movement detected on $${ticker}. 500k just moved to a fresh wallet. Something is brewing. 🐋`,
(ticker: string) => `Markets are choppy but $${ticker} showing incredible relative strength today.`,
(ticker: string) => `Just published my deep dive on $${ticker}. TLDR: Bullish.`,
(ticker: string) => `The dev team for $${ticker} just dropped a massive update in the discord. This changes everything.`,
(ticker: string) => `If you missed the $SOL train, $${ticker} is your second chance. Chart looks identical to early 2021.`,
(ticker: string) => `Liquidity for $${ticker} is deepening. Smart money is quietly positioning before the next leg up.`,
(ticker: string) => `Hearing rumors that $${ticker} is about to be listed on a tier 1 exchange. NFA but I'm packing my bags.`,
(ticker: string) => `The R/R on this $${ticker} setup is insane. Risking 2% to make 20%. Easy trade.`,
(ticker: string) => `Why is nobody talking about $${ticker}? The on-chain metrics are screaming buy.`,
(ticker: string) => `Just saw a wallet with 80% winrate buy $${ticker}. Copy trading this one.`,
(ticker: string) => `$${ticker} creates a perfect inverse head and shoulders on the 4H. Sending it higher. 📈`,
(ticker: string) => `Community sentiment for $${ticker} is at an all time high. The vibes are immaculate.`,
(ticker: string) => `Accumulation phase for $${ticker} is over. Markup phase begins now. buckle up.`,
(ticker: string) => `I've been in crypto for 5 years and I haven't seen a chart this clean since 2020. $${ticker} to the moon.`,
(ticker: string) => `Selling my car to buy more $${ticker}. (Joke... unless?)`,
(ticker: string) => `The FDV of $${ticker} is a joke compared to its competitors. easy 10x from here.`,
(ticker: string) => `Golden cross on the daily for $${ticker}. Algorithm bots are about to go crazy.`,
];
const CHART_IMAGES = [
'https://pquxfbbxflqvtidtlrhl.supabase.co/storage/v1/object/public/hmac-uploads/brand/a031228b-9265-4751-8dda-0c20d3151ef8/assets/6f36892c-b692-48c5-abcf-ef3a212c4d33.webp',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701479372-ade6e2aa/2007085425169502284_0.jpg',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701477566-b8692359/2006890906943975764_0.jpg',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701481455-7daefae8/2007261225047208370_0.jpg',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701480067-55e1f8c5/2007100699113554114_0.jpg',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701481240-cfc307a2/2007258218318499892_0.jpg',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701478707-de7bf92c/2007051403366469739_0.jpg',
'https://vgbujcuwptvheqijyjbe.supabase.co/storage/v1/object/public/hmac-uploads/uploads/184da2be-6046-4d2c-87ae-69ba24ea32e0/1767701481672-613776be/2007265349578969363_0.jpg',
];
const generateAddress = () => `${Math.random().toString(36).substring(2, 6)}...${Math.random().toString(36).substring(2, 6)}`;
const generateToken = (id: string): Token => ({
id,
ticker: TICKERS[Math.floor(Math.random() * TICKERS.length)],
address: generateAddress(),
timeAgo: `${Math.floor(Math.random() * 59) + 1}s`,
isNew: true,
status: Math.random() > 0.5 ? 'migrated' : 'bonding',
marketCap: Math.random() * 50000 + 5000,
volume: Math.random() * 100000 + 10000,
fees: Math.random() * 2 + 0.1,
transactions: Math.floor(Math.random() * 500) + 50,
buyAmount: [0.01, 0.05, 0.1, 0.5][Math.floor(Math.random() * 4)],
social: {
admin: {
handle: `@admin${Math.floor(Math.random() * 999)}`,
followers: `${(Math.random() * 5 + 0.5).toFixed(1)}k`,
score: Math.floor(Math.random() * 50) + 20,
lists: Math.floor(Math.random() * 100) + 10,
ran: Math.floor(Math.random() * 10) + 1,
},
community: {
moderatorCount: Math.floor(Math.random() * 5) + 2,
moderators: Array.from({ length: 4 }).map((_, i) => ({
name: `@mod${i}`,
followers: '1.2k',
score: 45,
lists: 12
})),
twitterGroupMembers: Math.floor(Math.random() * 500) + 50,
communityMembers: Math.floor(Math.random() * 200) + 20,
},
tweets: {
total: Math.floor(Math.random() * 300) + 100,
bot: Math.floor(Math.random() * 50) + 10,
reach: `${(Math.random() * 50 + 10).toFixed(0)}k`,
unique: Math.floor(Math.random() * 50) + 10,
filtered: Math.floor(Math.random() * 80) + 20,
},
sentiment: {
fud: Math.floor(Math.random() * 10),
team: Math.floor(Math.random() * 10) + 1,
shrimp: Math.floor(Math.random() * 20) + 5,
fish: Math.floor(Math.random() * 10) + 2,
dolphin: Math.floor(Math.random() * 5),
whale: Math.floor(Math.random() * 2),
}
}
});
const generateTweet = (id: string, type: 'alpha' | 'discussion'): Tweet => {
const user = USERS[Math.floor(Math.random() * USERS.length)];
const ticker = TICKERS[Math.floor(Math.random() * TICKERS.length)];
const template = CONTENT_TEMPLATES[Math.floor(Math.random() * CONTENT_TEMPLATES.length)];
const hasMedia = Math.random() > 0.5; // Increased chance of media
return {
id,
user: {
...user,
avatarGradient: `from-${['indigo', 'blue', 'purple', 'violet'][Math.floor(Math.random()*4)]}-500 to-${['pink', 'rose', 'fuchsia'][Math.floor(Math.random()*3)]}-500`,
},
content: template(ticker) + (Math.random() > 0.5 ? " This is not financial advice." : ""),
timestamp: '2m',
highlight: Math.random() > 0.8,
type,
ticker,
priceChange: (Math.random() * 10 - 3), // Random price change between -3% and +7%
mediaUrl: hasMedia ? CHART_IMAGES[Math.floor(Math.random() * CHART_IMAGES.length)] : undefined,
};
};
const LiveNumber = ({ value, prefix = "", colorClass = "text-slate-200" }: { value: number, prefix?: string, colorClass?: string }) => {
return (
<span className={`font-mono font-bold ${colorClass}`}>
{prefix}{value >= 1000 ? (value / 1000).toFixed(1) + 'K' : value.toFixed(0)}
</span>
);
};
export function AxiomShowcase() {
const [alphaTweets, setAlphaTweets] = useState<Tweet[]>([]);
const [discussionTweets, setDiscussionTweets] = useState<Tweet[]>([]);
const [radarTokens, setRadarTokens] = useState<Token[]>([]);
const [positionTokens, setPositionTokens] = useState<Token[]>([]);
useEffect(() => {
setAlphaTweets(Array.from({ length: 20 }).map((_, i) => ({ ...generateTweet(`a-${i}`, 'alpha'), timestamp: `${i * 3}m` })));
setDiscussionTweets(Array.from({ length: 20 }).map((_, i) => ({ ...generateTweet(`d-${i}`, 'discussion'), timestamp: `${i * 4}m` })));
setRadarTokens(Array.from({ length: 8 }).map((_, i) => ({ ...generateToken(`r-${i}`), isNew: false, timeAgo: `${i * 2}m` })));
setPositionTokens(Array.from({ length: 6 }).map((_, i) => ({ ...generateToken(`p-${i}`), isNew: false, timeAgo: `${i * 5}m` })));
const interval = setInterval(() => {
const rand = Math.random();
if (rand > 0.7) {
setRadarTokens(prev => [generateToken(`r-${Date.now()}`), ...prev.slice(0, 19)]);
} else if (rand > 0.5) {
setAlphaTweets(prev => [generateTweet(`a-${Date.now()}`, 'alpha'), ...prev.slice(0, 19)]);
} else if (rand > 0.3) {
setDiscussionTweets(prev => [generateTweet(`d-${Date.now()}`, 'discussion'), ...prev.slice(0, 19)]);
} else {
setPositionTokens(prev => [generateToken(`p-${Date.now()}`), ...prev.slice(0, 19)]);
}
}, 2500);
return () => clearInterval(interval);
}, []);
return (
<div className="flex h-screen w-full bg-[#06070b] text-slate-200 font-sans overflow-hidden selection:bg-[#526fff]/30">
{/* LEFT PANEL: FEED (50%) */}
<div className="flex-1 flex flex-col min-w-0 bg-[#06070b] border-r border-[#1d254a]">
<header className="h-14 border-b border-[#1d254a] flex items-center justify-between px-6 bg-[#06070b] sticky top-0 z-20">
<div className="flex items-center gap-3">
<div className="relative flex h-2.5 w-2.5">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
<span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
</div>
<h1 className="font-bold tracking-tight text-lg text-white">Tokens</h1>
<span className="flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-[10px] font-bold text-emerald-500 tracking-wide ml-2">
<div className="w-3 h-1.5 rounded-full bg-emerald-500" />
PUMP
</span>
</div>
</header>
<div className="flex-1 flex overflow-hidden">
<div className="flex-1 flex flex-col border-r border-[#1d254a] min-w-0 bg-[#06070b]/40">
<div className="h-10 flex items-center justify-between px-4 border-b border-[#1d254a] bg-[#1d254a]/10 backdrop-blur-sm sticky top-0 z-10">
<div className="flex items-center">
<span className="text-xs font-bold uppercase tracking-wider text-slate-400">New Listings</span>
</div>
<SlidersHorizontal size={14} className="text-slate-500 hover:text-white cursor-pointer transition-colors" />
</div>
<div className="flex-1 overflow-y-auto relative scrollbar-thin scrollbar-thumb-[#1d254a] hover:scrollbar-thumb-[#526fff]/50">
<div className="absolute inset-0 bg-gradient-to-b from-[#526fff]/5 via-transparent to-transparent pointer-events-none opacity-20" />
<AnimatePresence initial={false}>
{radarTokens.map((token) => (
<PulseCard key={token.id} token={token} type="radar" />
))}
</AnimatePresence>
</div>
</div>
<div className="flex-1 flex flex-col min-w-0 bg-[#06070b]/60">
<div className="h-10 flex items-center justify-between px-4 border-b border-[#1d254a] bg-[#1d254a]/10 backdrop-blur-sm sticky top-0 z-10">
<div className="flex items-center">
<span className="text-xs font-bold uppercase tracking-wider text-slate-400">Watching</span>
</div>
<SlidersHorizontal size={14} className="text-slate-500 hover:text-white cursor-pointer transition-colors" />
</div>
<div className="flex-1 overflow-y-auto relative scrollbar-thin scrollbar-thumb-[#1d254a] hover:scrollbar-thumb-[#97a8ff]/50">
<AnimatePresence initial={false}>
{positionTokens.map((token) => (
<PulseCard key={token.id} token={token} type="position" />
))}
</AnimatePresence>
</div>
</div>
</div>
</div>
{/* RIGHT PANEL: LIVE FEED (50%) */}
<div className="flex-1 flex flex-col min-w-0 bg-[#06070b]">
<header className="h-14 border-b border-[#1d254a] flex items-center justify-between px-6 bg-[#06070b] sticky top-0 z-20">
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-full bg-[#1d9bf0]/10 flex items-center justify-center border border-[#1d9bf0]/20">
<Activity size={16} className="text-[#1d9bf0]" />
</div>
<h2 className="font-bold text-lg tracking-tight text-white">Social</h2>
</div>
</header>
<div className="flex-1 flex overflow-hidden">
<div className="flex-1 flex flex-col border-r border-[#1d254a] min-w-0 bg-[#06070b]/40">
<div className="h-10 flex items-center justify-between px-4 border-b border-[#1d254a] bg-[#1d254a]/10 backdrop-blur-sm sticky top-0 z-10">
<div className="flex items-center">
<span className="text-xs font-bold uppercase tracking-wider text-slate-400">SELECTED</span>
</div>
<SlidersHorizontal size={14} className="text-slate-500 hover:text-white cursor-pointer transition-colors" />
</div>
<div className="flex-1 overflow-y-auto relative scrollbar-thin scrollbar-thumb-[#1d254a] hover:scrollbar-thumb-amber-500/50">
<AnimatePresence initial={false}>
{alphaTweets.map((tweet) => (
<TweetCard key={tweet.id} tweet={tweet} variant="alpha" />
))}
</AnimatePresence>
</div>
</div>
<div className="flex-1 flex flex-col min-w-0 bg-[#06070b]/60">
<div className="h-10 flex items-center justify-between px-4 border-b border-[#1d254a] bg-[#1d254a]/10 backdrop-blur-sm sticky top-0 z-10">
<div className="flex items-center">
<span className="text-xs font-bold uppercase tracking-wider text-slate-400">ALPHA</span>
</div>
<SlidersHorizontal size={14} className="text-slate-500 hover:text-white cursor-pointer transition-colors" />
</div>
<div className="flex-1 overflow-y-auto relative scrollbar-thin scrollbar-thumb-[#1d254a] hover:scrollbar-thumb-slate-500/50">
<AnimatePresence initial={false}>
{discussionTweets.map((tweet) => (
<TweetCard key={tweet.id} tweet={tweet} variant="discussion" />
))}
</AnimatePresence>
</div>
</div>
</div>
</div>
</div>
);
}
function PulseCard({ token, type }: { token: Token, type: 'radar' | 'position' }) {
const isRadar = type === 'radar';
const glowClass = isRadar ? 'from-[#526fff]/20' : 'from-[#97a8ff]/20';
return (
<motion.div
layout
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={`group relative p-3 border-b border-[#1d254a] hover:bg-[#101114] transition-all cursor-pointer flex flex-row items-stretch`}
>
<div className={`absolute inset-0 bg-gradient-to-br ${glowClass} to-transparent opacity-0 group-hover:opacity-100 transition-opacity`} />
{/* Left Side: Image & Ticker */}
<div className="flex flex-col items-center gap-1.5 w-[68px] shrink-0">
<div className="w-[68px] h-[68px] rounded-lg bg-[#06070b] border border-[#1d254a] flex items-center justify-center font-bold text-sm text-slate-400 group-hover:text-white transition-colors shadow-lg shadow-black/40">
{token.ticker.slice(0, 2)}
</div>
<div className="flex flex-col items-center w-full gap-0.5 px-0.5">
<div className="flex items-center justify-center gap-1 w-full">
<span className="font-bold text-[11px] text-slate-200 group-hover:text-white truncate max-w-[45px] leading-none">{token.ticker}</span>
<span className="text-[9px] font-mono text-slate-500 shrink-0 leading-none">{token.timeAgo}</span>
<span
className={`text-[8px] font-bold px-0.5 rounded-[2px] leading-none ${
token.status === 'migrated'
? 'text-emerald-400 bg-emerald-500/10'
: 'text-amber-400 bg-amber-500/10'
}`}
title={token.status === 'migrated' ? 'Migrated' : 'Bonding'}
>
{token.status === 'migrated' ? 'M' : 'B'}
</span>
</div>
<span className="font-mono text-[9px] text-slate-500 opacity-60 hover:opacity-100 transition-opacity w-full text-center truncate leading-none">{token.address}</span>
</div>
</div>
{/* Middle: Social Signals (New Implementation) */}
<div className="flex-1 px-3 flex flex-col justify-between min-w-0 mx-1.5 border-l border-[#1d254a]/30 border-r border-[#1d254a]/30">
{/* Row 1: Admin & Community (Identity) */}
<div className="flex items-center justify-between mt-0.5">
<div className="flex items-center gap-2 overflow-hidden">
{/* Admin Rank & Handle */}
<div className="group/admin relative flex items-center gap-1.5 cursor-help">
<Crown size={14} strokeWidth={1.5} className="text-amber-400" />
<div className="flex flex-col leading-none">
<span className="text-[12px] font-mono text-slate-200">{token.social.admin.handle}</span>
</div>
{/* Admin Tooltip */}
<div className="absolute bottom-full left-0 mb-2 p-2.5 bg-[#06070b]/95 backdrop-blur-md border border-[#1d254a] rounded shadow-xl opacity-0 group-hover/admin:opacity-100 pointer-events-none z-50 flex flex-col gap-1.5 transition-opacity duration-200 min-w-[140px]">
<span className="text-[10px] font-bold text-slate-400 border-b border-[#1d254a] pb-1.5 uppercase tracking-wider block w-full">{token.social.admin.handle}</span>
<div className="flex items-center justify-between gap-2 text-[10px] font-mono text-slate-300">
<div className="flex items-center gap-1.5" title="Followers">
<Users size={12} className="text-slate-400" />
<span>{token.social.admin.followers}</span>
</div>
<div className="flex items-center gap-1.5" title="Score">
<Medal size={12} className="text-amber-500" />
<span>{token.social.admin.score}</span>
</div>
<div className="flex items-center gap-1.5" title="Lists">
<Layers size={12} className="text-slate-500" />
<span>{token.social.admin.lists}</span>
</div>
</div>
</div>
</div>
{/* Divider */}
<div className="h-4 w-[1px] bg-[#1d254a]" />
{/* Moderators */}
<div className="group/mod relative flex items-center gap-1.5 cursor-help" title="Moderators">
<ShieldCheck size={14} strokeWidth={1.5} className="text-emerald-400" />
<span className="text-[12px] font-mono text-slate-300">{token.social.community.moderatorCount}</span>
{/* Glassmorphism Tooltip */}
<div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-48 p-2 bg-[#06070b]/95 backdrop-blur-md border border-[#1d254a] rounded shadow-xl opacity-0 group-hover/mod:opacity-100 pointer-events-none z-50 flex flex-col gap-1 transition-opacity duration-200">
<span className="text-[10px] font-bold text-emerald-500 border-b border-[#1d254a] pb-1 mb-0.5 uppercase tracking-wider">Top Moderators</span>
{token.social.community.moderators.map((mod, i) => (
<div key={i} className="flex justify-between text-[10px] text-slate-400 font-mono">
<span>{mod.name}</span>
<span className="text-slate-200">{mod.score}s</span>
</div>
))}
</div>
</div>
</div>
{/* Community Stats */}
<div className="flex items-center gap-3 shrink-0 ml-2">
<div className="flex items-center gap-1.5 text-slate-500 hover:text-[#1d9bf0] transition-colors cursor-pointer" title="Twitter Community">
<Twitter size={14} strokeWidth={1.5} className="text-[#1d9bf0]" />
<span className="text-[12px] font-mono text-slate-300">{token.social.community.twitterGroupMembers}</span>
</div>
<div className="flex items-center gap-1.5 text-slate-500 hover:text-[#526fff] transition-colors cursor-pointer" title="Telegram/Discord">
<MessageSquare size={14} strokeWidth={1.5} className="text-[#526fff]" />
<span className="text-[12px] font-mono text-slate-300">{token.social.community.communityMembers}</span>
</div>
</div>
</div>
{/* Row 2: Tweet Metrics Grid (Volume) */}
<div className="grid grid-cols-5 gap-1 mt-0.5 items-center">
{/* Total */}
<div className="flex items-center gap-1.5" title="Total Volume">
<Layers size={14} strokeWidth={1.5} className="text-slate-500" />
<span className="text-[12px] font-mono text-slate-200 font-medium">{token.social.tweets.total}</span>
</div>
{/* Bots */}
<div className="flex items-center gap-1.5" title="Bot Activity">
<Bot size={14} strokeWidth={1.5} className={token.social.tweets.bot > 30 ? "text-rose-500" : "text-slate-500"} />
<span className={`text-[12px] font-mono font-medium ${token.social.tweets.bot > 30 ? "text-rose-400" : "text-slate-300"}`}>{token.social.tweets.bot}</span>
</div>
{/* Reach */}
<div className="flex items-center gap-1.5" title="Total Reach">
<Eye size={14} strokeWidth={1.5} className="text-slate-500" />
<span className="text-[12px] font-mono text-slate-300 font-medium">{token.social.tweets.reach}</span>
</div>
{/* Unique */}
<div className="flex items-center gap-1.5" title="Unique Authors">
<User size={14} strokeWidth={1.5} className="text-[#526fff]" />
<span className="text-[12px] font-mono text-slate-200 font-medium">{token.social.tweets.unique}</span>
</div>
{/* Smart Money */}
<div className="flex items-center gap-1.5" title="Smart Money Interest">
<Filter size={14} strokeWidth={1.5} className="text-emerald-500" />
<span className="text-[12px] font-mono text-emerald-400 font-medium">{token.social.tweets.filtered}</span>
</div>
</div>
{/* Row 3: Sentiment & Marine Life (Details) */}
<div className="flex items-center justify-between gap-1 mt-0.5 border-t border-[#1d254a]/30 pt-1">
{/* Risks */}
<div className="flex items-center gap-3">
<div className="flex items-center gap-1.5" title="FUD Level">
<AlertTriangle size={14} strokeWidth={1.5} className="text-slate-500" />
<span className="text-[12px] font-mono text-slate-300">{token.social.sentiment.fud}</span>
</div>
<div className="flex items-center gap-1.5" title="Team Activity">
<Users2 size={14} strokeWidth={1.5} className="text-slate-500" />
<span className="text-[12px] font-mono text-slate-300">{token.social.sentiment.team}</span>
</div>
</div>
{/* Marine Life Tiers */}
<div className="flex items-center gap-2.5">
<div className="flex items-center gap-1" title="Shrimp (<1 SOL)">
<Fish size={10} strokeWidth={1.5} className="text-amber-500/60 -scale-x-100" />
<span className="text-[12px] font-mono text-slate-400">{token.social.sentiment.shrimp}</span>
</div>
<div className="flex items-center gap-1" title="Fish (1-10 SOL)">
<Fish size={12} strokeWidth={1.5} className="text-orange-400/80 -scale-x-100" />
<span className="text-[12px] font-mono text-slate-300">{token.social.sentiment.fish}</span>
</div>
<div className="flex items-center gap-1" title="Dolphin (10-100 SOL)">
<Fish size={14} strokeWidth={1.5} className="text-emerald-500 -scale-x-100" />
<span className="text-[12px] font-mono text-emerald-400">{token.social.sentiment.dolphin}</span>
</div>
<div className="flex items-center gap-1" title="Whale (>100 SOL)">
<Fish size={16} strokeWidth={1.5} className="text-cyan-400 -scale-x-100 fill-cyan-400/10" />
<span className="text-[12px] font-mono text-cyan-300 font-bold">{token.social.sentiment.whale}</span>
</div>
</div>
</div>
</div>
{/* Right Side: Trading Metrics (Reduced width) */}
<div className="w-[62px] shrink-0 flex flex-col justify-between min-w-0">
{/* Top Row: Volume & Market Cap */}
<div className="flex flex-col gap-0.5 mt-0.5">
<div className="flex items-center gap-1">
<span className="text-[7px] font-bold text-slate-500 w-3">V</span>
<LiveNumber value={token.volume} prefix="$" colorClass="text-white text-[10px]" />
</div>
<div className="flex items-center gap-1">
<span className="text-[7px] font-bold text-slate-500 w-3">MC</span>
<LiveNumber value={token.marketCap} prefix="$" colorClass="text-cyan-400 text-[10px]" />
</div>
</div>
{/* Middle Row: Fees & TX */}
<div className="flex flex-col gap-0.5 mt-0.5">
<div className="flex items-center gap-1">
<span className="text-[7px] font-bold text-slate-500 w-3">F</span>
<div className="flex items-center gap-0.5">
<img src="https://cryptologos.cc/logos/solana-sol-logo.png?v=026" className="w-1.5 h-1.5 opacity-80" alt="sol" />
<span className="text-[8px] font-mono font-medium text-slate-200">{token.fees.toFixed(1)}</span>
</div>
</div>
<div className="flex items-center gap-1">
<span className="text-[7px] font-bold text-slate-500 w-3">TX</span>
<div className="flex items-center gap-1">
<span className="text-[8px] font-mono font-medium text-slate-200">{token.transactions}</span>
<div className="flex gap-0.5 h-1 items-end">
<div className="w-1.5 h-0.5 rounded-full bg-emerald-500 animate-pulse" />
<div className="w-1.5 h-0.5 rounded-full bg-rose-500 opacity-50" />
</div>
</div>
</div>
</div>
{/* Bottom Row: Buy Button & Time */}
<div className="mt-1 w-full">
<button className="w-full flex items-center justify-center gap-1 bg-[#4963e4] hover:bg-[#5f7af8] hover:shadow-[0_0_10px_rgba(73,99,228,0.6)] active:scale-95 transition-all text-white rounded-[2px] h-7 px-0 group/btn shadow-lg shadow-blue-900/20">
<Zap size={10} className="fill-white" />
<span className="text-[10px] font-bold font-mono">{token.buyAmount}</span>
</button>
</div>
</div>
</motion.div>
);
}
function TweetCard({ tweet, variant }: { tweet: Tweet, variant: 'alpha' | 'discussion' }) {
const isAlpha = variant === 'alpha';
return (
<motion.div
layout
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0 }}
className={`px-4 py-4 border-b border-[#1d254a] hover:bg-[#101114] cursor-pointer transition-colors group ${tweet.type === 'alpha' ? 'bg-amber-500/[0.02]' : ''}`}
>
<div className="flex gap-3">
{/* Avatar Section */}
<div className="flex-shrink-0 flex flex-col items-center gap-2 pt-1 w-10">
<div className={`w-8 h-8 rounded-full bg-gradient-to-br ${tweet.user.avatarGradient} flex items-center justify-center text-white font-bold text-xs shadow-lg shadow-[#1d254a]/50`}>
{tweet.user.name[0]}
</div>
{/* User Metrics */}
<div className="flex flex-col gap-1 items-center">
<div className="flex items-center gap-0.5 text-[8px] text-slate-500" title="Followers">
<Users size={8} />
<span>{tweet.user.followers}</span>
</div>
<div className="flex items-center gap-0.5 text-[8px] text-slate-500" title="Avg Reach">
<BarChart2 size={8} />
<span>{tweet.user.reach}</span>
</div>
<div className="flex items-center gap-0.5 text-[8px] text-emerald-500 font-medium" title="Trust Score">
<Shield size={8} />
<span>{tweet.user.trustScore}</span>
</div>
</div>
</div>
{/* Content */}
<div className="flex-1 min-w-0">
<div className="flex items-center gap-1.5 mb-1">
<span className={`font-bold text-xs truncate ${isAlpha ? 'text-amber-100' : 'text-slate-200'}`}>
{tweet.user.name}
</span>
{tweet.user.verified && <div className="w-3 h-3 rounded-full bg-[#1d9bf0] flex items-center justify-center"><User size={8} className="text-white" /></div>}
<span className="text-slate-500 text-[10px] truncate max-w-[80px]">{tweet.user.handle}</span>
<div className="ml-auto flex items-center gap-2">
<span className="text-slate-600 text-[10px]">{tweet.timestamp}</span>
<MoreHorizontal size={14} className="text-slate-600 hover:text-slate-400 cursor-pointer" />
</div>
</div>
<p className="text-sm text-slate-300 leading-relaxed whitespace-pre-wrap mb-2">
{tweet.content}
</p>
{/* Optional Media */}
{tweet.mediaUrl && (
<div className="mb-2 rounded-lg overflow-hidden border border-[#1d254a] relative aspect-video">
<img src={tweet.mediaUrl} alt="Chart" className="w-full h-full object-cover opacity-80 hover:opacity-100 transition-opacity" />
<div className="absolute top-2 right-2 bg-black/60 px-1.5 py-0.5 rounded text-[9px] text-white flex items-center gap-1">
<ImageIcon size={10} />
<span>IMG</span>
</div>
</div>
)}
<div className="relative flex items-center justify-end mt-2">
{/* Ticker Badge - Bottom Right */}
{tweet.ticker && (
<div className="flex items-center gap-1 bg-slate-900/80 backdrop-blur-md border border-slate-800 rounded-full py-0.5 px-1.5 shadow-lg hover:border-slate-700 transition-colors ml-auto">
<div className={`w-3 h-3 rounded-full flex items-center justify-center text-[7px] font-bold ${
tweet.ticker === 'SOL' ? 'bg-gradient-to-tr from-[#9945FF] to-[#14F195] text-white' :
tweet.ticker === 'BONK' ? 'bg-[#ffde9e] text-orange-900' :
tweet.ticker === 'WIF' ? 'bg-[#dec499] text-amber-900' :
'bg-slate-700 text-white'
}`}>
{tweet.ticker[0]}
</div>
<span className="text-[8px] font-bold text-slate-200">{tweet.ticker}</span>
{tweet.priceChange !== undefined && (
<span className={`text-[8px] font-mono ${tweet.priceChange >= 0 ? 'text-emerald-400' : 'text-rose-400'}`}>
{tweet.priceChange >= 0 ? '+' : ''}{tweet.priceChange.toFixed(2)}%
</span>
)}
</div>
)}
</div>
</div>
</div>
</motion.div>
);
}
~~~
Implementation Guidelines
1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system
Help me integrate this into my design