🎉 FIXED: Screenshot gallery preview and enlargement functionality

Major Issues Resolved:
- Screenshot gallery images now load and display correctly
- Click-to-enlarge modal functionality working
- ESC key closes enlarged images (confirmed working)
- Click-outside-to-close functionality added

- Created new /api/image route to serve screenshots (bypasses Next.js 15 route issue)
- Fixed screenshot URL formatting to use query parameter format
- Added proper keyboard event handling for ESC key
- Improved timeframe extraction from screenshot filenames
- Enhanced trade execution error handling with detailed feedback

- Fixed Next.js build cache issues causing route problems
- Cleaned up debugging console logs
- Restored normal conditional gallery rendering
- Proper error handling for image loading failures

The screenshot gallery now fully works:
1. Images display in grid layout 
2. Click any image to enlarge 
3. ESC key closes enlarged view 
4. Click outside modal to close 
5. Proper timeframe labeling 
6. Trade execution shows detailed error messages 
This commit is contained in:
mindesbunister
2025-07-14 01:22:30 +02:00
parent 1e65f5d87a
commit 23cab77200
4 changed files with 50 additions and 144 deletions

View File

@@ -475,7 +475,6 @@ export default function AIAnalysisPanel() {
return (
<div className="card card-gradient">
{console.log('AIAnalysisPanel render - result:', result)}
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-white flex items-center">
<span className="w-8 h-8 bg-gradient-to-br from-cyan-400 to-blue-600 rounded-lg flex items-center justify-center mr-3">
@@ -1371,23 +1370,14 @@ export default function AIAnalysisPanel() {
{/* Screenshot Gallery */}
{result && result.screenshots && (
<>
{console.log('Rendering ScreenshotGallery with:', {
screenshots: result.screenshots,
screenshotsLength: result.screenshots.length,
symbol,
selectedTimeframes,
enlargedScreenshot
})}
<ScreenshotGallery
screenshots={result.screenshots}
symbol={symbol}
timeframes={selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label || tf)}
enlargedImage={enlargedScreenshot}
onImageClick={handleScreenshotClick}
onClose={() => setEnlargedScreenshot(null)}
/>
</>
<ScreenshotGallery
screenshots={result.screenshots}
symbol={symbol}
timeframes={selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label || tf)}
enlargedImage={enlargedScreenshot}
onImageClick={handleScreenshotClick}
onClose={() => setEnlargedScreenshot(null)}
/>
)}
{/* Multi-timeframe Screenshot Gallery */}

View File

@@ -18,15 +18,6 @@ export default function ScreenshotGallery({
onImageClick,
onClose
}: ScreenshotGalleryProps) {
// Debug logging
console.log('ScreenshotGallery props:', {
screenshots,
symbol,
timeframes,
enlargedImage,
screenshotsLength: screenshots?.length
})
// Handle ESC key to close enlarged image
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
@@ -41,124 +32,14 @@ export default function ScreenshotGallery({
}
}, [enlargedImage, onClose])
if (screenshots.length === 0) {
console.log('ScreenshotGallery: No screenshots to display')
// TEMPORARY: Show a test gallery with known screenshots for debugging
const testScreenshots = [
'/screenshots/SOLUSD_240_ai_1752447978639.png',
'/screenshots/SOLUSD_15_ai_1752441315672.png'
]
console.log('ScreenshotGallery: Using test screenshots for debugging:', testScreenshots)
return (
<>
{/* Test Gallery Grid */}
<div className="mt-6 p-4 bg-gradient-to-br from-red-500/10 to-orange-500/10 border border-red-500/30 rounded-lg">
<div className="flex items-center justify-between mb-4">
<h4 className="text-lg font-bold text-white flex items-center">
<span className="w-6 h-6 bg-gradient-to-br from-red-400 to-red-600 rounded-lg flex items-center justify-center mr-2 text-sm">
🧪
</span>
Test Screenshots (Debug Mode)
</h4>
<div className="text-xs text-gray-400">
{testScreenshots.length} test images Click to enlarge
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{testScreenshots.map((screenshot, index) => {
const filename = screenshot.split('/').pop() || ''
const timeframe = index === 0 ? '4h' : '15m'
return (
<div
key={index}
className="group relative bg-gray-800/30 rounded-lg overflow-hidden border border-gray-700 hover:border-red-500/50 transition-all cursor-pointer transform hover:scale-[1.02]"
onClick={() => {
console.log('Test image clicked:', screenshot)
onImageClick(screenshot)
}}
>
<div className="aspect-video bg-gray-800 flex items-center justify-center relative">
<img
src={screenshot}
alt={`${symbol} - ${timeframe} chart`}
className="w-full h-full object-cover"
onLoad={() => console.log(`Test image loaded successfully: ${screenshot}`)}
onError={(e: any) => {
console.error(`Test image failed to load: ${screenshot}`, e)
const target = e.target as HTMLImageElement
target.style.display = 'none'
}}
/>
</div>
<div className="p-3">
<div className="flex items-center justify-between">
<div>
<div className="text-sm font-medium text-white">{symbol}</div>
<div className="text-xs text-red-300">{timeframe} Timeframe (Test)</div>
</div>
<div className="text-xs text-gray-400">
Click to view
</div>
</div>
</div>
</div>
)
})}
</div>
</div>
{/* Test Enlarged Image Modal */}
{enlargedImage && (
<div
className="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 z-50"
onClick={onClose}
>
<div className="relative max-w-6xl max-h-[90vh] w-full" onClick={(e: any) => e.stopPropagation()}>
<button
onClick={onClose}
className="absolute top-4 right-4 w-10 h-10 bg-black/50 hover:bg-black/70 rounded-full flex items-center justify-center text-white z-10 transition-colors"
>
</button>
<img
src={enlargedImage}
alt="Enlarged chart"
className="w-full h-full object-contain rounded-lg border border-gray-600"
onError={(e: any) => {
console.error('Failed to load enlarged image:', enlargedImage)
const target = e.target as HTMLImageElement
target.alt = 'Failed to load image'
}}
/>
<div className="absolute bottom-4 left-4 right-4 bg-black/70 backdrop-blur-sm rounded-lg p-4">
<div className="flex items-center justify-between">
<div>
<div className="text-white font-medium">{symbol} Chart Analysis (Test Mode)</div>
<div className="text-gray-300 text-sm">Debug screenshot High resolution view</div>
</div>
<div className="text-xs text-gray-400">
ESC to close Click outside to close
</div>
</div>
</div>
</div>
</div>
)}
</>
)
}
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}`
// Use the new API route with query parameter
return `/api/image?file=${filename}`
}
return (
@@ -196,8 +77,6 @@ export default function ScreenshotGallery({
const timeframe = timeframes[index] || extractTimeframeFromFilename(filename)
const imageUrl = formatScreenshotUrl(screenshot)
console.log(`Screenshot ${index}:`, { screenshot, filename, timeframe, imageUrl })
return (
<div
key={index}
@@ -210,9 +89,7 @@ export default function ScreenshotGallery({
src={imageUrl}
alt={`${symbol} - ${timeframe} chart`}
className="w-full h-full object-cover"
onLoad={() => console.log(`Image loaded successfully: ${imageUrl}`)}
onError={(e: any) => {
console.error(`Failed to load image: ${imageUrl}`, e)
const target = e.target as HTMLImageElement
target.style.display = 'none'
const fallback = target.nextElementSibling as HTMLElement