34 lines
1.4 KiB
JavaScript
34 lines
1.4 KiB
JavaScript
import { SlashCommandBuilder, EmbedBuilder } from 'discord.js';
|
|
import { withConn } from '../db/pool.js';
|
|
export const data = new SlashCommandBuilder()
|
|
.setName('leaderboard')
|
|
.setDescription('Show top users by XP');
|
|
export async function execute(interaction) {
|
|
if (!interaction.guildId)
|
|
return interaction.reply({ content: 'Guild only command.', ephemeral: true });
|
|
const rows = await withConn(async (conn) => {
|
|
return conn.query('SELECT user_id, xp FROM user_xp WHERE guild_id = ? ORDER BY xp DESC LIMIT 10', [interaction.guildId]);
|
|
});
|
|
const list = rows;
|
|
if (!list.length)
|
|
return interaction.reply('No XP data yet. Start chatting!');
|
|
const medals = ['🥇', '🥈', '🥉'];
|
|
const XP_PER_LEVEL = 500;
|
|
const desc = list
|
|
.map((r, i) => {
|
|
const rank = i + 1;
|
|
const level = Math.floor((r.xp || 0) / XP_PER_LEVEL);
|
|
const tag = `<@${r.user_id}>`;
|
|
const medal = medals[i] || `#${rank}`;
|
|
return `${medal} ${tag} — ${r.xp} XP (Lvl ${level})`;
|
|
})
|
|
.join('\n');
|
|
const embed = new EmbedBuilder()
|
|
.setTitle('Server Leaderboard')
|
|
.setColor(0xFEE75C)
|
|
.setDescription(desc)
|
|
.setFooter({ text: interaction.guild?.name || 'Leaderboard' })
|
|
.setTimestamp();
|
|
await interaction.reply({ embeds: [embed], allowedMentions: { parse: [] } });
|
|
}
|