167 lines
4.6 KiB
TypeScript
167 lines
4.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { authMiddleware } from '@/lib/auth-middleware'
|
|
import { uploadFile, moveToPermStorage, getFileUrl, generateUniqueFilename } from '@/lib/file-vault'
|
|
|
|
// POST /api/topic-content-image - Upload images for topic content (rich text editor)
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
// Authentication required for image uploads
|
|
const user = await authMiddleware(request)
|
|
if (!user) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Authentication required', code: 'AUTH_REQUIRED' },
|
|
},
|
|
{ status: 401 }
|
|
)
|
|
}
|
|
|
|
const formData = await request.formData()
|
|
const image = formData.get('file') as File
|
|
|
|
if (!image) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Image file is required', code: 'MISSING_IMAGE' },
|
|
},
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
// Validate file type
|
|
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
|
|
if (!allowedTypes.includes(image.type)) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: {
|
|
message: 'Invalid file type. Only JPEG, PNG, GIF, and WebP are allowed',
|
|
code: 'INVALID_FILE_TYPE',
|
|
},
|
|
},
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
// Validate file size (5MB limit)
|
|
const maxSize = 5 * 1024 * 1024 // 5MB
|
|
if (image.size > maxSize) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: {
|
|
message: 'File size too large. Maximum size is 5MB',
|
|
code: 'FILE_TOO_LARGE',
|
|
},
|
|
},
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
console.log('Processing topic content image upload for user:', user.id)
|
|
|
|
try {
|
|
// Convert file to buffer (exactly like dev-portfolio)
|
|
const bytes = await image.arrayBuffer()
|
|
const buffer = Buffer.from(bytes)
|
|
|
|
// Upload directly to external API (no temp storage needed)
|
|
const uploadResult = await uploadFile(buffer, image.name, image.type, user.id)
|
|
const imageUrl = uploadResult.url
|
|
const uniqueFilename = uploadResult.filename
|
|
const permanentPath = uploadResult.url
|
|
|
|
console.log('Topic content image uploaded successfully:', {
|
|
originalName: image.name,
|
|
permanentPath,
|
|
uploadedBy: user.id,
|
|
})
|
|
|
|
// Return URL format expected by BlockNote editor
|
|
return NextResponse.json(
|
|
{
|
|
success: true,
|
|
data: {
|
|
url: imageUrl, // BlockNote expects URL here
|
|
fileName: uniqueFilename,
|
|
path: permanentPath,
|
|
size: image.size,
|
|
type: image.type,
|
|
uploadedBy: user.id,
|
|
uploadedAt: new Date().toISOString(),
|
|
},
|
|
},
|
|
{ status: 200 }
|
|
)
|
|
} catch (error) {
|
|
console.error('Failed to upload topic content image:', error)
|
|
throw error
|
|
}
|
|
} catch (error) {
|
|
console.error('Error uploading topic content image:', error)
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Failed to upload image', code: 'UPLOAD_ERROR' },
|
|
},
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|
|
|
|
// GET /api/topic-content-image - Get image metadata or URL by path (like dev-portfolio)
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
// Authentication required to access image metadata
|
|
const user = await authMiddleware(request)
|
|
if (!user) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Authentication required', code: 'AUTH_REQUIRED' },
|
|
},
|
|
{ status: 401 }
|
|
)
|
|
}
|
|
|
|
const { searchParams } = new URL(request.url)
|
|
const imagePath = searchParams.get('path')
|
|
|
|
if (!imagePath) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Image path parameter is required', code: 'MISSING_PATH' },
|
|
},
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
// Get accessible URL for the image (like dev-portfolio)
|
|
const imageUrl = await getFileUrl(imagePath)
|
|
|
|
return NextResponse.json(
|
|
{
|
|
success: true,
|
|
data: {
|
|
path: imagePath,
|
|
url: imageUrl,
|
|
},
|
|
},
|
|
{ status: 200 }
|
|
)
|
|
} catch (error) {
|
|
console.error('Error serving topic content image:', error)
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Failed to retrieve image', code: 'SERVER_ERROR' },
|
|
},
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|