refactor(cmd/administration): adding the tsconfig + eslint correction

This commit is contained in:
Raphael 2025-10-14 00:17:23 +02:00 committed by Raphaël
parent e911f3b2e0
commit 8d41ef8f7a
4 changed files with 434 additions and 273 deletions

View file

@ -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;
}
},
};

View file

@ -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<ButtonBuilder>().addComponents(
function createMainRow(
guildData: GuildPrisma,
): ActionRowBuilder<ButtonBuilder> {
return new ActionRowBuilder<ButtonBuilder>().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<ButtonBuilder>().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<ButtonBuilder>().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<TextInputBuilder>().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<TextInputBuilder>().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);
});
}

View file

@ -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;
}
},

View file

@ -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<ButtonBuilder> {
function getButton(
selected: string,
active: boolean,
): ActionRowBuilder<ButtonBuilder> {
const button = new ActionRowBuilder<ButtonBuilder>().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<StringSelectMenuBuilder>().addComponents(menu)],
components: [
new ActionRowBuilder<StringSelectMenuBuilder>().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<StringSelectMenuBuilder>().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<StringSelectMenuBuilder>().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)],
});
})();
});
},
};