/** * /panel โ€” create a ticket-creation panel embed in a chosen channel. * Also hosts /signature (modal for staff personal email signature) since * both are user-facing UX-flow commands without their own dedicated module. */ const { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, MessageFlags, ModalBuilder, TextInputBuilder, TextInputStyle } = require('discord.js'); const { mongoose } = require('../../db-connection'); const { CONFIG } = require('../../config'); const { enqueueSend } = require('../../services/channelQueue'); const StaffSignature = mongoose.model('StaffSignature'); async function handlePanel(interaction) { const channel = interaction.options.getChannel('channel'); const panelType = interaction.options.getString('type') || null; // 'thread' | 'category' | 'both' or null const title = interaction.options.getString('title') || 'Indifferent Broccoli Tickets'; const description = interaction.options.getString('description') || 'Need help? Click below to create a ticket. ๐ŸŽŸ'; const embed = new EmbedBuilder() .setTitle(title) .setDescription(description) .setColor(0x2ecc71) .setThumbnail(CONFIG.LOGO_URL || null) .setFooter({ text: 'Indifferent Broccoli Tickets' }); const row = buildPanelButtonRow(panelType); try { await enqueueSend(channel, { embeds: [embed], components: [row] }); await interaction.reply({ content: `Panel created in ${channel}!`, flags: MessageFlags.Ephemeral }); } catch (err) { console.error('Panel creation error:', err); await interaction.reply({ content: 'Failed to create panel.', flags: MessageFlags.Ephemeral }); } } function buildPanelButtonRow(panelType) { if (panelType === 'both') { return new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId('open_ticket_thread') .setLabel('Create ticket (thread)') .setStyle(ButtonStyle.Secondary) .setEmoji('๐Ÿงต'), new ButtonBuilder() .setCustomId('open_ticket_channel') .setLabel('Create ticket (channel)') .setStyle(ButtonStyle.Secondary) .setEmoji('๐Ÿ“') ); } if (panelType === 'thread') { return new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId('open_ticket_thread') .setLabel('Create ticket') .setStyle(ButtonStyle.Secondary) .setEmoji('๐Ÿงต') ); } if (panelType === 'category') { return new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId('open_ticket_channel') .setLabel('Create ticket') .setStyle(ButtonStyle.Secondary) .setEmoji('๐Ÿ“') ); } return new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId('open_ticket') .setLabel('Create ticket') .setStyle(ButtonStyle.Secondary) .setEmoji('โœ…') ); } async function handleSignature(interaction) { try { const existingSignature = await StaffSignature.findOne({ userId: interaction.user.id }).lean(); const modal = new ModalBuilder() .setCustomId(`signature_modal_${interaction.user.id}`) .setTitle('Staff Signature Settings'); const valedictionInput = new TextInputBuilder() .setCustomId('valediction') .setLabel('Valediction (e.g. "Best regards", "Thanks")') .setStyle(TextInputStyle.Short) .setRequired(false) .setValue(existingSignature?.valediction || ''); const displayNameInput = new TextInputBuilder() .setCustomId('display_name') .setLabel('Display Name (e.g. "Support Team")') .setStyle(TextInputStyle.Short) .setRequired(false) .setValue(existingSignature?.displayName || ''); const taglineInput = new TextInputBuilder() .setCustomId('tagline') .setLabel('Tagline (e.g. "Technical Support Specialist")') .setStyle(TextInputStyle.Short) .setRequired(false) .setValue(existingSignature?.tagline || ''); modal.addComponents( new ActionRowBuilder().addComponents(valedictionInput), new ActionRowBuilder().addComponents(displayNameInput), new ActionRowBuilder().addComponents(taglineInput) ); await interaction.showModal(modal); } catch (err) { console.error('Signature command error:', err); if (!interaction.replied && !interaction.deferred) { await interaction.reply({ content: 'Failed to open signature settings.', flags: MessageFlags.Ephemeral }).catch(() => {}); } } } module.exports = { handlePanel, handleSignature };