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
This commit is contained in:
@@ -4,11 +4,18 @@ 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() {
|
||||
@@ -17,6 +24,13 @@ export default function Dashboard() {
|
||||
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')
|
||||
}
|
||||
@@ -29,41 +43,167 @@ export default function Dashboard() {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 p-8 bg-gray-950 min-h-screen">
|
||||
<div className="space-y-8">
|
||||
<AIAnalysisPanel />
|
||||
<AutoTradingPanel />
|
||||
<DeveloperSettings />
|
||||
</div>
|
||||
<div className="space-y-8">
|
||||
<div className="bg-gray-900 rounded-lg shadow p-6">
|
||||
<h2 className="text-xl font-bold mb-4 text-white">Open Positions</h2>
|
||||
{loading ? <div className="text-gray-400">Loading...</div> : error ? <div className="text-red-400">{error}</div> : (
|
||||
<table className="w-full text-sm text-left">
|
||||
<thead className="text-gray-400 border-b border-gray-700">
|
||||
<tr>
|
||||
<th className="py-2">Symbol</th>
|
||||
<th>Side</th>
|
||||
<th>Size</th>
|
||||
<th>Entry Price</th>
|
||||
<th>Unrealized PnL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{positions.map((pos, i) => (
|
||||
<tr key={i} className="border-b border-gray-800 hover:bg-gray-800">
|
||||
<td className="py-2">{pos.symbol}</td>
|
||||
<td>{pos.side}</td>
|
||||
<td>{pos.size}</td>
|
||||
<td>{pos.entryPrice}</td>
|
||||
<td>{pos.unrealizedPnl}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
<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>
|
||||
<TradingHistory />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user