Compare commits
4 Commits
045d4a41e3
...
23cab77200
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23cab77200 | ||
|
|
1e65f5d87a | ||
|
|
65994816ab | ||
|
|
8087806a16 |
27
app/api/image/route.ts
Normal file
27
app/api/image/route.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const filename = searchParams.get('file')
|
||||
|
||||
if (!filename) {
|
||||
return NextResponse.json({ error: 'Filename required' }, { status: 400 })
|
||||
}
|
||||
|
||||
const screenshotsDir = path.join(process.cwd(), 'screenshots')
|
||||
const filePath = path.join(screenshotsDir, filename)
|
||||
const file = await fs.readFile(filePath)
|
||||
|
||||
return new NextResponse(file, {
|
||||
headers: {
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Disposition': `inline; filename="${filename}"`
|
||||
}
|
||||
})
|
||||
} catch (e: any) {
|
||||
return NextResponse.json({ error: e.message }, { status: 404 })
|
||||
}
|
||||
}
|
||||
12
app/api/test-gallery/route.ts
Normal file
12
app/api/test-gallery/route.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
return NextResponse.json({
|
||||
message: 'Test endpoint working',
|
||||
timestamp: new Date().toISOString(),
|
||||
screenshots: [
|
||||
'/app/screenshots/SOLUSD_240_ai_1752448407811.png',
|
||||
'/app/screenshots/SOLUSD_15_ai_1752441315672.png'
|
||||
]
|
||||
})
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
context: any
|
||||
) {
|
||||
try {
|
||||
const screenshotsDir = path.join(process.cwd(), 'screenshots')
|
||||
const filePath = path.join(screenshotsDir, context.params.filename)
|
||||
const file = await fs.readFile(filePath)
|
||||
return new NextResponse(file, {
|
||||
headers: {
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Disposition': `inline; filename="${context.params.filename}"`
|
||||
}
|
||||
})
|
||||
} catch (e: any) {
|
||||
return NextResponse.json({ error: e.message }, { status: 404 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ export default function ScreenshotGallery({
|
||||
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 (
|
||||
@@ -61,7 +61,20 @@ export default function ScreenshotGallery({
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{screenshots.map((screenshot, index) => {
|
||||
const filename = screenshot.split('/').pop() || ''
|
||||
const timeframe = timeframes[index] || 'Unknown'
|
||||
// Extract timeframe from filename (e.g., SOLUSD_5_ai_timestamp.png -> "5m")
|
||||
const extractTimeframeFromFilename = (filename: string) => {
|
||||
const match = filename.match(/_(\d+|D)_/)
|
||||
if (!match) return 'Unknown'
|
||||
const tf = match[1]
|
||||
if (tf === 'D') return '1D'
|
||||
if (tf === '5') return '5m'
|
||||
if (tf === '15') return '15m'
|
||||
if (tf === '60') return '1h'
|
||||
if (tf === '240') return '4h'
|
||||
return `${tf}m`
|
||||
}
|
||||
|
||||
const timeframe = timeframes[index] || extractTimeframeFromFilename(filename)
|
||||
const imageUrl = formatScreenshotUrl(screenshot)
|
||||
|
||||
return (
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 273 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 270 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 125 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 265 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 264 KiB |
124
test-gallery.html
Normal file
124
test-gallery.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Screenshot Gallery</title>
|
||||
<style>
|
||||
body {
|
||||
background: #111;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 20px;
|
||||
}
|
||||
.gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.screenshot {
|
||||
border: 1px solid #333;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
.screenshot img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
}
|
||||
.screenshot:hover {
|
||||
border-color: #666;
|
||||
}
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.8);
|
||||
z-index: 1000;
|
||||
}
|
||||
.modal img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Screenshot Gallery Test</h1>
|
||||
<p>Testing direct screenshot access:</p>
|
||||
|
||||
<div class="gallery">
|
||||
<div class="screenshot">
|
||||
<img src="/screenshots/SOLUSD_240_ai_1752447978639.png" alt="SOLUSD 4h">
|
||||
<div style="padding: 10px;">SOLUSD - 4h Timeframe</div>
|
||||
</div>
|
||||
<div class="screenshot">
|
||||
<img src="/screenshots/SOLUSD_15_ai_1752441315672.png" alt="SOLUSD 15m">
|
||||
<div style="padding: 10px;">SOLUSD - 15m Timeframe</div>
|
||||
</div>
|
||||
<div class="screenshot">
|
||||
<img src="/screenshots/SOLUSD_5_ai_1752441274081.png" alt="SOLUSD 5m">
|
||||
<div style="padding: 10px;">SOLUSD - 5m Timeframe</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal" class="modal">
|
||||
<span class="close">×</span>
|
||||
<img id="modalImg" src="" alt="">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const screenshots = document.querySelectorAll('.screenshot img');
|
||||
const modal = document.getElementById('modal');
|
||||
const modalImg = document.getElementById('modalImg');
|
||||
const close = document.querySelector('.close');
|
||||
|
||||
screenshots.forEach(img => {
|
||||
img.addEventListener('click', function() {
|
||||
modal.style.display = 'block';
|
||||
modalImg.src = this.src;
|
||||
console.log('Image clicked:', this.src);
|
||||
});
|
||||
|
||||
img.addEventListener('load', function() {
|
||||
console.log('Image loaded:', this.src);
|
||||
});
|
||||
|
||||
img.addEventListener('error', function() {
|
||||
console.error('Image failed to load:', this.src);
|
||||
this.style.border = '2px solid red';
|
||||
});
|
||||
});
|
||||
|
||||
close.addEventListener('click', function() {
|
||||
modal.style.display = 'none';
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
modal.addEventListener('click', function(e) {
|
||||
if (e.target === modal) {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user