diff --git a/app/api/admin/avatars/upload/route.ts b/app/api/admin/avatars/upload/route.ts new file mode 100644 index 0000000..5e50558 --- /dev/null +++ b/app/api/admin/avatars/upload/route.ts @@ -0,0 +1,70 @@ +import { NextResponse } from "next/server"; +import { auth } from "@/lib/auth"; +import { Role } from "@/prisma/generated/prisma/client"; +import { writeFile, mkdir } from "fs/promises"; +import { join } from "path"; +import { existsSync } from "fs"; + +export async function POST(request: Request) { + try { + const session = await auth(); + + if (!session?.user || session.user.role !== Role.ADMIN) { + return NextResponse.json({ error: "Accès refusé" }, { status: 403 }); + } + + const formData = await request.formData(); + const file = formData.get("file") as File; + + if (!file) { + return NextResponse.json( + { error: "Aucun fichier fourni" }, + { status: 400 } + ); + } + + // Vérifier le type de fichier + if (!file.type.startsWith("image/")) { + return NextResponse.json( + { error: "Le fichier doit être une image" }, + { status: 400 } + ); + } + + // Limiter la taille (par exemple 5MB) + const maxSize = 5 * 1024 * 1024; // 5MB + if (file.size > maxSize) { + return NextResponse.json( + { error: "L'image est trop grande (max 5MB)" }, + { status: 400 } + ); + } + + // Créer le dossier uploads/avatars s'il n'existe pas + const uploadsDir = join(process.cwd(), "public", "uploads"); + const avatarsDir = join(uploadsDir, "avatars"); + if (!existsSync(avatarsDir)) { + await mkdir(avatarsDir, { recursive: true }); + } + + // Générer un nom de fichier unique + const timestamp = Date.now(); + const filename = `avatar-admin-${timestamp}-${file.name}`; + const filepath = join(avatarsDir, filename); + + // Convertir le fichier en buffer et l'écrire + const bytes = await file.arrayBuffer(); + const buffer = Buffer.from(bytes); + await writeFile(filepath, buffer); + + // Retourner l'URL de l'image + const imageUrl = `/uploads/avatars/${filename}`; + return NextResponse.json({ url: imageUrl }); + } catch (error) { + console.error("Error uploading avatar:", error); + return NextResponse.json( + { error: "Erreur lors de l'upload de l'avatar" }, + { status: 500 } + ); + } +} diff --git a/app/api/profile/avatar/route.ts b/app/api/profile/avatar/route.ts index ab9eb97..f93a199 100644 --- a/app/api/profile/avatar/route.ts +++ b/app/api/profile/avatar/route.ts @@ -39,16 +39,17 @@ export async function POST(request: Request) { ); } - // Créer le dossier uploads s'il n'existe pas + // Créer le dossier uploads/avatars s'il n'existe pas const uploadsDir = join(process.cwd(), "public", "uploads"); - if (!existsSync(uploadsDir)) { - await mkdir(uploadsDir, { recursive: true }); + const avatarsDir = join(uploadsDir, "avatars"); + if (!existsSync(avatarsDir)) { + await mkdir(avatarsDir, { recursive: true }); } // Générer un nom de fichier unique avec l'ID utilisateur const timestamp = Date.now(); const filename = `avatar-${session.user.id}-${timestamp}-${file.name}`; - const filepath = join(uploadsDir, filename); + const filepath = join(avatarsDir, filename); // Convertir le fichier en buffer et l'écrire const bytes = await file.arrayBuffer(); @@ -56,7 +57,7 @@ export async function POST(request: Request) { await writeFile(filepath, buffer); // Retourner l'URL de l'image - const imageUrl = `/uploads/${filename}`; + const imageUrl = `/uploads/avatars/${filename}`; return NextResponse.json({ url: imageUrl }); } catch (error) { console.error("Error uploading avatar:", error); diff --git a/app/api/register/avatar/route.ts b/app/api/register/avatar/route.ts index 4dcbbe6..f5cd247 100644 --- a/app/api/register/avatar/route.ts +++ b/app/api/register/avatar/route.ts @@ -32,17 +32,18 @@ export async function POST(request: Request) { ); } - // Créer le dossier uploads s'il n'existe pas + // Créer le dossier uploads/avatars s'il n'existe pas const uploadsDir = join(process.cwd(), "public", "uploads"); - if (!existsSync(uploadsDir)) { - await mkdir(uploadsDir, { recursive: true }); + const avatarsDir = join(uploadsDir, "avatars"); + if (!existsSync(avatarsDir)) { + await mkdir(avatarsDir, { recursive: true }); } // Générer un nom de fichier unique avec timestamp const timestamp = Date.now(); const randomId = Math.random().toString(36).substring(2, 9); const filename = `avatar-register-${timestamp}-${randomId}-${file.name}`; - const filepath = join(uploadsDir, filename); + const filepath = join(avatarsDir, filename); // Convertir le fichier en buffer et l'écrire const bytes = await file.arrayBuffer(); @@ -50,7 +51,7 @@ export async function POST(request: Request) { await writeFile(filepath, buffer); // Retourner l'URL de l'image - const imageUrl = `/uploads/${filename}`; + const imageUrl = `/uploads/avatars/${filename}`; return NextResponse.json({ url: imageUrl }); } catch (error) { console.error("Error uploading avatar:", error); diff --git a/components/UserManagement.tsx b/components/UserManagement.tsx index 2cde8f0..fef1aec 100644 --- a/components/UserManagement.tsx +++ b/components/UserManagement.tsx @@ -349,7 +349,7 @@ export default function UserManagement() { formData.append("file", file); const response = await fetch( - "/api/admin/images/upload", + "/api/admin/avatars/upload", { method: "POST", body: formData,