Add profile link to Navigation component for user access, enhancing navigation options.

This commit is contained in:
Julien Froidefond
2025-12-09 12:46:29 +01:00
parent f732eb7385
commit 447ef9d076
7 changed files with 559 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
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) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
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 s'il n'existe pas
const uploadsDir = join(process.cwd(), "public", "uploads");
if (!existsSync(uploadsDir)) {
await mkdir(uploadsDir, { 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);
// 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/${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 }
);
}
}

122
app/api/profile/route.ts Normal file
View File

@@ -0,0 +1,122 @@
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
export async function GET() {
try {
const session = await auth();
if (!session?.user) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
const user = await prisma.user.findUnique({
where: { id: session.user.id },
select: {
id: true,
email: true,
username: true,
avatar: true,
hp: true,
maxHp: true,
xp: true,
maxXp: true,
level: true,
score: true,
createdAt: true,
},
});
if (!user) {
return NextResponse.json({ error: "Utilisateur non trouvé" }, { status: 404 });
}
return NextResponse.json(user);
} catch (error) {
console.error("Error fetching profile:", error);
return NextResponse.json(
{ error: "Erreur lors de la récupération du profil" },
{ status: 500 }
);
}
}
export async function PUT(request: Request) {
try {
const session = await auth();
if (!session?.user) {
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
}
const body = await request.json();
const { username, avatar } = body;
// Validation
if (username !== undefined) {
if (typeof username !== "string" || username.trim().length === 0) {
return NextResponse.json(
{ error: "Le nom d'utilisateur ne peut pas être vide" },
{ status: 400 }
);
}
if (username.length < 3 || username.length > 20) {
return NextResponse.json(
{ error: "Le nom d'utilisateur doit contenir entre 3 et 20 caractères" },
{ status: 400 }
);
}
// Vérifier si le username est déjà pris par un autre utilisateur
const existingUser = await prisma.user.findFirst({
where: {
username: username.trim(),
NOT: { id: session.user.id },
},
});
if (existingUser) {
return NextResponse.json(
{ error: "Ce nom d'utilisateur est déjà pris" },
{ status: 400 }
);
}
}
// Mettre à jour l'utilisateur
const updateData: { username?: string; avatar?: string | null } = {};
if (username !== undefined) {
updateData.username = username.trim();
}
if (avatar !== undefined) {
updateData.avatar = avatar || null;
}
const updatedUser = await prisma.user.update({
where: { id: session.user.id },
data: updateData,
select: {
id: true,
email: true,
username: true,
avatar: true,
hp: true,
maxHp: true,
xp: true,
maxXp: true,
level: true,
score: true,
},
});
return NextResponse.json(updatedUser);
} catch (error) {
console.error("Error updating profile:", error);
return NextResponse.json(
{ error: "Erreur lors de la mise à jour du profil" },
{ status: 500 }
);
}
}