diff --git a/src/interactions/commands/General/ticket/subcommands/ticket-presets.ts b/src/interactions/commands/General/ticket/subcommands/ticket-presets.ts new file mode 100644 index 000000000..f4f626fd2 --- /dev/null +++ b/src/interactions/commands/General/ticket/subcommands/ticket-presets.ts @@ -0,0 +1,79 @@ +import { DatabaseManager } from "@alice-database/DatabaseManager"; +import { TicketLocalization } from "@alice-localization/interactions/commands/General/ticket/TicketLocalization"; +import { SlashSubcommand } from "@alice-structures/core/SlashSubcommand"; +import { OnButtonPageChange } from "@alice-structures/utils/OnButtonPageChange"; +import { EmbedCreator } from "@alice-utils/creators/EmbedCreator"; +import { MessageButtonCreator } from "@alice-utils/creators/MessageButtonCreator"; +import { MessageCreator } from "@alice-utils/creators/MessageCreator"; +import { CommandHelper } from "@alice-utils/helpers/CommandHelper"; +import { InteractionHelper } from "@alice-utils/helpers/InteractionHelper"; +import { bold } from "discord.js"; + +export const run: SlashSubcommand["run"] = async (_, interaction) => { + if (!interaction.inCachedGuild()) { + return; + } + + const localization = new TicketLocalization( + await CommandHelper.getLocale(interaction), + ); + + await InteractionHelper.deferReply(interaction); + + const presets = + await DatabaseManager.aliceDb.collections.supportTicketPreset.get( + "id", + {}, + { projection: { _id: 0, id: 1, name: 1 } }, + ); + + if (presets.size === 0) { + return InteractionHelper.reply(interaction, { + content: MessageCreator.createReject( + localization.getTranslation("noTicketPresetsExist"), + ), + }); + } + + const presetsArray = [...presets.values()]; + const presetsPerPage = 5; + const embed = EmbedCreator.createNormalEmbed({ + author: interaction.user, + color: interaction.member.displayColor, + }); + + embed.setTitle(localization.getTranslation("ticketPresetListEmbedTitle")); + + const onPageChange: OnButtonPageChange = async (_, page) => { + const presets = presetsArray.slice( + presetsPerPage * (page - 1), + presetsPerPage * page, + ); + + const presetDescriptions: string[] = []; + + for (let i = 0; i < presets.length; ++i) { + const preset = presets[i]; + + presetDescriptions.push( + `${bold("ID")}: ${preset.id}\n${preset.name}`, + ); + } + + embed.setDescription(presetDescriptions.join("\n\n")); + }; + + MessageButtonCreator.createLimitedButtonBasedPaging( + interaction, + { embeds: [embed] }, + [interaction.user.id], + 1, + Math.ceil(presets.size / presetsPerPage), + 90, + onPageChange, + ); +}; + +export const config: SlashSubcommand["config"] = { + permissions: [], +}; diff --git a/src/interactions/commands/General/ticket/ticket.ts b/src/interactions/commands/General/ticket/ticket.ts index 2b3224a58..c70fdb4da 100644 --- a/src/interactions/commands/General/ticket/ticket.ts +++ b/src/interactions/commands/General/ticket/ticket.ts @@ -119,6 +119,35 @@ export const config: SlashCommand["config"] = { }, ], }, + { + name: "list", + type: ApplicationCommandOptionType.Subcommand, + description: "Lists all tickets from you or a user.", + options: [ + { + name: "author", + type: ApplicationCommandOptionType.User, + description: + "The user who opened the ticket. Defaults to yourself.", + }, + { + name: "status", + type: ApplicationCommandOptionType.Integer, + description: + "The ticket status to filter for. If unspecified, no status filter is applied.", + choices: [ + { + name: "Open", + value: SupportTicketStatus.open, + }, + { + name: "Closed", + value: SupportTicketStatus.closed, + }, + ], + }, + ], + }, { name: "move", type: ApplicationCommandOptionType.Subcommand, @@ -150,33 +179,9 @@ export const config: SlashCommand["config"] = { ], }, { - name: "list", + name: "presets", type: ApplicationCommandOptionType.Subcommand, - description: "Lists all tickets from you or a user.", - options: [ - { - name: "author", - type: ApplicationCommandOptionType.User, - description: - "The user who opened the ticket. Defaults to yourself.", - }, - { - name: "status", - type: ApplicationCommandOptionType.Integer, - description: - "The ticket status to filter for. If unspecified, no status filter is applied.", - choices: [ - { - name: "Open", - value: SupportTicketStatus.open, - }, - { - name: "Closed", - value: SupportTicketStatus.closed, - }, - ], - }, - ], + description: "Lists all available ticket presets.", }, { name: "reopen", diff --git a/src/localization/interactions/commands/General/ticket/TicketLocalization.ts b/src/localization/interactions/commands/General/ticket/TicketLocalization.ts index cd70787cf..f24fc9999 100644 --- a/src/localization/interactions/commands/General/ticket/TicketLocalization.ts +++ b/src/localization/interactions/commands/General/ticket/TicketLocalization.ts @@ -6,6 +6,7 @@ export interface TicketStrings { readonly ticketNotFound: string; readonly presetNotFound: string; readonly noTicketsFound: string; + readonly noTicketPresetsExist: string; readonly noTicketsAssigned: string; readonly ticketEditModalTitle: string; readonly ticketCreateModalTitle: string; @@ -27,6 +28,7 @@ export interface TicketStrings { readonly unassignTicketSuccess: string; readonly ticketListEmbedTitle: string; readonly assignedTicketListEmbedTitle: string; + readonly ticketPresetListEmbedTitle: string; readonly ticketStatus: string; readonly ticketGoToChannel: string; } diff --git a/src/localization/interactions/commands/General/ticket/translations/TicketENTranslation.ts b/src/localization/interactions/commands/General/ticket/translations/TicketENTranslation.ts index aa20f124d..9218819a8 100644 --- a/src/localization/interactions/commands/General/ticket/translations/TicketENTranslation.ts +++ b/src/localization/interactions/commands/General/ticket/translations/TicketENTranslation.ts @@ -9,6 +9,8 @@ export class TicketENTranslation extends Translation { ticketNotFound: "I'm sorry, I could not find the ticket!", presetNotFound: "I'm sorry, I could not find the preset!", noTicketsFound: "I'm sorry, I could not find any tickets!", + noTicketPresetsExist: + "I'm sorry, there are no ticket presets as of now!", noTicketsAssigned: "I'm sorry, you do not have any assigned tickets that match your filter!", ticketEditModalTitle: "Edit Ticket", @@ -34,6 +36,7 @@ export class TicketENTranslation extends Translation { assignTicketSuccess: "Successfully assigned you to the ticket.", ticketListEmbedTitle: "Tickets from %s", assignedTicketListEmbedTitle: "Assigned Tickets", + ticketPresetListEmbedTitle: "Ticket Presets", ticketStatus: "Status", ticketGoToChannel: "Go to Ticket Channel", };