52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import { createCommand } from "@/lib/utils";
|
|
import { SlashCommandBuilder, EmbedBuilder } from "discord.js";
|
|
import { DrizzleClient } from "@/lib/DrizzleClient";
|
|
import { users } from "@/db/schema";
|
|
import { desc } from "drizzle-orm";
|
|
import { createWarningEmbed } from "@lib/embeds";
|
|
|
|
export const leaderboard = createCommand({
|
|
data: new SlashCommandBuilder()
|
|
.setName("leaderboard")
|
|
.setDescription("View the top players")
|
|
.addStringOption(option =>
|
|
option.setName("type")
|
|
.setDescription("Sort by XP or Balance")
|
|
.setRequired(true)
|
|
.addChoices(
|
|
{ name: "Level / XP", value: "xp" },
|
|
{ name: "Balance", value: "balance" }
|
|
)
|
|
),
|
|
execute: async (interaction) => {
|
|
await interaction.deferReply();
|
|
|
|
const type = interaction.options.getString("type", true);
|
|
const isXp = type === "xp";
|
|
|
|
const leaders = await DrizzleClient.query.users.findMany({
|
|
orderBy: isXp ? desc(users.xp) : desc(users.balance),
|
|
limit: 10
|
|
});
|
|
|
|
if (leaders.length === 0) {
|
|
await interaction.editReply({ embeds: [createWarningEmbed("No users found.", "Leaderboard")] });
|
|
return;
|
|
}
|
|
|
|
const description = leaders.map((user, index) => {
|
|
const medal = index === 0 ? "🥇" : index === 1 ? "🥈" : index === 2 ? "🥉" : `${index + 1}.`;
|
|
const value = isXp ? `Lvl ${user.level} (${user.xp} XP)` : `${user.balance} 🪙`;
|
|
return `${medal} **${user.username}** — ${value}`;
|
|
}).join("\n");
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTitle(isXp ? "🏆 XP Leaderboard" : "💰 Richest Players")
|
|
.setDescription(description)
|
|
.setColor("Gold")
|
|
.setTimestamp();
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
});
|