From 045d4a41e3f10c8f1db6740c961b1458a96e4d6d Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Mon, 14 Jul 2025 00:50:39 +0200 Subject: [PATCH] Fix ScreenshotGallery and improve trade execution feedback - Add keyboard ESC listener for closing enlarged screenshots - Fix screenshot URL formatting to use /screenshots/[filename] route - Improve trade execution error handling with detailed messages - Show specific feedback for insufficient funds, auth issues, etc. - Remove unused Modal import that was causing build errors - Add click-outside-to-close functionality for enlarged images --- components/AIAnalysisPanel.tsx | 40 ++++++++++++++++++++------ components/ScreenshotGallery.tsx | 48 ++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/components/AIAnalysisPanel.tsx b/components/AIAnalysisPanel.tsx index 9946ec1..39539c8 100644 --- a/components/AIAnalysisPanel.tsx +++ b/components/AIAnalysisPanel.tsx @@ -1,6 +1,5 @@ "use client" import React, { useState } from 'react' -import Modal from './Modal' import TradeModal from './TradeModal' import ScreenshotGallery from './ScreenshotGallery' @@ -420,27 +419,50 @@ export default function AIAnalysisPanel() { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ symbol: tradeData.symbol, - side: 'buy', // Could be derived from analysis - size: parseFloat(tradeData.size), + side: 'BUY', // Could be derived from analysis + amount: parseFloat(tradeData.size), // Changed from 'size' to 'amount' price: parseFloat(tradeData.entry), stopLoss: parseFloat(tradeData.sl), takeProfit: parseFloat(tradeData.tp), leverage: parseInt(tradeData.leverage), - timeframe: tradeData.timeframe + timeframe: tradeData.timeframe, + orderType: 'MARKET' // Default to market order }) }) const result = await response.json() - if (response.ok) { - // Show success message - alert(`Trade executed successfully! Order ID: ${result.orderId || 'N/A'}`) + if (response.ok && result.success) { + // Show detailed success message + let message = `āœ… Trade executed successfully!\n\n` + message += `šŸ“Š Order ID: ${result.txId}\n` + message += `šŸ’° Symbol: ${tradeData.symbol}\n` + message += `šŸ“ˆ Size: ${tradeData.size}\n` + message += `šŸ’µ Entry: $${tradeData.entry}\n` + + if (tradeData.sl) message += `šŸ›‘ Stop Loss: $${tradeData.sl}\n` + if (tradeData.tp) message += `šŸŽÆ Take Profit: $${tradeData.tp}\n` + + if (result.conditionalOrders && result.conditionalOrders.length > 0) { + message += `\nšŸ”„ Conditional orders: ${result.conditionalOrders.length} placed` + } + + alert(message) } else { - alert(`Trade failed: ${result.error || 'Unknown error'}`) + // Show detailed error message + const errorMsg = result.error || 'Unknown error occurred' + + if (errorMsg.includes('insufficient funds') || errorMsg.includes('balance')) { + alert(`āŒ Trade Failed: Insufficient Balance\n\nPlease deposit funds to your Drift account before placing trades.\n\nError: ${errorMsg}`) + } else if (errorMsg.includes('not logged in') || errorMsg.includes('Cannot execute trade')) { + alert(`āŒ Trade Failed: Authentication Issue\n\nPlease check your Drift connection in the settings.\n\nError: ${errorMsg}`) + } else { + alert(`āŒ Trade Failed\n\nError: ${errorMsg}`) + } } } catch (error) { console.error('Trade execution failed:', error) - alert('Trade execution failed. Please check your connection.') + alert('āŒ Trade execution failed due to network error.\n\nPlease check your connection and try again.') } setTradeModalOpen(false) diff --git a/components/ScreenshotGallery.tsx b/components/ScreenshotGallery.tsx index 15d24a4..30dcf48 100644 --- a/components/ScreenshotGallery.tsx +++ b/components/ScreenshotGallery.tsx @@ -1,5 +1,5 @@ "use client" -import React from 'react' +import React, { useEffect } from 'react' interface ScreenshotGalleryProps { screenshots: string[] @@ -18,8 +18,30 @@ export default function ScreenshotGallery({ onImageClick, onClose }: ScreenshotGalleryProps) { + // Handle ESC key to close enlarged image + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === 'Escape' && enlargedImage) { + onClose() + } + } + + if (enlargedImage) { + document.addEventListener('keydown', handleKeyDown) + return () => document.removeEventListener('keydown', handleKeyDown) + } + }, [enlargedImage, onClose]) + if (screenshots.length === 0) return null + // Helper function to format screenshot URL + const formatScreenshotUrl = (screenshot: string) => { + // Extract just the filename from the full path + const filename = screenshot.split('/').pop() || screenshot + // Return the Next.js API route format + return `/screenshots/${filename}` + } + return ( <> {/* Gallery Grid */} @@ -40,23 +62,25 @@ export default function ScreenshotGallery({ {screenshots.map((screenshot, index) => { const filename = screenshot.split('/').pop() || '' const timeframe = timeframes[index] || 'Unknown' + const imageUrl = formatScreenshotUrl(screenshot) return (
onImageClick(screenshot)} + onClick={() => onImageClick(imageUrl)} > {/* Preview Image */}
{`${symbol} { + onError={(e: any) => { const target = e.target as HTMLImageElement target.style.display = 'none' - target.nextElementSibling?.classList.remove('hidden') + const fallback = target.nextElementSibling as HTMLElement + if (fallback) fallback.classList.remove('hidden') }} />
@@ -97,8 +121,11 @@ export default function ScreenshotGallery({ {/* Enlarged Image Modal */} {enlargedImage && ( -
-
+
+
e.stopPropagation()}> {/* Close Button */}
- ESC to close + ESC to close • Click outside to close