refactor: add leveling view layer

Create leveling.view.ts with UI logic extracted from leaderboard command:
- getLeaderboardEmbed() for leaderboard display (XP and Balance)
- getMedalEmoji() helper for ranking medals (🥇🥈🥉)
- formatLeaderEntry() helper for entry formatting with null safety

Updated leaderboard.ts to use view functions instead of inline formatting.
This commit is contained in:
syntaxbullet
2025-12-24 22:09:04 +01:00
parent 7d6912cdee
commit 1523a392c2
2 changed files with 51 additions and 8 deletions

View File

@@ -0,0 +1,48 @@
import { EmbedBuilder } from "discord.js";
/**
* User data for leaderboard display
*/
interface LeaderboardUser {
username: string;
level: number | null;
xp: bigint | null;
balance: bigint | null;
}
/**
* Returns the appropriate medal emoji for a ranking position
*/
function getMedalEmoji(index: number): string {
if (index === 0) return "🥇";
if (index === 1) return "🥈";
if (index === 2) return "🥉";
return `${index + 1}.`;
}
/**
* Formats a single leaderboard entry based on type
*/
function formatLeaderEntry(user: LeaderboardUser, index: number, type: 'xp' | 'balance'): string {
const medal = getMedalEmoji(index);
const value = type === 'xp'
? `Lvl ${user.level ?? 1} (${user.xp ?? 0n} XP)`
: `${user.balance ?? 0n} 🪙`;
return `${medal} **${user.username}** — ${value}`;
}
/**
* Creates a leaderboard embed for either XP or Balance rankings
*/
export function getLeaderboardEmbed(leaders: LeaderboardUser[], type: 'xp' | 'balance'): EmbedBuilder {
const description = leaders.map((user, index) =>
formatLeaderEntry(user, index, type)
).join("\n");
const title = type === 'xp' ? "🏆 XP Leaderboard" : "💰 Richest Players";
return new EmbedBuilder()
.setTitle(title)
.setDescription(description)
.setColor(0xFFD700); // Gold
}