Enhance user profiles with character class feature: Add character class field to user model and update related API routes, UI components, and validation logic. This update improves user profile customization and leaderboard entries by allowing users to select and display their character class.

This commit is contained in:
Julien Froidefond
2025-12-09 22:03:51 +01:00
parent 3a0dd57bb6
commit b245be3bf4
17 changed files with 438 additions and 25 deletions

View File

@@ -9,6 +9,7 @@ interface LeaderboardEntry {
level: number;
avatar?: string | null;
bio?: string | null;
characterClass?: string | null;
}
// Format number with consistent locale to avoid hydration mismatch
@@ -82,18 +83,80 @@ export default function Leaderboard() {
{entry.rank}
</span>
</div>
<div className="col-span-5 flex items-center relative group">
<div className="col-span-5 flex items-center gap-2 relative group">
<span className="font-bold text-pixel-gold cursor-pointer relative z-10">
{entry.username}
</span>
{entry.bio && (
{entry.characterClass && (
<span className="text-xs text-gray-400 uppercase tracking-wider">
[{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"}
]
</span>
)}
{(entry.bio || entry.characterClass) && (
<div className="absolute left-0 top-full mt-1 z-[100] w-72 p-4 bg-black border-2 border-pixel-gold/70 rounded-lg shadow-2xl opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 pointer-events-none">
<div className="text-xs text-pixel-gold uppercase tracking-widest mb-2 border-b border-pixel-gold/30 pb-1 font-bold">
Bio
</div>
<p className="text-sm text-gray-200 leading-relaxed whitespace-pre-wrap break-words">
{entry.bio}
</p>
{entry.characterClass && (
<div className="mb-3">
<div className="text-xs text-pixel-gold uppercase tracking-widest mb-1 font-bold">
Classe
</div>
<div className="text-sm text-gray-200 flex items-center gap-2">
<span>
{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" && "💀"}
</span>
<span className="uppercase tracking-wider">
{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"}
</span>
</div>
</div>
)}
{entry.bio && (
<>
{entry.characterClass && (
<div className="border-b border-pixel-gold/30 mb-3 pb-3"></div>
)}
<div>
<div className="text-xs text-pixel-gold uppercase tracking-widest mb-2 border-b border-pixel-gold/30 pb-1 font-bold">
Bio
</div>
<p className="text-sm text-gray-200 leading-relaxed whitespace-pre-wrap break-words">
{entry.bio}
</p>
</div>
</>
)}
</div>
)}
</div>