From ab4d9fbae8c8105cae3927d5ba3104839a50f670 Mon Sep 17 00:00:00 2001 From: shni Date: Fri, 3 Oct 2025 22:38:43 -0500 Subject: [PATCH] feat: implement modal for managing points with user selection and input fields --- src/components/buttons/ldManagePoints.ts | 84 ++++++++++++------------ 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/src/components/buttons/ldManagePoints.ts b/src/components/buttons/ldManagePoints.ts index 877c581..fcf7be4 100644 --- a/src/components/buttons/ldManagePoints.ts +++ b/src/components/buttons/ldManagePoints.ts @@ -2,11 +2,10 @@ import logger from "../../core/lib/logger"; import { ButtonInteraction, MessageFlags, - PermissionFlagsBits, - StringSelectMenuBuilder, - ActionRowBuilder + PermissionFlagsBits } from 'discord.js'; import { prisma } from '../../core/database/prisma'; +import { ComponentType, TextInputStyle } from 'discord-api-types/v10'; export default { customId: 'ld_manage_points', @@ -28,7 +27,7 @@ export default { } 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({ where: { guildId: interaction.guild.id }, orderBy: { totalPoints: 'desc' }, @@ -42,47 +41,50 @@ export default { }); } - // Construir opciones del select menu - const options = await Promise.all( - stats.map(async (stat) => { - let displayName = 'Usuario desconocido'; - try { - const member = await interaction.guild!.members.fetch(stat.userId); - displayName = member.displayName || member.user.username; - } catch { - try { - const user = await interaction.client.users.fetch(stat.userId); - displayName = user.username; - } catch { - // Mantener el nombre por defecto - } - } + // Crear modal con TextInput y UserSelect usando el nuevo formato de discord.js dev + const modal = { + title: 'Gestionar Puntos de Alianza', + customId: 'ld_points_modal', + components: [ + { + type: ComponentType.TextDisplay, + content: 'Selecciona un usuario del leaderboard y modifica sus puntos.' + }, + { + type: ComponentType.Label, + label: 'Modificar Puntos Totales', + 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 { - 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() - .addComponents(selectMenu); - - await interaction.reply({ - content: '### ⚙️ Gestión de Puntos\nSelecciona el usuario al que deseas modificar los puntos:', - components: [row], - flags: MessageFlags.Ephemeral - }); + await interaction.showModal(modal); } catch (e) { logger.error({ err: e }, 'Error en ldManagePoints'); await interaction.reply({ - content: '❌ Error al cargar la lista de usuarios.', + content: '❌ Error al abrir el modal de gestión.', flags: MessageFlags.Ephemeral }); }