Initial commit

This commit is contained in:
OptimiDev
2025-10-20 16:30:50 +02:00
commit c2e9af0a8a
43 changed files with 3035 additions and 0 deletions

68
dist/commands/profile.js vendored Normal file
View File

@@ -0,0 +1,68 @@
import { SlashCommandBuilder, EmbedBuilder } from 'discord.js';
import { withConn } from '../db/pool.js';
export const data = new SlashCommandBuilder()
.setName('profile')
.setDescription('Show XP profile')
.addUserOption(o =>
o.setName('user').setDescription('User to view')
);
export async function execute(interaction) {
if (!interaction.guildId)
return interaction.reply({
content: 'Guild only command.',
ephemeral: true,
});
const target = interaction.options.getUser('user') || interaction.user;
const data = await withConn(async conn => {
const rows = await conn.query(
'SELECT xp FROM user_xp WHERE guild_id = ? AND user_id = ? LIMIT 1',
[BigInt(interaction.guildId), BigInt(target.id)]
);
const xp = Number(rows[0]?.xp ?? 0);
const rankRows = await conn.query(
'SELECT COUNT(*) AS ahead FROM user_xp WHERE guild_id = ? AND xp > ?',
[BigInt(interaction.guildId), xp]
);
const rank = Number(rankRows[0]?.ahead ?? 0) + 1;
return { xp, rank };
});
const XP_PER_LEVEL = 500; // match visual example
const level = Math.floor(data.xp / XP_PER_LEVEL);
const currentLevelXp = data.xp % XP_PER_LEVEL;
const progress = Math.min(
100,
Math.round((currentLevelXp / XP_PER_LEVEL) * 1000) / 10
);
const embed = new EmbedBuilder()
.setAuthor({
name: `${target.username}'s Profile`,
iconURL: target.displayAvatarURL(),
})
.setColor(0x5865f2)
.setDescription(`Progress to next level: **${progress}%**`)
.addFields(
{ name: '🏅 Level', value: `${level}`, inline: true },
{ name: '💎 XP', value: `${currentLevelXp} / ${XP_PER_LEVEL}`, inline: true },
{ name: '🏆 Rank', value: `#${data.rank}`, inline: true }
)
.setFooter({
text: `Server: ${interaction.guild?.name || 'Unknown'}`,
})
.setTimestamp();
await interaction.reply({
embeds: [embed],
allowedMentions: { parse: [] },
});
}