feat: implement modal for managing points with user selection and input fields

This commit is contained in:
2025-10-03 22:38:43 -05:00
parent 22e1701738
commit ab4d9fbae8

View File

@@ -2,11 +2,10 @@ import logger from "../../core/lib/logger";
import { import {
ButtonInteraction, ButtonInteraction,
MessageFlags, MessageFlags,
PermissionFlagsBits, PermissionFlagsBits
StringSelectMenuBuilder,
ActionRowBuilder
} from 'discord.js'; } from 'discord.js';
import { prisma } from '../../core/database/prisma'; import { prisma } from '../../core/database/prisma';
import { ComponentType, TextInputStyle } from 'discord-api-types/v10';
export default { export default {
customId: 'ld_manage_points', customId: 'ld_manage_points',
@@ -28,7 +27,7 @@ export default {
} }
try { try {
// Obtener todos los usuarios con puntos en este servidor // Obtener todos los usuarios con puntos en este servidor (limitado a 25 para el UserSelect)
const stats = await prisma.partnershipStats.findMany({ const stats = await prisma.partnershipStats.findMany({
where: { guildId: interaction.guild.id }, where: { guildId: interaction.guild.id },
orderBy: { totalPoints: 'desc' }, orderBy: { totalPoints: 'desc' },
@@ -42,47 +41,50 @@ export default {
}); });
} }
// Construir opciones del select menu // Crear modal con TextInput y UserSelect usando el nuevo formato de discord.js dev
const options = await Promise.all( const modal = {
stats.map(async (stat) => { title: 'Gestionar Puntos de Alianza',
let displayName = 'Usuario desconocido'; customId: 'ld_points_modal',
try { components: [
const member = await interaction.guild!.members.fetch(stat.userId); {
displayName = member.displayName || member.user.username; type: ComponentType.TextDisplay,
} catch { content: 'Selecciona un usuario del leaderboard y modifica sus puntos.'
try { },
const user = await interaction.client.users.fetch(stat.userId); {
displayName = user.username; type: ComponentType.Label,
} catch { label: 'Modificar Puntos Totales',
// Mantener el nombre por defecto component: {
} type: ComponentType.TextInput,
} customId: 'points_input',
style: TextInputStyle.Short,
required: true,
placeholder: '+50 (añadir) / -20 (quitar) / =100 (establecer)',
minLength: 1,
maxLength: 10
},
},
{
type: ComponentType.Label,
label: 'Selecciona el usuario (del leaderboard)',
component: {
type: ComponentType.UserSelect,
customId: 'user_select',
required: true,
minValues: 1,
maxValues: 1,
placeholder: 'Elige un usuario...',
// Filtrar solo usuarios que están en el leaderboard
defaultUsers: stats.map(s => s.userId)
},
},
],
} as const;
return { await interaction.showModal(modal);
label: displayName,
description: `Total: ${stat.totalPoints} | Semanal: ${stat.weeklyPoints} | Mensual: ${stat.monthlyPoints}`,
value: stat.userId
};
})
);
const selectMenu = new StringSelectMenuBuilder()
.setCustomId('ld_select_user')
.setPlaceholder('Selecciona un usuario para gestionar sus puntos')
.addOptions(options);
const row = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(selectMenu);
await interaction.reply({
content: '### ⚙️ Gestión de Puntos\nSelecciona el usuario al que deseas modificar los puntos:',
components: [row],
flags: MessageFlags.Ephemeral
});
} catch (e) { } catch (e) {
logger.error({ err: e }, 'Error en ldManagePoints'); logger.error({ err: e }, 'Error en ldManagePoints');
await interaction.reply({ await interaction.reply({
content: '❌ Error al cargar la lista de usuarios.', content: '❌ Error al abrir el modal de gestión.',
flags: MessageFlags.Ephemeral flags: MessageFlags.Ephemeral
}); });
} }