From 8d41ef8f7a096817a38135e7b5b8c8607cecb978 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 14 Oct 2025 00:17:23 +0200 Subject: [PATCH] refactor(cmd/administration): adding the tsconfig + eslint correction --- .../administration/deleteCategories.ts | 79 +++-- src/commands/administration/join.ts | 305 ++++++++++-------- src/commands/administration/logs.ts | 150 ++++++--- src/commands/administration/protect.ts | 173 +++++----- 4 files changed, 434 insertions(+), 273 deletions(-) diff --git a/src/commands/administration/deleteCategories.ts b/src/commands/administration/deleteCategories.ts index 49b2d25..3f76b01 100644 --- a/src/commands/administration/deleteCategories.ts +++ b/src/commands/administration/deleteCategories.ts @@ -1,71 +1,94 @@ -import { MessageFlags, ChannelType, SlashCommandBuilder, CommandInteraction } from 'discord.js'; +import { SlashCommandBuilder } from '@discordjs/builders'; +import { + MessageFlags, + ChannelType, + ChatInputCommandInteraction, + type SlashCommandChannelOption, + CategoryChannel, +} from 'discord.js'; import emoji from '../../../assets/emoji.json' assert { type: 'json' }; -import { prisma } from '../../lib/prisma.ts'; +import { prisma } from '@lib/prisma'; import { User as UserPrisma } from '@prisma/client'; export default { data: new SlashCommandBuilder() .setName('deletecat') - .setDescription('Delete the categorie given in parameter') - .addChannelOption((opt) => + .setDescription('Delete the category given in parameter') + .addChannelOption((opt: SlashCommandChannelOption) => opt .setName('category') - .setDescription('Choose the categorie you want to delete') + .setDescription('Choose the category you want to delete') .setRequired(true) .addChannelTypes(ChannelType.GuildCategory), ), - async execute(interaction: CommandInteraction) { - let userData: UserPrisma; + + async execute(interaction: ChatInputCommandInteraction) { + let userData: UserPrisma | null = null; try { userData = await prisma.user.findUnique({ - where: { - id: interaction.user.id, - }, + where: { id: interaction.user.id }, }); } - catch (err) { - console.error( - `\t⚠️ | Whitelist => Cannot get the database connection!\n\t\t(${err}).`, - ); + catch (err: unknown) { + if (err instanceof Error) { + console.error(`❌ ${err.name}: ${err.message}`); + console.error(err.stack); + } + else { + console.error('❌ Unknown error:', err); + } await interaction.reply({ content: `${emoji.answer.error} | Cannot connect to the database`, flags: MessageFlags.Ephemeral, }); - console.error(`Cannot connect to the database:\n\t${err}`); return; } - if (!userData.isOwner) { + + if (!userData?.isOwner) { await interaction.reply({ - content: `${emoji.answer.no} | This command is only for owner`, + content: `${emoji.answer.no} | This command is only for owners`, flags: MessageFlags.Ephemeral, }); return; } - const category: ChannelType.GuildCategory = interaction.options.getChannel( - 'category', - true, - ); + + const categoryOption = interaction.options.getChannel('category', true); + + if (categoryOption.type !== ChannelType.GuildCategory) { + await interaction.reply({ + content: `${emoji.answer.no} | Please choose a valid category.`, + flags: MessageFlags.Ephemeral, + }); + return; + } + + const category = categoryOption as CategoryChannel; + try { for (const channel of category.children.cache.values()) { await channel.delete( - `Delete cat of ${channel.name} (by ${interaction.username})`, + `Deleted ${channel.name} (requested by ${interaction.user.username})`, ); } + await category.delete( - `Delete cat of ${category.name} (by ${interaction.username})`, + `Deleted ${category.name} (requested by ${interaction.user.username})`, ); + await interaction.reply({ - content: `${emoji.answer.yes} | Suppressed the ${category.name}`, + content: `${emoji.answer.yes} | Deleted category **${category.name}** and its channels.`, flags: MessageFlags.Ephemeral, }); } - catch (err) { + catch (err: unknown) { + const errorMessage = err instanceof Error ? err.message : String(err); + console.error( + `Cannot delete category or its channels:\n\t${errorMessage}`, + ); await interaction.reply({ - content: `${emoji.answer.error} | Cannot suppress the category's channels`, + content: `${emoji.answer.error} | Failed to delete the category or its channels.`, flags: MessageFlags.Ephemeral, }); - console.error(`Cannot suppress the category's channel:\n\t${err}`); - return; } }, }; diff --git a/src/commands/administration/join.ts b/src/commands/administration/join.ts index 4a9446e..a6552e1 100644 --- a/src/commands/administration/join.ts +++ b/src/commands/administration/join.ts @@ -1,11 +1,10 @@ +import { ActionRowBuilder, SlashCommandBuilder } from '@discordjs/builders'; import { - SlashCommandBuilder, - ChatInputCommandInteraction, - EmbedBuilder, - ActionRowBuilder, - ButtonBuilder, ButtonStyle, + ChatInputCommandInteraction, ComponentType, + EmbedBuilder, + Interaction, MessageFlags, ModalBuilder, TextInputBuilder, @@ -43,22 +42,16 @@ function getPlaceholdersEmbed(guildData: GuildPrisma): EmbedBuilder { .setColor(guildData.color); } -export const data = new SlashCommandBuilder() - .setName('join') - .setDescription('Configure welcome and leave messages'); - -export async function execute(interaction: ChatInputCommandInteraction) { - const guildId = interaction.guildId!; - let guildData = await prisma.guild.findUnique({ where: { id: guildId } }); - if (!guildData) { - guildData = await prisma.guild.create({ data: { id: guildId } }); - } - - const mainRow = new ActionRowBuilder().addComponents( +function createMainRow( + guildData: GuildPrisma, +): ActionRowBuilder { + return new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId('toggle_welcome') .setLabel(guildData.welcomeEnabled ? 'Disable welcome' : 'Enable welcome') - .setStyle(guildData.welcomeEnabled ? ButtonStyle.Danger : ButtonStyle.Success), + .setStyle( + guildData.welcomeEnabled ? ButtonStyle.Danger : ButtonStyle.Success, + ), new ButtonBuilder() .setCustomId('edit_welcome') .setLabel('Edit welcome message') @@ -66,7 +59,9 @@ export async function execute(interaction: ChatInputCommandInteraction) { new ButtonBuilder() .setCustomId('toggle_leave') .setLabel(guildData.leaveEnabled ? 'Disable leave' : 'Enable leave') - .setStyle(guildData.leaveEnabled ? ButtonStyle.Danger : ButtonStyle.Success), + .setStyle( + guildData.leaveEnabled ? ButtonStyle.Danger : ButtonStyle.Success, + ), new ButtonBuilder() .setCustomId('edit_leave') .setLabel('Edit leave message') @@ -77,132 +72,188 @@ export async function execute(interaction: ChatInputCommandInteraction) { .setEmoji('ℹ️') .setStyle(ButtonStyle.Secondary), ); +} + +export const data = new SlashCommandBuilder() + .setName('join') + .setDescription('Configure welcome and leave messages'); + +export async function execute(interaction: ChatInputCommandInteraction) { + const guildId = interaction.guildId; + if (!guildId) { + await interaction.reply({ + content: '❌ This command can only be used in a guild.', + flags: MessageFlags.Ephemeral, + }); + return; + } + + let currentGuildData: GuildPrisma | null = await prisma.guild.findUnique({ + where: { id: guildId }, + }); + if (!currentGuildData) { + currentGuildData = await prisma.guild.create({ data: { id: guildId } }); + } + + const mainRow : ActionRowBuilder = createMainRow(currentGuildData); await interaction.reply({ - embeds: [getEmbed(guildData)], + embeds: [getEmbed(currentGuildData)], components: [mainRow], flags: MessageFlags.Ephemeral, }); - const collector = interaction.channel!.createMessageComponentCollector({ + const collector = interaction.channel?.createMessageComponentCollector({ componentType: ComponentType.Button, time: 60_000, }); - collector.on('collect', async (i) => { - if (i.user.id !== interaction.user.id) { - return i.reply({ - content: '❌ You are not allowed to use this panel.', - ephemeral: true, - }); - } + if (!collector) { + return; + } - // ℹ️ Show placeholders - if (i.customId === 'placeholders') { - const backRow = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('back_to_main') - .setLabel('↩️ Back') - .setStyle(ButtonStyle.Secondary), - ); - await interaction.editReply({ - embeds: [getPlaceholdersEmbed(guildData)], - components: [backRow], - }); - return; - } + collector.on('collect', (i) => { + void (async () => { + if (i.user.id !== interaction.user.id) { + await i.reply({ + content: '❌ You are not allowed to use this panel.', + flags: MessageFlags.Ephemeral, + }); + return; + } - // ↩️ Back to main panel - if (i.customId === 'back_to_main') { - await interaction.editReply({ - embeds: [getEmbed(guildData)], - components: [mainRow], - }); - return; - } - - // 🟢 Toggle welcome - if (i.customId === 'toggle_welcome') { - guildData = await prisma.guild.update({ - where: { id: guildId }, - data: { welcomeEnabled: !guildData.welcomeEnabled }, - }); - await interaction.editReply({ - embeds: [getEmbed(guildData)], - components: [mainRow], - }); - return; - } - - // 🟢 Toggle leave - if (i.customId === 'toggle_leave') { - guildData = await prisma.guild.update({ - where: { id: guildId }, - data: { leaveEnabled: !guildData.leaveEnabled }, - }); - await interaction.editReply({ - embeds: [getEmbed(guildData)], - components: [mainRow], - }); - return; - } - - // ✏️ Open modal for editing messages - if (i.customId === 'edit_welcome' || i.customId === 'edit_leave') { - const modal = new ModalBuilder() - .setCustomId(i.customId + '_modal') - .setTitle('Edit Message'); - - const input = new TextInputBuilder() - .setCustomId('message') - .setLabel('Message content (placeholders allowed)') - .setStyle(TextInputStyle.Paragraph) - .setPlaceholder('Ex: Welcome {user.mention} to {server.name}!') - .setValue( - i.customId === 'edit_welcome' - ? guildData.welcomeMessage || '' - : guildData.leaveMessage || '', + // ℹ️ Show placeholders + if (i.customId === 'placeholders') { + const backRow = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId('back_to_main') + .setLabel('↩️ Back') + .setStyle(ButtonStyle.Secondary), ); + await interaction.editReply({ + embeds: [getPlaceholdersEmbed(currentGuildData)], + components: [backRow], + }); + return; + } - modal.addComponents(new ActionRowBuilder().addComponents(input)); - await i.showModal(modal); - } + // ↩️ Back to main panel + if (i.customId === 'back_to_main') { + await interaction.editReply({ + embeds: [getEmbed(currentGuildData)], + components: [createMainRow(currentGuildData)], + }); + return; + } + + // 🟢 Toggle welcome + if (i.customId === 'toggle_welcome') { + const updatedGuildData = await prisma.guild.update({ + where: { id: guildId }, + data: { welcomeEnabled: !currentGuildData.welcomeEnabled }, + }); + currentGuildData = updatedGuildData; + const newMainRow = createMainRow(updatedGuildData); + await interaction.editReply({ + embeds: [getEmbed(updatedGuildData)], + components: [newMainRow], + }); + return; + } + + // 🟢 Toggle leave + if (i.customId === 'toggle_leave') { + const updatedGuildData = await prisma.guild.update({ + where: { id: guildId }, + data: { leaveEnabled: !currentGuildData.leaveEnabled }, + }); + currentGuildData = updatedGuildData; + const newMainRow = createMainRow(updatedGuildData); + await interaction.editReply({ + embeds: [getEmbed(updatedGuildData)], + components: [newMainRow], + }); + return; + } + + // ✏️ Open modal for editing messages + if (i.customId === 'edit_welcome' || i.customId === 'edit_leave') { + const modal = new ModalBuilder() + .setCustomId(`${i.customId}_modal`) + .setTitle('Edit Message'); + + const input = new TextInputBuilder() + .setCustomId('message') + .setLabel({ name: 'Message content (placeholders allowed)' }) + .setStyle(TextInputStyle.Paragraph) + .setPlaceholder('Ex: Welcome {user.mention} to {server.name}!') + .setValue( + i.customId === 'edit_welcome' + ? currentGuildData.welcomeMessage || '' + : currentGuildData.leaveMessage || '', + ); + + modal.addComponents( + new ActionRowBuilder().addComponents(input), + ); + await i.showModal(modal); + } + })(); }); // Handle modal submissions - interaction.client.on('interactionCreate', async (modalInt) => { - if (!modalInt.isModalSubmit()) return; + const modalHandler = (modalInt: Interaction) => { + void (async () => { + if ( + !modalInt.isModalSubmit() || + modalInt.user.id !== interaction.user.id + ) { + return; + } - if (modalInt.customId === 'edit_welcome_modal') { - const msg = modalInt.fields.getTextInputValue('message'); - guildData = await prisma.guild.update({ - where: { id: guildId }, - data: { welcomeMessage: msg }, - }); - await modalInt.reply({ - content: '✅ | Welcome message updated!', - ephemeral: true, - }); - await interaction.editReply({ - embeds: [getEmbed(guildData)], - components: [mainRow], - }); - } + const typedModalInt = modalInt; - if (modalInt.customId === 'edit_leave_modal') { - const msg = modalInt.fields.getTextInputValue('message'); - guildData = await prisma.guild.update({ - where: { id: guildId }, - data: { leaveMessage: msg }, - }); - await modalInt.reply({ - content: '✅ | Leave message updated!', - ephemeral: true, - }); - await interaction.editReply({ - embeds: [getEmbed(guildData)], - components: [mainRow], - }); - } + if (typedModalInt.customId === 'edit_welcome_modal') { + const msg = typedModalInt.fields.getTextInputValue('message'); + const updatedGuildData = await prisma.guild.update({ + where: { id: guildId }, + data: { welcomeMessage: msg }, + }); + currentGuildData = updatedGuildData; + await typedModalInt.reply({ + content: '✅ | Welcome message updated!', + ephemeral: true, + }); + const newMainRow = createMainRow(updatedGuildData); + await interaction.editReply({ + embeds: [getEmbed(updatedGuildData)], + components: [newMainRow], + }); + } + + if (typedModalInt.customId === 'edit_leave_modal') { + const msg = typedModalInt.fields.getTextInputValue('message'); + const updatedGuildData = await prisma.guild.update({ + where: { id: guildId }, + data: { leaveMessage: msg }, + }); + currentGuildData = updatedGuildData; + await typedModalInt.reply({ + content: '✅ | Leave message updated!', + ephemeral: true, + }); + const newMainRow = createMainRow(updatedGuildData); + await interaction.editReply({ + embeds: [getEmbed(updatedGuildData)], + components: [newMainRow], + }); + } + })(); + }; + + interaction.client.on('interactionCreate', modalHandler); + + collector.on('end', () => { + interaction.client.off('interactionCreate', modalHandler); }); } diff --git a/src/commands/administration/logs.ts b/src/commands/administration/logs.ts index a4319d1..2e138bf 100644 --- a/src/commands/administration/logs.ts +++ b/src/commands/administration/logs.ts @@ -1,6 +1,6 @@ -import { prisma } from '../../lib/prisma.ts'; +import { prisma } from '@lib/prisma'; +import { ActionRowBuilder, SlashCommandBuilder } from '@discordjs/builders'; import { - ActionRowBuilder, ChannelType, PermissionsBitField, ComponentType, @@ -8,12 +8,13 @@ import { StringSelectMenuBuilder, StringSelectMenuInteraction, StringSelectMenuOptionBuilder, - SlashCommandBuilder, MessageFlags, EmbedBuilder, - CommandInteraction, + ChatInputCommandInteraction, + CategoryChannel, } from 'discord.js'; import emoji from '../../../assets/emoji.json' assert { type: 'json' }; +import { Guild, User } from '@prisma/client'; export default { data: new SlashCommandBuilder() @@ -43,8 +44,16 @@ export default { }, ), ), - async execute(interaction: CommandInteraction) { - let guildData: Guild; + async execute(interaction: ChatInputCommandInteraction) { + if (!interaction.guild) { + await interaction.reply({ + content: `${emoji.answer.error} | This command can only be used in a guild`, + flags: MessageFlags.Ephemeral, + }); + return; + } + + let guildData: Guild | null; try { guildData = await prisma.guild.findUnique({ where: { @@ -52,9 +61,10 @@ export default { }, }); } - catch (err) { + catch (err: unknown) { + const errorMessage = err instanceof Error ? err.message : String(err); console.error( - `\t⚠️ | Cannot get the database connection!\n\t\t(${err}).`, + `\t⚠️ | Cannot get the database connection!\n\t\t(${errorMessage}).`, ); await interaction.reply({ content: `${emoji.answer.error} | Cannot connect to the database`, @@ -62,7 +72,16 @@ export default { }); return; } - let userData: User; + + if (!guildData) { + await interaction.reply({ + content: `${emoji.answer.error} | Guild data not found`, + flags: MessageFlags.Ephemeral, + }); + return; + } + + let userData: User | null; try { userData = await prisma.user.findUnique({ where: { @@ -70,10 +89,23 @@ export default { }, }); } - catch (err) { - throw `\t⚠️ | Cannot get the database connection!\n\t\t(${err}).`; + catch (err: unknown) { + const errorMessage = err instanceof Error ? err.message : String(err); + throw new Error( + `\t⚠️ | Cannot get the database connection!\n\t\t(${errorMessage}).`, + ); } - const choice: string = interaction.options.getString('action'); + + if (!userData) { + await interaction.reply({ + content: `${emoji.answer.error} | User data not found`, + flags: MessageFlags.Ephemeral, + }); + return; + } + + const choice = interaction.options.getString('action', true); + switch (choice) { case 'logs_show': { if (!userData.isOwner) { @@ -86,7 +118,7 @@ export default { if (guildData.logEnable) { const logsData: EmbedBuilder = new EmbedBuilder() .setTitle(`Logs for ${interaction.guild.name}`) - .setColor(`${guildData.color}`) + .setColor(guildData.color) .setFooter({ text: guildData.footer, }).setDescription(` @@ -128,8 +160,8 @@ export default { return; } - const roles = interaction.guild?.roles.cache - .filter((role) => !role.managed && role.id !== interaction.guild?.id) + const roles = interaction.guild.roles.cache + .filter((role) => !role.managed && role.id !== interaction.guild.id) .sort((a, b) => b.position - a.position); const menu = new StringSelectMenuBuilder() @@ -150,7 +182,7 @@ export default { const permSelector: EmbedBuilder = new EmbedBuilder() .setTitle('Which role will have access') - .setColor(`${guildData.color}`) + .setColor(guildData.color) .setFooter({ text: guildData.footer, }); @@ -158,27 +190,29 @@ export default { const msg = await interaction.reply({ embeds: [permSelector], components: [roleSelection], - flags: MessageFlags.fetchReply, }); const collector = msg.createMessageComponentCollector({ componentType: ComponentType.StringSelect, time: 60_000, max: 25, }); - collector.on('end', async (collected) => { - if (collected.size === 0) { - await interaction.editReply({ - content: '⏰ | Too many time to select roles allowed to see the logs', - embeds: [], - components: [], - }); - } + collector.on('end', (collected) => { + void (async () => { + if (collected.size === 0) { + await interaction.editReply({ + content: + '⏰ | Too many time to select roles allowed to see the logs', + embeds: [], + components: [], + }); + } + })(); }); collector.on( 'collect', async (selectInteraction: StringSelectMenuInteraction) => { if (selectInteraction.user.id !== interaction.user.id) { - selectInteraction.reply({ + void selectInteraction.reply({ content: `${emoji.answer.no} | You cannot use this selector !`, ephemeral: true, }); @@ -199,53 +233,53 @@ export default { })), ]; - const category = (await interaction.guild.channels.create({ + const category = await interaction.guild.channels.create({ name: 'Logs', type: ChannelType.GuildCategory, permissionOverwrites, - })) as CategoryChannel; + }); - const logBot = (await interaction.guild.channels.create({ + const logBot = await interaction.guild.channels.create({ name: 'bot-logs', type: ChannelType.GuildText, parent: category, permissionOverwrites, - })) as TextChannel; + }); - const logChannels = (await interaction.guild.channels.create({ + const logChannels = await interaction.guild.channels.create({ name: 'channel-logs', type: ChannelType.GuildText, parent: category, permissionOverwrites, - })) as TextChannel; + }); - const logMember = (await interaction.guild.channels.create({ + const logMember = await interaction.guild.channels.create({ name: 'member-logs', type: ChannelType.GuildText, parent: category, permissionOverwrites, - })) as TextChannel; + }); - const logMod = (await interaction.guild.channels.create({ + const logMod = await interaction.guild.channels.create({ name: 'mod-logs', type: ChannelType.GuildText, parent: category, permissionOverwrites, - })) as TextChannel; + }); - const logMsg = (await interaction.guild.channels.create({ + const logMsg = await interaction.guild.channels.create({ name: 'message-logs', type: ChannelType.GuildText, parent: category, permissionOverwrites, - })) as TextChannel; + }); - const logServer = (await interaction.guild.channels.create({ + const logServer = await interaction.guild.channels.create({ name: 'server-logs', type: ChannelType.GuildText, parent: category, permissionOverwrites, - })) as TextChannel; + }); await prisma.guild.update({ where: { @@ -273,7 +307,7 @@ export default { ${mentionList} `, ) - .setColor(`${guildData.color}`) + .setColor(guildData.color) .setFooter({ text: guildData.footer, }); @@ -301,27 +335,47 @@ export default { }); return; } - const category: GuildCategory = await interaction.guild.channels.fetch(guildData.logCategory); + if (!guildData.logCategory) { + await interaction.reply({ + content: `${emoji.answer.error} | No log category found`, + flags: MessageFlags.Ephemeral, + }); + return; + } + const category = (await interaction.guild.channels.fetch( + guildData.logCategory, + )) as CategoryChannel | null; + if (!category) { + await interaction.reply({ + content: `${emoji.answer.error} | Category not found`, + flags: MessageFlags.Ephemeral, + }); + return; + } try { for (const channel of category.children.cache.values()) { await channel.delete( - `Delete cat of ${channel.name} (by ${interaction.username})`, + `Delete cat of ${channel.name} (by ${interaction.user.username})`, ); } await category.delete( - `Delete cat of ${category.name} (by ${interaction.username})`, + `Delete cat of ${category.name} (by ${interaction.user.username})`, ); await interaction.reply({ content: `${emoji.answer.yes} | Disabled the logs of the guild`, flags: MessageFlags.Ephemeral, }); } - catch (err) { + catch (err: unknown) { + const errorMessage = + err instanceof Error ? err.message : (err as string); await interaction.reply({ content: `${emoji.answer.error} | Cannot suppress the category's channels`, flags: MessageFlags.Ephemeral, }); - console.error(`Cannot suppress the category's channel:\n\t${err}`); + console.error( + `Cannot suppress the category's channel:\n\t${errorMessage}`, + ); return; } await prisma.guild.update({ @@ -343,6 +397,10 @@ export default { } default: console.error(`no choice on logs command ${choice}`); + await interaction.reply({ + content: `${emoji.answer.error} | Invalid choice`, + flags: MessageFlags.Ephemeral, + }); return; } }, diff --git a/src/commands/administration/protect.ts b/src/commands/administration/protect.ts index 046fb97..b30f0fd 100644 --- a/src/commands/administration/protect.ts +++ b/src/commands/administration/protect.ts @@ -1,8 +1,6 @@ +import { ButtonBuilder, ActionRowBuilder, SlashCommandBuilder } from '@discordjs/builders'; import { - SlashCommandBuilder, - ActionRowBuilder, StringSelectMenuBuilder, - ButtonBuilder, ButtonStyle, EmbedBuilder, ComponentType, @@ -45,7 +43,10 @@ function getEmbed(guildData: GuildPrisma): EmbedBuilder { return baseEmbed; } -function getButton(selected: string, active: boolean): ActionRowBuilder { +function getButton( + selected: string, + active: boolean, +): ActionRowBuilder { const button = new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId(`enable_${selected}`) @@ -74,8 +75,16 @@ export default { .setDescription('Manage guild protections interactively'), async execute(interaction: ChatInputCommandInteraction) { - const guildId: string | null = interaction.guildId!; - let guildData: GuildPrisma = await prisma.guild.findUnique({ + const guildId = interaction.guildId; + if (!guildId) { + await interaction.reply({ + content: 'This command can only be used in a guild.', + flags: MessageFlags.Ephemeral, + }); + return; + } + + let guildData = await prisma.guild.findUnique({ where: { id: guildId, }, @@ -98,87 +107,107 @@ export default { ); const msg = await interaction.reply({ embeds: [getEmbed(guildData)], - components: [new ActionRowBuilder().addComponents(menu)], + components: [ + new ActionRowBuilder().addComponents(menu), + ], flags: MessageFlags.Ephemeral, }); const collector = msg.createMessageComponentCollector({ componentType: ComponentType.StringSelect, time: 5 * 60 * 1000, }); - collector.on('collect', async (selectInteraction) => { - if (selectInteraction.user.id !== interaction.user.id) { - return selectInteraction.reply({ - content: '❌ You cannot use this menu.', - flags: MessageFlags.Ephemeral, + collector.on('collect', (selectInteraction) => { + void (async () => { + if (selectInteraction.user.id !== interaction.user.id) { + await selectInteraction.reply({ + content: '❌ You cannot use this menu.', + flags: MessageFlags.Ephemeral, + }); + return; + } + const selected: string = selectInteraction + .values[0] as keyof typeof modules; + const enabled = guildData[ + `protect${camel(selected)}` as keyof GuildPrisma + ] as boolean; + const moduleEmbed = new EmbedBuilder() + .setTitle(`⚙️ | Manage ${modules[selected as keyof typeof modules]}`) + .setFooter({ + text: guildData.footer, + }) + .setDescription( + `This module is currently: **${enabled ? 'Enabled ✅' : 'Disabled ❌'}**`, + ) + .setColor(enabled ? '#00ff00' : '#ff0000'); + await selectInteraction.update({ + embeds: [moduleEmbed], + components: [getButton(selected, true)], }); - } - const selected: string = selectInteraction.values[0] as keyof typeof modules; - const enabled = guildData![`protect${camel(selected)}`]; - const moduleEmbed = new EmbedBuilder() - .setTitle(`⚙️ | Manage ${modules[selected]}`) - .setFooter({ - text: guildData.footer, - }) - .setDescription( - `This module is currently: **${enabled ? 'Enabled ✅' : 'Disabled ❌'}**`, - ) - .setColor(enabled ? '#00ff00' : '#ff0000'); - await selectInteraction.update({ - embeds: [moduleEmbed], - components: [getButton(selected, true)], - }); + })(); }); const buttonCollector = msg.createMessageComponentCollector({ componentType: ComponentType.Button, time: 5 * 60 * 1000, }); - buttonCollector.on('collect', async (btnInteraction) => { - if (btnInteraction.user.id !== interaction.user.id) { - return btnInteraction.reply({ - content: '❌ | You cannot use these buttons.', - flags: MessageFlags.Ephemeral, + buttonCollector.on('collect', (btnInteraction) => { + void (async () => { + if (btnInteraction.user.id !== interaction.user.id) { + await btnInteraction.reply({ + content: '❌ | You cannot use these buttons.', + flags: MessageFlags.Ephemeral, + }); + return; + } + if (btnInteraction.customId === 'return') { + await btnInteraction.update({ + embeds: [getEmbed(guildData)], + components: [ + new ActionRowBuilder().addComponents( + menu, + ), + ], + }); + return; + } + const [action, moduleName] = btnInteraction.customId.split('_'); + if (!moduleName) return; + + const field = `protect${camel(moduleName)}`; + await prisma.guild.update({ + where: { + id: guildId, + }, + data: { + [field]: action === 'enable', + }, }); - } - if (btnInteraction.customId === 'return') { - return btnInteraction.update({ - embeds: [getEmbed(guildData)], - components: [ - new ActionRowBuilder().addComponents(menu), + const updatedGuildData = await prisma.guild.findUnique({ + where: { + id: guildId, + }, + }); + if (!updatedGuildData) return; + + guildData = updatedGuildData; + await btnInteraction.update({ + embeds: [ + new EmbedBuilder() + .setTitle( + `⚙️ | Manage ${modules[moduleName as keyof typeof modules]}`, + ) + .setFooter({ + text: updatedGuildData.footer, + }) + .setDescription( + `This module is now: **${ + action === 'enable' ? '✅ Enabled' : '❌ Disabled' + }**`, + ) + .setColor(action === 'enable' ? '#00ff00' : '#ff0000'), ], + components: [getButton(moduleName, false)], }); - } - const [action, moduleName] = btnInteraction.customId.split('_'); - const field = `protect${camel(moduleName)}`; - await prisma.guild.update({ - where: { - id: guildId, - }, - data: { - [field]: action === 'enable', - }, - }); - guildData = await prisma.guild.findUnique({ - where: { - id: guildId, - }, - }); - await btnInteraction.update({ - embeds: [ - new EmbedBuilder() - .setTitle(`⚙️ | Manage ${modules[moduleName as keyof typeof modules]}`) - .setFooter({ - text: guildData.footer, - }) - .setDescription( - `This module is now: **${ - action === 'enable' ? '✅ Enabled' : '❌ Disabled' - }**`, - ) - .setColor(action === 'enable' ? '#00ff00' : '#ff0000'), - ], - components: [getButton(null, false)], - }); + })(); }); }, }; -