diff --git a/app/api/leaderboard/route.ts b/app/api/leaderboard/route.ts index a0dca1f..0cfd212 100644 --- a/app/api/leaderboard/route.ts +++ b/app/api/leaderboard/route.ts @@ -14,16 +14,30 @@ export async function GET() { score: true, level: true, avatar: true, + bio: true, }, }); - const leaderboard = users.map((user: { id: string; username: string; score: number; level: number; avatar: string | null }, index: number) => ({ - rank: index + 1, - username: user.username, - score: user.score, - level: user.level, - avatar: user.avatar, - })); + const leaderboard = users.map( + ( + user: { + id: string; + username: string; + score: number; + level: number; + avatar: string | null; + bio: string | null; + }, + index: number + ) => ({ + rank: index + 1, + username: user.username, + score: user.score, + level: user.level, + avatar: user.avatar, + bio: user.bio, + }) + ); return NextResponse.json(leaderboard); } catch (error) { @@ -34,4 +48,3 @@ export async function GET() { ); } } - diff --git a/app/api/profile/route.ts b/app/api/profile/route.ts index 630c141..a3953d9 100644 --- a/app/api/profile/route.ts +++ b/app/api/profile/route.ts @@ -17,6 +17,7 @@ export async function GET() { email: true, username: true, avatar: true, + bio: true, hp: true, maxHp: true, xp: true, @@ -50,7 +51,7 @@ export async function PUT(request: Request) { } const body = await request.json(); - const { username, avatar } = body; + const { username, avatar, bio } = body; // Validation if (username !== undefined) { @@ -84,14 +85,33 @@ export async function PUT(request: Request) { } } + // Validation bio + if (bio !== undefined) { + if (typeof bio !== "string") { + return NextResponse.json( + { error: "La bio doit être une chaîne de caractères" }, + { status: 400 } + ); + } + if (bio.length > 500) { + return NextResponse.json( + { error: "La bio ne peut pas dépasser 500 caractères" }, + { status: 400 } + ); + } + } + // Mettre à jour l'utilisateur - const updateData: { username?: string; avatar?: string | null } = {}; + const updateData: { username?: string; avatar?: string | null; bio?: string | null } = {}; if (username !== undefined) { updateData.username = username.trim(); } if (avatar !== undefined) { updateData.avatar = avatar || null; } + if (bio !== undefined) { + updateData.bio = bio.trim() || null; + } const updatedUser = await prisma.user.update({ where: { id: session.user.id }, @@ -101,6 +121,7 @@ export async function PUT(request: Request) { email: true, username: true, avatar: true, + bio: true, hp: true, maxHp: true, xp: true, diff --git a/app/leaderboard/page.tsx b/app/leaderboard/page.tsx index 07f623b..c7e5738 100644 --- a/app/leaderboard/page.tsx +++ b/app/leaderboard/page.tsx @@ -9,6 +9,7 @@ interface LeaderboardEntry { score: number; level: number; avatar: string | null; + bio: string | null; } export default async function LeaderboardPage() { @@ -23,6 +24,7 @@ export default async function LeaderboardPage() { score: true, level: true, avatar: true, + bio: true, }, }); @@ -32,6 +34,7 @@ export default async function LeaderboardPage() { score: user.score, level: user.level, avatar: user.avatar, + bio: user.bio, })); const backgroundImage = await getBackgroundImage( diff --git a/app/profile/page.tsx b/app/profile/page.tsx index eedbd92..d4e8568 100644 --- a/app/profile/page.tsx +++ b/app/profile/page.tsx @@ -19,6 +19,7 @@ export default async function ProfilePage() { email: true, username: true, avatar: true, + bio: true, hp: true, maxHp: true, xp: true, diff --git a/components/Leaderboard.tsx b/components/Leaderboard.tsx index 2c42007..f2d0ac7 100644 --- a/components/Leaderboard.tsx +++ b/components/Leaderboard.tsx @@ -8,6 +8,7 @@ interface LeaderboardEntry { score: number; level: number; avatar?: string | null; + bio?: string | null; } // Format number with consistent locale to avoid hydration mismatch @@ -48,7 +49,7 @@ export default function Leaderboard() { LEADERBOARD -
+
{/* Header */}
Rank
@@ -58,11 +59,11 @@ export default function Leaderboard() {
{/* Entries */} -
+
{leaderboard.map((entry) => (
@@ -81,10 +82,20 @@ export default function Leaderboard() { {entry.rank}
-
- +
+ {entry.username} + {entry.bio && ( +
+
+ Bio +
+

+ {entry.bio} +

+
+ )}
diff --git a/components/LeaderboardSection.tsx b/components/LeaderboardSection.tsx index 5a13d79..fe56505 100644 --- a/components/LeaderboardSection.tsx +++ b/components/LeaderboardSection.tsx @@ -6,6 +6,7 @@ interface LeaderboardEntry { score: number; level: number; avatar?: string | null; + bio?: string | null; } interface LeaderboardSectionProps { @@ -23,7 +24,7 @@ export default function LeaderboardSection({ backgroundImage, }: LeaderboardSectionProps) { return ( -
+
{/* Background Image */}
{/* Leaderboard Table */} -
+
{/* Header */}
Rank
@@ -67,11 +68,11 @@ export default function LeaderboardSection({
{/* Entries */} -
+
{leaderboard.map((entry) => (
{/* Player */} -
+
{entry.avatar ? (
)} @@ -121,6 +122,16 @@ export default function LeaderboardSection({ {entry.rank <= 3 && ( )} + {entry.bio && ( +
+
+ Bio +
+

+ {entry.bio} +

+
+ )}
{/* Score */} diff --git a/components/ProfileForm.tsx b/components/ProfileForm.tsx index 2c2d224..c4cf255 100644 --- a/components/ProfileForm.tsx +++ b/components/ProfileForm.tsx @@ -8,6 +8,7 @@ interface UserProfile { email: string; username: string; avatar: string | null; + bio: string | null; hp: number; maxHp: number; xp: number; @@ -38,6 +39,7 @@ export default function ProfileForm({ const [username, setUsername] = useState(initialProfile.username); const [avatar, setAvatar] = useState(initialProfile.avatar); + const [bio, setBio] = useState(initialProfile.bio || null); const fileInputRef = useRef(null); const [uploadingAvatar, setUploadingAvatar] = useState(false); @@ -99,12 +101,14 @@ export default function ProfileForm({ body: JSON.stringify({ username, avatar, + bio, }), }); if (response.ok) { const data = await response.json(); setProfile(data); + setBio(data.bio || null); setSuccess("Profil mis à jour avec succès"); setTimeout(() => setSuccess(null), 3000); } else { @@ -316,6 +320,24 @@ export default function ProfileForm({

3-20 caractères

+ {/* Bio Field */} +
+ +