109 lines
2.6 KiB
TypeScript
109 lines
2.6 KiB
TypeScript
import { Router, Request, Response, NextFunction } from 'express';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
|
|
const router = Router();
|
|
const prisma = new PrismaClient();
|
|
|
|
// Get all images for a recipe by recipe ID
|
|
router.get('/recipe/:recipeId', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { recipeId } = req.params;
|
|
|
|
if (!recipeId) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Recipe ID is required',
|
|
});
|
|
}
|
|
|
|
const images = await prisma.recipeImage.findMany({
|
|
where: { recipeId: parseInt(recipeId) },
|
|
orderBy: { id: 'asc' }
|
|
});
|
|
|
|
return res.json({
|
|
success: true,
|
|
data: images,
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
// Serve image file
|
|
router.get('/serve/:imagePath(*)', (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const imagePath = req.params.imagePath;
|
|
|
|
if (!imagePath) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Image path is required',
|
|
});
|
|
}
|
|
|
|
// Remove leading 'uploads/' if present to avoid duplication
|
|
const cleanPath = imagePath.replace(/^uploads\//, '');
|
|
const fullPath = path.join(process.cwd(), '../../uploads', cleanPath);
|
|
|
|
console.log(`Serving image: ${imagePath} -> ${fullPath}`);
|
|
|
|
if (!fs.existsSync(fullPath)) {
|
|
console.log(`Image not found: ${fullPath}`);
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'Image not found',
|
|
requestedPath: imagePath,
|
|
resolvedPath: fullPath
|
|
});
|
|
}
|
|
|
|
// Set CORS headers for images
|
|
res.set({
|
|
'Access-Control-Allow-Origin': 'http://localhost:5173',
|
|
'Access-Control-Allow-Credentials': 'true',
|
|
'Cache-Control': 'public, max-age=31536000', // Cache for 1 year
|
|
});
|
|
|
|
return res.sendFile(path.resolve(fullPath));
|
|
} catch (error) {
|
|
console.error('Error serving image:', error);
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
// Get image metadata
|
|
router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
if (!id) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Image ID is required',
|
|
});
|
|
}
|
|
|
|
const image = await prisma.recipeImage.findUnique({
|
|
where: { id: parseInt(id) }
|
|
});
|
|
|
|
if (!image) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'Image not found',
|
|
});
|
|
}
|
|
|
|
return res.json({
|
|
success: true,
|
|
data: image,
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
export default router; |