diff --git a/app/api/leaderboard/route.ts b/app/api/leaderboard/route.ts
index 538e929..4797739 100644
--- a/app/api/leaderboard/route.ts
+++ b/app/api/leaderboard/route.ts
@@ -11,6 +11,7 @@ export async function GET() {
select: {
id: true,
username: true,
+ email: true,
score: true,
level: true,
avatar: true,
@@ -24,6 +25,7 @@ export async function GET() {
user: {
id: string;
username: string;
+ email: string;
score: number;
level: number;
avatar: string | null;
@@ -34,6 +36,7 @@ export async function GET() {
) => ({
rank: index + 1,
username: user.username,
+ email: user.email,
score: user.score,
level: user.level,
avatar: user.avatar,
diff --git a/app/leaderboard/page.tsx b/app/leaderboard/page.tsx
index fbe42d3..80e55cb 100644
--- a/app/leaderboard/page.tsx
+++ b/app/leaderboard/page.tsx
@@ -6,6 +6,7 @@ import { getBackgroundImage } from "@/lib/preferences";
interface LeaderboardEntry {
rank: number;
username: string;
+ email: string;
score: number;
level: number;
avatar: string | null;
@@ -22,6 +23,7 @@ export default async function LeaderboardPage() {
select: {
id: true,
username: true,
+ email: true,
score: true,
level: true,
avatar: true,
@@ -33,6 +35,7 @@ export default async function LeaderboardPage() {
const leaderboard: LeaderboardEntry[] = users.map((user, index) => ({
rank: index + 1,
username: user.username,
+ email: user.email,
score: user.score,
level: user.level,
avatar: user.avatar,
diff --git a/components/Leaderboard.tsx b/components/Leaderboard.tsx
index 8680090..97a75ec 100644
--- a/components/Leaderboard.tsx
+++ b/components/Leaderboard.tsx
@@ -5,6 +5,7 @@ import { useEffect, useState } from "react";
interface LeaderboardEntry {
rank: number;
username: string;
+ email: string;
score: number;
level: number;
avatar?: string | null;
@@ -20,6 +21,9 @@ const formatScore = (score: number): string => {
export default function Leaderboard() {
const [leaderboard, setLeaderboard] = useState([]);
const [loading, setLoading] = useState(true);
+ const [selectedEntry, setSelectedEntry] = useState(
+ null
+ );
useEffect(() => {
fetch("/api/leaderboard")
@@ -83,82 +87,31 @@ export default function Leaderboard() {
{entry.rank}
-
-
- {entry.username}
-
- {entry.characterClass && (
-
- [{entry.characterClass === "WARRIOR" && "⚔️ Guerrier"}
- {entry.characterClass === "MAGE" && "🔮 Mage"}
- {entry.characterClass === "ROGUE" && "🗡️ Voleur"}
- {entry.characterClass === "RANGER" && "🏹 Rôdeur"}
- {entry.characterClass === "PALADIN" && "🛡️ Paladin"}
- {entry.characterClass === "ENGINEER" && "⚙️ Ingénieur"}
- {entry.characterClass === "MERCHANT" && "💰 Marchand"}
- {entry.characterClass === "SCHOLAR" && "📚 Érudit"}
- {entry.characterClass === "BERSERKER" && "🔥 Berserker"}
- {entry.characterClass === "NECROMANCER" &&
- "💀 Nécromancien"}
- ]
+
+
setSelectedEntry(entry)}
+ >
+
+ {entry.username}
- )}
- {(entry.bio || entry.characterClass) && (
-
- {entry.characterClass && (
-
-
- Classe
-
-
-
- {entry.characterClass === "WARRIOR" && "⚔️"}
- {entry.characterClass === "MAGE" && "🔮"}
- {entry.characterClass === "ROGUE" && "🗡️"}
- {entry.characterClass === "RANGER" && "🏹"}
- {entry.characterClass === "PALADIN" && "🛡️"}
- {entry.characterClass === "ENGINEER" && "⚙️"}
- {entry.characterClass === "MERCHANT" && "💰"}
- {entry.characterClass === "SCHOLAR" && "📚"}
- {entry.characterClass === "BERSERKER" && "🔥"}
- {entry.characterClass === "NECROMANCER" && "💀"}
-
-
- {entry.characterClass === "WARRIOR" && "Guerrier"}
- {entry.characterClass === "MAGE" && "Mage"}
- {entry.characterClass === "ROGUE" && "Voleur"}
- {entry.characterClass === "RANGER" && "Rôdeur"}
- {entry.characterClass === "PALADIN" && "Paladin"}
- {entry.characterClass === "ENGINEER" &&
- "Ingénieur"}
- {entry.characterClass === "MERCHANT" &&
- "Marchand"}
- {entry.characterClass === "SCHOLAR" && "Érudit"}
- {entry.characterClass === "BERSERKER" &&
- "Berserker"}
- {entry.characterClass === "NECROMANCER" &&
- "Nécromancien"}
-
-
-
- )}
- {entry.bio && (
- <>
- {entry.characterClass && (
-
- )}
-
-
- Bio
-
-
- {entry.bio}
-
-
- >
- )}
-
- )}
+ {entry.characterClass && (
+
+ [{entry.characterClass === "WARRIOR" && "⚔️ Guerrier"}
+ {entry.characterClass === "MAGE" && "🔮 Mage"}
+ {entry.characterClass === "ROGUE" && "🗡️ Voleur"}
+ {entry.characterClass === "RANGER" && "🏹 Rôdeur"}
+ {entry.characterClass === "PALADIN" && "🛡️ Paladin"}
+ {entry.characterClass === "ENGINEER" && "⚙️ Ingénieur"}
+ {entry.characterClass === "MERCHANT" && "💰 Marchand"}
+ {entry.characterClass === "SCHOLAR" && "📚 Érudit"}
+ {entry.characterClass === "BERSERKER" && "🔥 Berserker"}
+ {entry.characterClass === "NECROMANCER" &&
+ "💀 Nécromancien"}
+ ]
+
+ )}
+
@@ -180,6 +133,127 @@ export default function Leaderboard() {
Compete with players worldwide and climb the ranks!
+
+ {/* Character Modal */}
+ {selectedEntry && (
+ setSelectedEntry(null)}
+ >
+
e.stopPropagation()}
+ >
+
+ {/* Header */}
+
+
+ {selectedEntry.username}
+
+
+
+
+ {/* Avatar and Class */}
+
+ {selectedEntry.avatar ? (
+
+

+
+ ) : (
+
+
+ {selectedEntry.username.charAt(0).toUpperCase()}
+
+
+ )}
+
+
+ Rank #{selectedEntry.rank}
+
+
+ {selectedEntry.email}
+
+ {selectedEntry.characterClass && (
+
+
+ {selectedEntry.characterClass === "WARRIOR" && "⚔️"}
+ {selectedEntry.characterClass === "MAGE" && "🔮"}
+ {selectedEntry.characterClass === "ROGUE" && "🗡️"}
+ {selectedEntry.characterClass === "RANGER" && "🏹"}
+ {selectedEntry.characterClass === "PALADIN" && "🛡️"}
+ {selectedEntry.characterClass === "ENGINEER" && "⚙️"}
+ {selectedEntry.characterClass === "MERCHANT" && "💰"}
+ {selectedEntry.characterClass === "SCHOLAR" && "📚"}
+ {selectedEntry.characterClass === "BERSERKER" && "🔥"}
+ {selectedEntry.characterClass === "NECROMANCER" && "💀"}
+
+
+ {selectedEntry.characterClass === "WARRIOR" &&
+ "Guerrier"}
+ {selectedEntry.characterClass === "MAGE" && "Mage"}
+ {selectedEntry.characterClass === "ROGUE" && "Voleur"}
+ {selectedEntry.characterClass === "RANGER" && "Rôdeur"}
+ {selectedEntry.characterClass === "PALADIN" &&
+ "Paladin"}
+ {selectedEntry.characterClass === "ENGINEER" &&
+ "Ingénieur"}
+ {selectedEntry.characterClass === "MERCHANT" &&
+ "Marchand"}
+ {selectedEntry.characterClass === "SCHOLAR" && "Érudit"}
+ {selectedEntry.characterClass === "BERSERKER" &&
+ "Berserker"}
+ {selectedEntry.characterClass === "NECROMANCER" &&
+ "Nécromancien"}
+
+
+ )}
+
+
+
+ {/* Stats */}
+
+
+
+ Score
+
+
+ {formatScore(selectedEntry.score)}
+
+
+
+
+ Niveau
+
+
+ Lv.{selectedEntry.level}
+
+
+
+
+ {/* Bio */}
+ {selectedEntry.bio && (
+
+
+ Bio
+
+
+ {selectedEntry.bio}
+
+
+ )}
+
+
+
+ )}
);
}
diff --git a/components/LeaderboardSection.tsx b/components/LeaderboardSection.tsx
index 52bc934..cff9934 100644
--- a/components/LeaderboardSection.tsx
+++ b/components/LeaderboardSection.tsx
@@ -1,8 +1,11 @@
"use client";
+import { useState } from "react";
+
interface LeaderboardEntry {
rank: number;
username: string;
+ email: string;
score: number;
level: number;
avatar?: string | null;
@@ -24,6 +27,10 @@ export default function LeaderboardSection({
leaderboard,
backgroundImage,
}: LeaderboardSectionProps) {
+ const [selectedEntry, setSelectedEntry] = useState(
+ null
+ );
+
return (
{/* Background Image */}
@@ -97,7 +104,7 @@ export default function LeaderboardSection({
{/* Player */}
-
+
{entry.avatar ? (
)}
-
setSelectedEntry(entry)}
>
- {entry.username}
-
- {entry.characterClass && (
-
- [{entry.characterClass === "WARRIOR" && "⚔️"}
- {entry.characterClass === "MAGE" && "🔮"}
- {entry.characterClass === "ROGUE" && "🗡️"}
- {entry.characterClass === "RANGER" && "🏹"}
- {entry.characterClass === "PALADIN" && "🛡️"}
- {entry.characterClass === "ENGINEER" && "⚙️"}
- {entry.characterClass === "MERCHANT" && "💰"}
- {entry.characterClass === "SCHOLAR" && "📚"}
- {entry.characterClass === "BERSERKER" && "🔥"}
- {entry.characterClass === "NECROMANCER" && "💀"}]
+
+ {entry.username}
- )}
- {entry.rank <= 3 && (
- ✦
- )}
- {(entry.bio || entry.characterClass) && (
-
- {entry.characterClass && (
-
-
- Classe
-
-
-
- {entry.characterClass === "WARRIOR" && "⚔️"}
- {entry.characterClass === "MAGE" && "🔮"}
- {entry.characterClass === "ROGUE" && "🗡️"}
- {entry.characterClass === "RANGER" && "🏹"}
- {entry.characterClass === "PALADIN" && "🛡️"}
- {entry.characterClass === "ENGINEER" && "⚙️"}
- {entry.characterClass === "MERCHANT" && "💰"}
- {entry.characterClass === "SCHOLAR" && "📚"}
- {entry.characterClass === "BERSERKER" && "🔥"}
- {entry.characterClass === "NECROMANCER" && "💀"}
-
-
- {entry.characterClass === "WARRIOR" && "Guerrier"}
- {entry.characterClass === "MAGE" && "Mage"}
- {entry.characterClass === "ROGUE" && "Voleur"}
- {entry.characterClass === "RANGER" && "Rôdeur"}
- {entry.characterClass === "PALADIN" && "Paladin"}
- {entry.characterClass === "ENGINEER" &&
- "Ingénieur"}
- {entry.characterClass === "MERCHANT" &&
- "Marchand"}
- {entry.characterClass === "SCHOLAR" && "Érudit"}
- {entry.characterClass === "BERSERKER" &&
- "Berserker"}
- {entry.characterClass === "NECROMANCER" &&
- "Nécromancien"}
-
-
-
- )}
- {entry.bio && (
- <>
- {entry.characterClass && (
-
- )}
-
-
- Bio
-
-
- {entry.bio}
-
-
- >
- )}
-
- )}
+ {entry.characterClass && (
+
+ [{entry.characterClass === "WARRIOR" && "⚔️"}
+ {entry.characterClass === "MAGE" && "🔮"}
+ {entry.characterClass === "ROGUE" && "🗡️"}
+ {entry.characterClass === "RANGER" && "🏹"}
+ {entry.characterClass === "PALADIN" && "🛡️"}
+ {entry.characterClass === "ENGINEER" && "⚙️"}
+ {entry.characterClass === "MERCHANT" && "💰"}
+ {entry.characterClass === "SCHOLAR" && "📚"}
+ {entry.characterClass === "BERSERKER" && "🔥"}
+ {entry.characterClass === "NECROMANCER" && "💀"}]
+
+ )}
+ {entry.rank <= 3 && (
+ ✦
+ )}
+
{/* Score */}
@@ -223,6 +179,127 @@ export default function LeaderboardSection({
+
+ {/* Character Modal */}
+ {selectedEntry && (
+ setSelectedEntry(null)}
+ >
+
e.stopPropagation()}
+ >
+
+ {/* Header */}
+
+
+ {selectedEntry.username}
+
+
+
+
+ {/* Avatar and Class */}
+
+ {selectedEntry.avatar ? (
+
+

+
+ ) : (
+
+
+ {selectedEntry.username.charAt(0).toUpperCase()}
+
+
+ )}
+
+
+ Rank #{selectedEntry.rank}
+
+
+ {selectedEntry.email}
+
+ {selectedEntry.characterClass && (
+
+
+ {selectedEntry.characterClass === "WARRIOR" && "⚔️"}
+ {selectedEntry.characterClass === "MAGE" && "🔮"}
+ {selectedEntry.characterClass === "ROGUE" && "🗡️"}
+ {selectedEntry.characterClass === "RANGER" && "🏹"}
+ {selectedEntry.characterClass === "PALADIN" && "🛡️"}
+ {selectedEntry.characterClass === "ENGINEER" && "⚙️"}
+ {selectedEntry.characterClass === "MERCHANT" && "💰"}
+ {selectedEntry.characterClass === "SCHOLAR" && "📚"}
+ {selectedEntry.characterClass === "BERSERKER" && "🔥"}
+ {selectedEntry.characterClass === "NECROMANCER" && "💀"}
+
+
+ {selectedEntry.characterClass === "WARRIOR" &&
+ "Guerrier"}
+ {selectedEntry.characterClass === "MAGE" && "Mage"}
+ {selectedEntry.characterClass === "ROGUE" && "Voleur"}
+ {selectedEntry.characterClass === "RANGER" && "Rôdeur"}
+ {selectedEntry.characterClass === "PALADIN" &&
+ "Paladin"}
+ {selectedEntry.characterClass === "ENGINEER" &&
+ "Ingénieur"}
+ {selectedEntry.characterClass === "MERCHANT" &&
+ "Marchand"}
+ {selectedEntry.characterClass === "SCHOLAR" && "Érudit"}
+ {selectedEntry.characterClass === "BERSERKER" &&
+ "Berserker"}
+ {selectedEntry.characterClass === "NECROMANCER" &&
+ "Nécromancien"}
+
+
+ )}
+
+
+
+ {/* Stats */}
+
+
+
+ Score
+
+
+ {formatScore(selectedEntry.score)}
+
+
+
+
+ Niveau
+
+
+ Lv.{selectedEntry.level}
+
+
+
+
+ {/* Bio */}
+ {selectedEntry.bio && (
+
+
+ Bio
+
+
+ {selectedEntry.bio}
+
+
+ )}
+
+
+
+ )}
);
}