diff --git a/app/analysis/page.js b/app/analysis/page.js index 652e018..0760a63 100644 --- a/app/analysis/page.js +++ b/app/analysis/page.js @@ -1,7 +1,6 @@ 'use client' import React, { useState } from 'react' import AIAnalysisPanel from '../../components/AIAnalysisPanel.tsx' -import TradeExecutionPanel from '../../components/TradeExecutionPanel.js' export default function AnalysisPage() { const [analysisResult, setAnalysisResult] = useState(null) @@ -16,22 +15,13 @@ export default function AnalysisPage() {
-

AI Analysis & Trading

-

Get market insights and execute trades based on AI recommendations

+

AI Analysis

+

Get comprehensive market insights powered by AI analysis

-
-
- -
- -
- -
+
+
) diff --git a/app/analysis/page_fixed.js b/app/analysis/page_with_trading_panel.js.backup similarity index 100% rename from app/analysis/page_fixed.js rename to app/analysis/page_with_trading_panel.js.backup diff --git a/app/globals.css b/app/globals.css index 8e4c6c8..6450dbb 100644 --- a/app/globals.css +++ b/app/globals.css @@ -52,3 +52,44 @@ body { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); } + +/* Custom range slider styling */ +input[type="range"] { + -webkit-appearance: none; + appearance: none; + height: 8px; + background: linear-gradient(to right, #3B82F6 0%, #3B82F6 30%, #374151 30%, #374151 100%); + border-radius: 4px; + outline: none; + cursor: pointer; +} + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 20px; + height: 20px; + background: #3B82F6; + border-radius: 50%; + cursor: pointer; + border: 2px solid #1e40af; + box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3); +} + +input[type="range"]::-moz-range-thumb { + width: 20px; + height: 20px; + background: #3B82F6; + border-radius: 50%; + cursor: pointer; + border: 2px solid #1e40af; + box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3); +} + +input[type="range"]:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); +} + +input[type="range"]:focus::-moz-range-thumb { + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); +} diff --git a/app/trading/page.js b/app/trading/page.js index d0f9155..ca8bc23 100644 --- a/app/trading/page.js +++ b/app/trading/page.js @@ -18,16 +18,22 @@ export default function TradingPage() { useEffect(() => { fetchBalance() + // Refresh balance every 30 seconds to keep it current + const interval = setInterval(fetchBalance, 30000) + return () => clearInterval(interval) }, []) const fetchBalance = async () => { setLoading(true) try { - const response = await fetch('/api/trading/balance') + // Use the real wallet balance API + const response = await fetch('/api/wallet/balance') const data = await response.json() if (data.success) { setBalance(data.balance) + } else { + console.error('Failed to fetch balance:', data.error) } } catch (error) { console.error('Failed to fetch balance:', error) diff --git a/components/StatusOverview.js b/components/StatusOverview.js index 65dff68..0529924 100644 --- a/components/StatusOverview.js +++ b/components/StatusOverview.js @@ -8,7 +8,9 @@ export default function StatusOverview() { dailyPnL: 0, systemStatus: 'offline', bitqueryStatus: 'unknown', - marketPrices: [] + marketPrices: [], + walletBalance: null, // Real wallet balance + availableCoins: [] // Available coins in wallet }) const [loading, setLoading] = useState(true) @@ -17,8 +19,25 @@ export default function StatusOverview() { try { setLoading(true) + // Get real wallet balance + let walletBalance = null + let availableCoins = [] + + try { + const walletRes = await fetch('/api/wallet/balance') + if (walletRes.ok) { + const walletData = await walletRes.json() + if (walletData.success) { + walletBalance = walletData.balance + availableCoins = walletData.balance.positions || [] + } + } + } catch (e) { + console.warn('Could not fetch wallet balance:', e) + } + // Get market data from Bitquery - let balance = 0 + let balance = walletBalance?.totalValue || 0 // Use real wallet balance let bitqueryStatus = 'error' let marketPrices = [] @@ -29,15 +48,6 @@ export default function StatusOverview() { if (marketData.success) { marketPrices = marketData.data.prices || [] bitqueryStatus = marketData.data.status?.connected ? 'online' : 'error' - - // Calculate portfolio value from Bitquery - const portfolioRes = await fetch('/api/trading/balance') - if (portfolioRes.ok) { - const portfolioData = await portfolioRes.json() - if (portfolioData.success) { - balance = portfolioData.balance.totalValue || 0 - } - } } } } catch (e) { @@ -61,7 +71,9 @@ export default function StatusOverview() { dailyPnL: 0, // No fake P&L systemStatus: systemStatus, bitqueryStatus: bitqueryStatus, - marketPrices: marketPrices + marketPrices: marketPrices, + walletBalance: walletBalance, + availableCoins: availableCoins }) } catch (error) { console.error('Error fetching status:', error) @@ -119,6 +131,19 @@ export default function StatusOverview() {

Portfolio Value

+ {/* Wallet Balance */} + {status.walletBalance && ( +
+
+ 🪙 +
+

+ {status.walletBalance.positions?.[0]?.amount?.toFixed(4) || '0.0000'} SOL +

+

Wallet Balance

+
+ )} +
🔄 @@ -194,6 +219,35 @@ export default function StatusOverview() {
)} + + {/* Available Coins in Wallet */} + {status.availableCoins.length > 0 && ( +
+
+

Available Wallet Coins

+ Ready for Trading +
+
+ {status.availableCoins.map((coin, index) => ( +
+
+
+ 🪙 +
+ {coin.symbol} +
${coin.price?.toFixed(2)}
+
+
+
+
{coin.amount?.toFixed(4)}
+
${coin.usdValue?.toFixed(2)}
+
+
+
+ ))} +
+
+ )} )} diff --git a/components/TradeModal.tsx b/components/TradeModal.tsx index f0a90e3..e69de29 100644 --- a/components/TradeModal.tsx +++ b/components/TradeModal.tsx @@ -1,183 +0,0 @@ -"use client" -import React, { useState } from 'react' - -interface TradeModalProps { - isOpen: boolean - onClose: () => void - tradeData: { - symbol: string - timeframe: string - entry: string - tp: string - sl: string - } | null - onExecute: (data: any) => void -} - -export default function TradeModal({ isOpen, onClose, tradeData, onExecute }: TradeModalProps) { - const [loading, setLoading] = useState(false) - const [formData, setFormData] = useState({ - entry: tradeData?.entry || '', - tp: tradeData?.tp || '', - sl: tradeData?.sl || '', - size: '0.1', - leverage: '1' - }) - - React.useEffect(() => { - if (tradeData) { - setFormData(prev => ({ - ...prev, - entry: tradeData.entry || '', - tp: tradeData.tp || '', - sl: tradeData.sl || '' - })) - } - }, [tradeData]) - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault() - setLoading(true) - - try { - await onExecute({ - symbol: tradeData?.symbol, - timeframe: tradeData?.timeframe, - ...formData - }) - } catch (error) { - console.error('Trade execution failed:', error) - } finally { - setLoading(false) - } - } - - if (!isOpen || !tradeData) return null - - return ( -
-
-
-

- - 💰 - - Execute Trade -

- -
- -
-
-
Symbol: {tradeData.symbol}
-
Timeframe: {tradeData.timeframe}
-
-
- -
-
- - setFormData(prev => ({ ...prev, entry: e.target.value }))} - className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-green-500 focus:outline-none" - placeholder="0.00" - required - /> -
- -
- - setFormData(prev => ({ ...prev, tp: e.target.value }))} - className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-green-500 focus:outline-none" - placeholder="0.00" - required - /> -
- -
- - setFormData(prev => ({ ...prev, sl: e.target.value }))} - className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-red-500 focus:outline-none" - placeholder="0.00" - required - /> -
- -
-
- - setFormData(prev => ({ ...prev, size: e.target.value }))} - className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-cyan-500 focus:outline-none" - placeholder="0.1" - required - /> -
- -
- - -
-
- -
- - -
-
-
-
- ) -} diff --git a/docker-compose.override.yml b/docker-compose.override.yml deleted file mode 100644 index ca0a9ac..0000000 --- a/docker-compose.override.yml +++ /dev/null @@ -1,29 +0,0 @@ -# Docker Compose override for development -# This file is automatically merged with docker-compose.yml in development -# Use: docker compose up (will automatically include this file) - -services: - app: - # Development-specific settings - environment: - - NODE_ENV=development - - NEXT_TELEMETRY_DISABLED=1 - - # Enable hot reloading for development - volumes: - - ./:/app - - /app/node_modules - - ./screenshots:/app/screenshots - - ./videos:/app/videos - - ./.env:/app/.env # Mount .env file for development - - # Override command for development - command: ["npm", "run", "dev:docker"] - - # Note: Using host networking so no port bindings needed - # Ports are available directly on host via network_mode: host - - # Add development labels - labels: - - "traefik.enable=false" - - "dev.local=true" diff --git a/docker-compose.yml b/docker-compose.yml index 5e48dd9..d272d91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: NODE_OPTIONS: "--max-old-space-size=4096" restart: unless-stopped - + container_name: trader # Base environment variables (common to all environments) environment: - DOCKER_ENV=true