From fdca926468a7e5cd7d7cf43f076d59608fe8d333 Mon Sep 17 00:00:00 2001 From: muken Date: Sun, 28 Jun 2026 13:37:55 -0500 Subject: [PATCH] feat: add image serving endpoint for rooms gallery --- src/app/api/images/[id]/route.ts | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/app/api/images/[id]/route.ts diff --git a/src/app/api/images/[id]/route.ts b/src/app/api/images/[id]/route.ts new file mode 100644 index 0000000..c2a5286 --- /dev/null +++ b/src/app/api/images/[id]/route.ts @@ -0,0 +1,42 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { db } from '@/lib/db'; + +export async function GET(request: NextRequest, { params }: { params: { id: string } }) { + try { + const id = parseInt(params.id, 10); + if (isNaN(id)) { + return NextResponse.json({ error: 'Invalid image ID' }, { status: 400 }); + } + + const { rows } = await db.query( + 'SELECT filename, data, category FROM images WHERE id = $1', + [id] + ); + + if (rows.length === 0) { + return NextResponse.json({ error: 'Image not found' }, { status: 404 }); + } + + const image = rows[0]; + const buffer = Buffer.from(image.data); + const contentType = getContentType(image.category, image.filename); + + return new NextResponse(buffer, { + status: 200, + headers: { + 'Content-Type': contentType, + 'Cache-Control': 'public, max-age=86400', + }, + }); + } catch (err: any) { + return NextResponse.json({ error: err.message || 'Failed to fetch image' }, { status: 500 }); + } +} + +function getContentType(category: string, filename: string): string { + if (category === 'photo') return 'image/jpeg'; + if (category === 'slide') return 'image/webp'; + if (filename.endsWith('.png')) return 'image/png'; + if (filename.endsWith('.webp')) return 'image/webp'; + return 'image/jpeg'; +}