Files
trading_bot_v3/components/Dashboard.tsx
mindesbunister a9bbcc7b5f Fix Tailwind CSS styling configuration
- Add tailwind.config.ts with proper content paths and theme config
- Add postcss.config.js for Tailwind and autoprefixer processing
- Downgrade tailwindcss to v3.4.17 and add missing PostCSS dependencies
- Update Dockerfile to clarify build process
- Fix UI styling issues in Docker environment
2025-07-12 23:29:42 +02:00

211 lines
9.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import React, { useEffect, useState } from 'react'
import AutoTradingPanel from './AutoTradingPanel'
import TradingHistory from './TradingHistory'
import DeveloperSettings from './DeveloperSettings'
import AIAnalysisPanel from './AIAnalysisPanel'
import SessionStatus from './SessionStatus'
export default function Dashboard() {
const [positions, setPositions] = useState<any[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [stats, setStats] = useState({
totalPnL: 0,
dailyPnL: 0,
winRate: 0,
totalTrades: 0
})
useEffect(() => {
async function fetchPositions() {
try {
const res = await fetch('/api/trading')
if (res.ok) {
const data = await res.json()
setPositions(data.positions || [])
// Calculate some mock stats for demo
setStats({
totalPnL: 1247.50,
dailyPnL: 67.25,
winRate: 73.2,
totalTrades: 156
})
} else {
setError('Failed to load positions')
}
} catch (e) {
setError('Error loading positions')
}
setLoading(false)
}
fetchPositions()
}, [])
return (
<div className="space-y-8">
{/* Stats Cards */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
<div className="card card-gradient">
<div className="flex items-center justify-between">
<div>
<p className="text-gray-400 text-sm font-medium">Total P&L</p>
<p className={`text-2xl font-bold ${stats.totalPnL >= 0 ? 'text-green-400' : 'text-red-400'}`}>
{stats.totalPnL >= 0 ? '+' : ''}${stats.totalPnL.toFixed(2)}
</p>
</div>
<div className="w-12 h-12 bg-green-500/20 rounded-full flex items-center justify-center">
<span className="text-green-400 text-xl">📈</span>
</div>
</div>
</div>
<div className="card card-gradient">
<div className="flex items-center justify-between">
<div>
<p className="text-gray-400 text-sm font-medium">Daily P&L</p>
<p className={`text-2xl font-bold ${stats.dailyPnL >= 0 ? 'text-green-400' : 'text-red-400'}`}>
{stats.dailyPnL >= 0 ? '+' : ''}${stats.dailyPnL.toFixed(2)}
</p>
</div>
<div className="w-12 h-12 bg-blue-500/20 rounded-full flex items-center justify-center">
<span className="text-blue-400 text-xl">💰</span>
</div>
</div>
</div>
<div className="card card-gradient">
<div className="flex items-center justify-between">
<div>
<p className="text-gray-400 text-sm font-medium">Win Rate</p>
<p className="text-2xl font-bold text-cyan-400">{stats.winRate}%</p>
</div>
<div className="w-12 h-12 bg-cyan-500/20 rounded-full flex items-center justify-center">
<span className="text-cyan-400 text-xl">🎯</span>
</div>
</div>
</div>
<div className="card card-gradient">
<div className="flex items-center justify-between">
<div>
<p className="text-gray-400 text-sm font-medium">Total Trades</p>
<p className="text-2xl font-bold text-purple-400">{stats.totalTrades}</p>
</div>
<div className="w-12 h-12 bg-purple-500/20 rounded-full flex items-center justify-center">
<span className="text-purple-400 text-xl">🔄</span>
</div>
</div>
</div>
</div>
{/* Main Content Grid */}
<div className="grid grid-cols-1 xl:grid-cols-3 gap-8">
{/* Left Column - Controls */}
<div className="xl:col-span-1 space-y-6">
<SessionStatus />
<AutoTradingPanel />
<DeveloperSettings />
</div>
{/* Right Column - Analysis & Positions */}
<div className="xl:col-span-2 space-y-6">
<AIAnalysisPanel />
{/* Open Positions */}
<div className="card card-gradient">
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-white flex items-center">
<span className="w-2 h-2 bg-green-400 rounded-full mr-3 animate-pulse"></span>
Open Positions
</h2>
<button className="text-sm text-gray-400 hover:text-gray-300 transition-colors">
View All
</button>
</div>
{loading ? (
<div className="flex items-center justify-center py-8">
<div className="spinner"></div>
<span className="ml-2 text-gray-400">Loading positions...</span>
</div>
) : error ? (
<div className="text-center py-8">
<div className="w-16 h-16 bg-red-500/20 rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-red-400 text-2xl"></span>
</div>
<p className="text-red-400 font-medium">{error}</p>
<p className="text-gray-500 text-sm mt-2">Please check your connection and try again</p>
</div>
) : positions.length === 0 ? (
<div className="text-center py-8">
<div className="w-16 h-16 bg-gray-700/50 rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-gray-400 text-2xl">📊</span>
</div>
<p className="text-gray-400 font-medium">No open positions</p>
<p className="text-gray-500 text-sm mt-2">Start trading to see your positions here</p>
</div>
) : (
<div className="overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b border-gray-700">
<th className="text-left py-3 px-4 text-gray-400 font-medium text-sm">Asset</th>
<th className="text-left py-3 px-4 text-gray-400 font-medium text-sm">Side</th>
<th className="text-right py-3 px-4 text-gray-400 font-medium text-sm">Size</th>
<th className="text-right py-3 px-4 text-gray-400 font-medium text-sm">Entry</th>
<th className="text-right py-3 px-4 text-gray-400 font-medium text-sm">PnL</th>
</tr>
</thead>
<tbody>
{positions.map((pos, i) => (
<tr key={i} className="border-b border-gray-800/50 hover:bg-gray-800/30 transition-colors">
<td className="py-4 px-4">
<div className="flex items-center">
<div className="w-8 h-8 bg-gradient-to-br from-orange-400 to-orange-600 rounded-full flex items-center justify-center mr-3">
<span className="text-white text-xs font-bold">
{pos.symbol?.slice(0, 2) || 'BT'}
</span>
</div>
<span className="font-medium text-white">{pos.symbol || 'BTC/USD'}</span>
</div>
</td>
<td className="py-4 px-4">
<span className={`inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium ${
pos.side === 'long' || pos.side === 'buy'
? 'bg-green-100 text-green-800'
: 'bg-red-100 text-red-800'
}`}>
{pos.side || 'Long'}
</span>
</td>
<td className="py-4 px-4 text-right font-mono text-gray-300">
{pos.size || '0.1 BTC'}
</td>
<td className="py-4 px-4 text-right font-mono text-gray-300">
${pos.entryPrice || '45,230.00'}
</td>
<td className="py-4 px-4 text-right">
<span className={`font-mono font-medium ${
(pos.unrealizedPnl || 125.50) >= 0 ? 'text-green-400' : 'text-red-400'
}`}>
{(pos.unrealizedPnl || 125.50) >= 0 ? '+' : ''}${(pos.unrealizedPnl || 125.50).toFixed(2)}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
</div>
<TradingHistory />
</div>
</div>
</div>
)
}