53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
|
|
import { NextRequest, NextResponse } from 'next/server';
|
||
|
|
import { writeFile, mkdir } from 'fs/promises';
|
||
|
|
import path from 'path';
|
||
|
|
import { authenticateToken, AuthenticatedRequest } from '@/lib/middleware';
|
||
|
|
|
||
|
|
// Helper to ensure directory exists
|
||
|
|
async function ensureDir(dirPath: string) {
|
||
|
|
try {
|
||
|
|
await mkdir(dirPath, { recursive: true });
|
||
|
|
} catch (error) {
|
||
|
|
// Ignore if exists
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handler(req: AuthenticatedRequest) {
|
||
|
|
if (req.user?.role !== 'admin') {
|
||
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 403 });
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const formData = await req.formData();
|
||
|
|
const files = formData.getAll('file') as File[];
|
||
|
|
|
||
|
|
if (!files || files.length === 0) {
|
||
|
|
return NextResponse.json({ error: 'No files uploaded' }, { status: 400 });
|
||
|
|
}
|
||
|
|
|
||
|
|
const uploadDir = path.join(process.cwd(), 'public', 'uploads', 'products');
|
||
|
|
await ensureDir(uploadDir);
|
||
|
|
|
||
|
|
const uploadedUrls: string[] = [];
|
||
|
|
|
||
|
|
for (const file of files) {
|
||
|
|
const buffer = Buffer.from(await file.arrayBuffer());
|
||
|
|
// Create unique filename
|
||
|
|
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
||
|
|
const ext = path.extname(file.name) || '.jpg';
|
||
|
|
const filename = `product-${uniqueSuffix}${ext}`;
|
||
|
|
const filepath = path.join(uploadDir, filename);
|
||
|
|
|
||
|
|
await writeFile(filepath, buffer);
|
||
|
|
uploadedUrls.push(`/uploads/products/${filename}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
return NextResponse.json({ urls: uploadedUrls });
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Upload error:', error);
|
||
|
|
return NextResponse.json({ error: 'Upload failed' }, { status: 500 });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export const POST = authenticateToken(handler);
|