solana / src /components /dashboard /PerformanceTracker.tsx
dronesplace's picture
Initial upload
2acde71 verified
Raw
History Blame Contribute Delete
9.1 kB
import React from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
LineChart,
Line,
PieChart,
Pie,
Cell
} from 'recharts';
import {
TrendingUp,
TrendingDown,
Activity,
Target,
DollarSign,
Percent
} from 'lucide-react';
// Mock data for demonstration
const performanceData = [
{ date: '2024-01-01', profit: 120, loss: -30, trades: 8 },
{ date: '2024-01-02', profit: 85, loss: -45, trades: 12 },
{ date: '2024-01-03', profit: 95, loss: -20, trades: 6 },
{ date: '2024-01-04', profit: 140, loss: -60, trades: 15 },
{ date: '2024-01-05', profit: 110, loss: -25, trades: 9 },
{ date: '2024-01-06', profit: 165, loss: -40, trades: 11 },
{ date: '2024-01-07', profit: 190, loss: -55, trades: 14 }
];
const portfolioData = [
{ name: 'SOL', value: 45, color: '#00D4AA' },
{ name: 'USDC', value: 30, color: '#3B82F6' },
{ name: 'RAY', value: 15, color: '#8B5CF6' },
{ name: 'Others', value: 10, color: '#F59E0B' }
];
const tradingPairs = [
{ pair: 'SOL/USDC', trades: 24, pnl: 340.50, winRate: 75 },
{ pair: 'RAY/SOL', trades: 18, pnl: -125.30, winRate: 44 },
{ pair: 'ORCA/USDC', trades: 12, pnl: 89.20, winRate: 67 },
{ pair: 'BONK/SOL', trades: 8, pnl: 156.80, winRate: 88 }
];
export const PerformanceTracker: React.FC = () => {
const totalPnL = performanceData.reduce((acc, day) => acc + day.profit + day.loss, 0);
const totalTrades = performanceData.reduce((acc, day) => acc + day.trades, 0);
const winningTrades = Math.floor(totalTrades * 0.685); // 68.5% win rate
return (
<div className="space-y-6">
{/* Performance Overview */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Card className="bg-gradient-card border-border/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<TrendingUp className="h-5 w-5 text-primary" />
Daily P&L Trend
</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={performanceData}>
<CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
<XAxis
dataKey="date"
stroke="hsl(var(--muted-foreground))"
fontSize={12}
tickFormatter={(value) => new Date(value).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
/>
<YAxis stroke="hsl(var(--muted-foreground))" fontSize={12} />
<Tooltip
contentStyle={{
backgroundColor: 'hsl(var(--card))',
border: '1px solid hsl(var(--border))',
borderRadius: 'var(--radius)'
}}
/>
<Bar dataKey="profit" fill="hsl(var(--profit))" />
<Bar dataKey="loss" fill="hsl(var(--loss))" />
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
<Card className="bg-gradient-card border-border/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Activity className="h-5 w-5 text-primary" />
Portfolio Allocation
</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={portfolioData}
cx="50%"
cy="50%"
outerRadius={80}
dataKey="value"
>
{portfolioData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip
contentStyle={{
backgroundColor: 'hsl(var(--card))',
border: '1px solid hsl(var(--border))',
borderRadius: 'var(--radius)'
}}
/>
</PieChart>
</ResponsiveContainer>
<div className="grid grid-cols-2 gap-2 mt-4">
{portfolioData.map((item) => (
<div key={item.name} className="flex items-center gap-2">
<div
className="w-3 h-3 rounded-full"
style={{ backgroundColor: item.color }}
/>
<span className="text-sm">{item.name}</span>
<span className="text-sm text-muted-foreground">{item.value}%</span>
</div>
))}
</div>
</CardContent>
</Card>
</div>
{/* Trading Pairs Performance */}
<Card className="bg-gradient-card border-border/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Target className="h-5 w-5 text-primary" />
Trading Pairs Performance
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
{tradingPairs.map((pair, index) => (
<div
key={pair.pair}
className="flex items-center justify-between p-4 rounded-lg border bg-secondary/30 animate-fade-in"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-center gap-4">
<div className="font-mono font-semibold">{pair.pair}</div>
<Badge variant="outline" className="text-xs">
{pair.trades} trades
</Badge>
</div>
<div className="flex items-center gap-6">
<div className="text-right">
<div className={`font-bold ${pair.pnl >= 0 ? 'text-profit' : 'text-loss'}`}>
{pair.pnl >= 0 ? '+' : ''}${pair.pnl.toFixed(2)}
</div>
<div className="text-xs text-muted-foreground">P&L</div>
</div>
<div className="text-right">
<div className={`font-bold ${pair.winRate >= 60 ? 'text-profit' : pair.winRate >= 40 ? 'text-warning' : 'text-loss'}`}>
{pair.winRate}%
</div>
<div className="text-xs text-muted-foreground">Win Rate</div>
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
{/* Summary Stats */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Card className="bg-gradient-card border-border/50">
<CardContent className="p-4">
<div className="flex items-center gap-2">
<DollarSign className="h-5 w-5 text-profit" />
<div>
<p className="text-sm text-muted-foreground">Total P&L</p>
<p className={`text-lg font-bold ${totalPnL >= 0 ? 'text-profit' : 'text-loss'}`}>
{totalPnL >= 0 ? '+' : ''}${totalPnL.toFixed(2)}
</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-gradient-card border-border/50">
<CardContent className="p-4">
<div className="flex items-center gap-2">
<Activity className="h-5 w-5 text-info" />
<div>
<p className="text-sm text-muted-foreground">Total Trades</p>
<p className="text-lg font-bold">{totalTrades}</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-gradient-card border-border/50">
<CardContent className="p-4">
<div className="flex items-center gap-2">
<TrendingUp className="h-5 w-5 text-profit" />
<div>
<p className="text-sm text-muted-foreground">Winning Trades</p>
<p className="text-lg font-bold text-profit">{winningTrades}</p>
</div>
</div>
</CardContent>
</Card>
<Card className="bg-gradient-card border-border/50">
<CardContent className="p-4">
<div className="flex items-center gap-2">
<Percent className="h-5 w-5 text-accent" />
<div>
<p className="text-sm text-muted-foreground">Win Rate</p>
<p className="text-lg font-bold text-profit">68.5%</p>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
);
};