feat: finish user create command (closes #291)

This commit is contained in:
Isaac 2023-05-30 00:25:25 +01:00
parent 540ee547ea
commit 8f51ff885c
No known key found for this signature in database
GPG Key ID: 0DE40AE37BBA5C33
3 changed files with 163 additions and 7 deletions

View File

@ -13,10 +13,11 @@ module.exports = class CreateButton extends Button {
* @param {import("discord.js").ButtonInteraction} interaction * @param {import("discord.js").ButtonInteraction} interaction
*/ */
async run(id, interaction) { async run(id, interaction) {
if (id.targetUser && id.targetUser !== interaction.user.id) return;
await this.client.tickets.create({ await this.client.tickets.create({
categoryId: id.target, categoryId: id.target,
interaction, interaction,
topic: id.topic, topic: id.topic,
}); });
} }
}; };

View File

@ -1,4 +1,16 @@
const { UserCommand } = require('@eartharoid/dbf'); const { UserCommand } = require('@eartharoid/dbf');
const { isStaff } = require('../../lib/users');
const ExtendedEmbedBuilder = require('../../lib/embed');
const ms = require('ms');
const {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
ComponentType,
StringSelectMenuBuilder,
StringSelectMenuOptionBuilder,
} = require('discord.js');
const emoji = require('node-emoji');
module.exports = class CreateUserCommand extends UserCommand { module.exports = class CreateUserCommand extends UserCommand {
constructor(client, options) { constructor(client, options) {
@ -13,10 +25,144 @@ module.exports = class CreateUserCommand extends UserCommand {
}); });
} }
async run(/* interaction */) { /**
// TODO: isStaff? * @param {import("discord.js").UserContextMenuCommandInteraction} interaction
// TODO: user->create */
// select category async run(interaction) {
// send button /** @type {import("client")} */
const client = this.client;
await interaction.deferReply({ ephemeral: true });
const settings = await client.prisma.guild.findUnique({
include: { categories:true },
where: { id: interaction.guild.id },
});
const getMessage = client.i18n.getLocale(settings.locale);
if (!await isStaff(interaction.guild, interaction.user.id)) {
return await interaction.editReply({
embeds: [
new ExtendedEmbedBuilder({
iconURL: interaction.guild.iconURL(),
text: settings.footer,
})
.setColor(settings.errorColour)
.setTitle(getMessage('commands.user.create.not_staff.title'))
.setDescription(getMessage('commands.user.create.not_staff.description')),
],
});
}
const prompt = async categoryId => {
interaction.followUp({
components: [
new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({
action: 'create',
target: categoryId,
targetUser: interaction.targetId,
}))
.setStyle(ButtonStyle.Primary)
.setEmoji(getMessage('buttons.create.emoji')) // emoji.get('ticket')
.setLabel(getMessage('buttons.create.text')),
),
],
content: interaction.targetUser.toString(),
embeds: [
new ExtendedEmbedBuilder()
.setColor(settings.primaryColour)
.setAuthor({
iconURL: interaction.member.displayAvatarURL(),
name: interaction.member.displayName,
})
.setTitle(getMessage('commands.user.create.prompt.title'))
.setDescription(getMessage('commands.user.create.prompt.description')),
],
ephemeral: false,
});
};
if (settings.categories.length === 0) {
interaction.reply({
components: [],
embeds: [
new ExtendedEmbedBuilder()
.setColor(settings.errorColour)
.setTitle(getMessage('misc.no_categories.title'))
.setDescription(getMessage('misc.no_categories.description')),
],
ephemeral: true,
});
} else if (settings.categories.length === 1) {
await prompt(settings.categories[0].id);
} else {
const collectorTime = ms('15s');
const confirmationM = await interaction.editReply({
components: [
new ActionRowBuilder()
.setComponents(
new StringSelectMenuBuilder()
.setCustomId(JSON.stringify({
action: 'promptCreate',
user: interaction.targetId,
}))
.setPlaceholder(getMessage('menus.category.placeholder'))
.setOptions(
settings.categories.map(category =>
new StringSelectMenuOptionBuilder()
.setValue(String(category.id))
.setLabel(category.name)
.setDescription(category.description)
.setEmoji(emoji.hasEmoji(category.emoji) ? emoji.get(category.emoji) : { id: category.emoji }),
),
),
),
],
});
confirmationM.awaitMessageComponent({
componentType: ComponentType.StringSelect,
filter: i => i.user.id === interaction.user.id,
time: collectorTime,
})
.then(async i => {
const category = settings.categories.find(c => c.id === Number(i.values[0]));
await i.update({
components: [],
embeds: [
new ExtendedEmbedBuilder({
iconURL: interaction.guild.iconURL(),
text: settings.footer,
})
.setColor(settings.successColour)
.setTitle(getMessage('commands.user.create.sent.title'))
.setDescription(getMessage('commands.user.create.sent.description', {
category: category.name,
user: interaction.targetUser.toString(),
})),
],
ephemeral: true,
});
await prompt(category.id);
})
.catch(async error => {
client.log.error(error);
await interaction.reply({
components: [],
embeds: [
new ExtendedEmbedBuilder({
iconURL: interaction.guild.iconURL(),
text: settings.footer,
})
.setColor(settings.errorColour)
.setTitle(getMessage('misc.expired.title'))
.setDescription(getMessage('misc.expired.description')),
],
});
});
}
} }
}; };

View File

@ -247,6 +247,15 @@ commands:
user: user:
create: create:
name: Create ticket for user name: Create ticket for user
not_staff:
description: Only staff members can open tickets for other members.
title: ❌ Error
prompt:
description: Click the button below to create a ticket.
title: Please create a ticket
sent:
description: "{user} has been invited to create a ticket in **{category}**."
title: ✅ Prompt sent
dm: dm:
closed: closed:
archived: Use the `/transcript` command in **{guild}** to view the archived messages. archived: Use the `/transcript` command in **{guild}** to view the archived messages.