import { NextRequest, NextResponse } from 'next/server'; import { writeFile, mkdir } from 'fs/promises'; import { existsSync } from 'fs'; import path from 'path'; import { prisma } from '@/lib/db'; import { verifyAdminAuth } from '@/lib/admin-auth'; const UPLOAD_DIR = path.join(process.cwd(), 'public', 'uploads'); const ALLOWED_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif']; const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB export async function POST(request: NextRequest) { try { const adminUser = await verifyAdminAuth(request); if (!adminUser) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const formData = await request.formData(); const file = formData.get('file') as File; const alt = formData.get('alt') as string; if (!file) { return NextResponse.json( { success: false, error: 'No file provided' }, { status: 400 } ); } if (!ALLOWED_TYPES.includes(file.type)) { return NextResponse.json( { success: false, error: 'Invalid file type. Only images are allowed.' }, { status: 400 } ); } if (file.size > MAX_FILE_SIZE) { return NextResponse.json( { success: false, error: 'File too large. Maximum size is 5MB.' }, { status: 400 } ); } // Ensure upload directory exists if (!existsSync(UPLOAD_DIR)) { await mkdir(UPLOAD_DIR, { recursive: true }); } // Generate unique filename const timestamp = Date.now(); const extension = path.extname(file.name); const baseFilename = file.name.replace(extension, '').replace(/[^a-zA-Z0-9]/g, '-'); const filename = `${timestamp}-${baseFilename}${extension}`; const filePath = path.join(UPLOAD_DIR, filename); // Write file to disk const bytes = await file.arrayBuffer(); const buffer = Buffer.from(bytes); await writeFile(filePath, buffer); // Save to database const mediaFile = await prisma.mediaFile.create({ data: { filename, originalName: file.name, mimeType: file.type, size: file.size, path: filePath, url: `/uploads/${filename}`, alt: alt || null, uploadedBy: adminUser.id } }); return NextResponse.json({ success: true, data: mediaFile }); } catch (error) { console.error('Error uploading file:', error); return NextResponse.json( { success: false, error: 'Failed to upload file' }, { status: 500 } ); } } export async function GET(request: NextRequest) { try { const adminUser = await verifyAdminAuth(request); if (!adminUser) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { searchParams } = new URL(request.url); const page = parseInt(searchParams.get('page') || '1'); const limit = parseInt(searchParams.get('limit') || '20'); const type = searchParams.get('type'); const skip = (page - 1) * limit; const where: any = {}; if (type) { where.mimeType = { startsWith: type }; } const [files, total] = await Promise.all([ prisma.mediaFile.findMany({ where, orderBy: { createdAt: 'desc' }, skip, take: limit, include: { uploader: { select: { name: true, email: true } } } }), prisma.mediaFile.count({ where }) ]); return NextResponse.json({ success: true, data: files, pagination: { page, limit, total, pages: Math.ceil(total / limit) } }); } catch (error) { console.error('Error fetching media files:', error); return NextResponse.json( { success: false, error: 'Failed to fetch media files' }, { status: 500 } ); } }