chore: 🎉 initial commit

This commit is contained in:
UltraLionFr
2025-08-26 01:01:34 +02:00
parent bf6d61e5a3
commit 30cfbd73fc
27 changed files with 1341 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
const { config, lang } = require("../handlers/configLoader");
module.exports = {
id: "cancelClosure",
async execute(interaction) {
const member = interaction.member;
const isStaff = config.staffRoles.some(roleId => member.roles.cache.has(roleId));
if (!isStaff) {
return interaction.reply({
content: lang.permissions.staff_only,
flags: 64
});
}
await interaction.reply({
content: lang.commands.alert.cancelled,
flags: 64
});
}
};
+24
View File
@@ -0,0 +1,24 @@
const { PermissionFlagsBits } = require("discord.js");
const { closeTicket } = require("../handlers/database");
const { config, lang } = require("../handlers/configLoader");
module.exports = {
id: "closeTicket",
async execute(interaction) {
const member = interaction.member;
const isStaff = member.roles.cache.some(role => config.staffRoles.includes(role.id));
if (!isStaff) {
return interaction.reply({ content: lang.permissions.staff_only, flags: 64 });
}
const channel = interaction.channel;
await interaction.reply({ content: lang.ticket.closing });
setTimeout(async () => {
closeTicket(channel.id);
await channel.delete().catch(() => {});
}, 5000);
}
};
+100
View File
@@ -0,0 +1,100 @@
const {
ModalBuilder,
TextInputBuilder,
TextInputStyle,
ActionRowBuilder,
PermissionFlagsBits,
EmbedBuilder
} = require("discord.js");
const { getModal } = require("../handlers/modalHandler");
const { createTicket } = require("../handlers/database");
const { config } = require("../handlers/configLoader");
module.exports = {
id: /^ticket_.+$/,
async execute(interaction, client) {
const modalConfig = getModal(interaction.customId);
const staffRoles = (Array.isArray(config.staffRoles) ? config.staffRoles : [config.staffRoles])
.filter(r => r && r.trim() !== "");
if (!modalConfig || modalConfig.Enabled === false) {
const guild = interaction.guild;
const member = interaction.member;
const categories = config.TicketPanel.Panel.Categories;
const parentCategory = categories && categories.length > 0 ? categories[0] : null;
const overwrites = [
{ id: guild.id, deny: [PermissionFlagsBits.ViewChannel] },
{
id: member.id,
allow: [
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ReadMessageHistory
]
}
];
for (const roleId of staffRoles) {
overwrites.push({
id: roleId,
allow: [
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ReadMessageHistory
]
});
}
const channel = await guild.channels.create({
name: `ticket-${member.user.username}`.toLowerCase(),
type: 0,
parent: parentCategory || undefined,
permissionOverwrites: overwrites
});
createTicket(member.id, channel.id);
await interaction.reply({
content: `✅ Ton ticket a été créé : ${channel}`,
flags: 64
});
await channel.send(`🎟️ Bonjour ${member}, un membre du staff va bientôt te répondre.`);
const logChannel = await client.channels.fetch(config.logsChannel).catch(() => null);
if (logChannel) {
const embed = new EmbedBuilder()
.setTitle("🎟️ Nouveau ticket (sans formulaire)")
.addFields(
{ name: "Utilisateur", value: `${member.user.tag} (${member.id})` },
{ name: "Salon", value: `${channel}` }
)
.setColor(0x2ecc71)
.setTimestamp();
await logChannel.send({ embeds: [embed] });
}
return;
}
const modal = new ModalBuilder()
.setCustomId(`ticket_modal_${interaction.customId}`)
.setTitle(modalConfig.Title || "Création de ticket");
modalConfig.Inputs.forEach(input => {
const textInput = new TextInputBuilder()
.setCustomId(input.CustomId)
.setLabel(input.Label)
.setStyle(TextInputStyle[input.Style] || TextInputStyle.Short)
.setRequired(input.Required ?? false);
modal.addComponents(new ActionRowBuilder().addComponents(textInput));
});
await interaction.showModal(modal);
}
};
+87
View File
@@ -0,0 +1,87 @@
const { ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder, PermissionFlagsBits, EmbedBuilder } = require("discord.js");
const { getModal } = require("../handlers/modalHandler");
const { createTicket } = require("../handlers/database");
const { config } = require("../handlers/configLoader");
module.exports = {
id: "ticket_select",
async execute(interaction, client) {
const selected = interaction.values[0];
const modalConfig = getModal(selected);
if (!modalConfig || modalConfig.Enabled === false) {
const guild = interaction.guild;
const member = interaction.member;
const categories = config.TicketPanel.Panel.Categories;
const parentCategory = categories && categories.length > 0 ? categories[0] : null;
const channel = await guild.channels.create({
name: `ticket-${member.user.username}`.toLowerCase(),
type: 0,
parent: parentCategory || undefined,
permissionOverwrites: [
{ id: guild.id, deny: [PermissionFlagsBits.ViewChannel] },
{
id: member.id,
allow: [
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ReadMessageHistory
]
},
...config.staffRoles.map(roleId => ({
id: roleId,
allow: [
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ReadMessageHistory
]
}))
]
});
createTicket(member.id, channel.id);
await interaction.reply({
content: `✅ Ton ticket a été créé : ${channel}`,
flags: 64
});
await channel.send(`🎟️ Bonjour ${member}, un membre du staff va bientôt te répondre.`);
const logChannel = await client.channels.fetch(config.logsChannel).catch(() => null);
if (logChannel) {
const embed = new EmbedBuilder()
.setTitle("🎟️ Nouveau ticket (sans formulaire - via SelectMenu)")
.addFields(
{ name: "Utilisateur", value: `${member.user.tag} (${member.id})` },
{ name: "Salon", value: `${channel}` },
{ name: "Type de ticket", value: selected }
)
.setColor(0x2ecc71)
.setTimestamp();
await logChannel.send({ embeds: [embed] });
}
return;
}
const modal = new ModalBuilder()
.setCustomId(`ticket_modal_${selected}`)
.setTitle(modalConfig.Title || "Création de ticket");
modalConfig.Inputs.forEach(input => {
const textInput = new TextInputBuilder()
.setCustomId(input.CustomId)
.setLabel(input.Label)
.setStyle(TextInputStyle[input.Style] || TextInputStyle.Short)
.setRequired(input.Required ?? false);
modal.addComponents(new ActionRowBuilder().addComponents(textInput));
});
await interaction.showModal(modal);
}
};
+96
View File
@@ -0,0 +1,96 @@
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
const { createTicket } = require("../handlers/database");
const { config } = require("../handlers/configLoader");
module.exports = {
id: /^ticket_modal_.+$/,
async execute(interaction, client) {
const originalId = interaction.customId.replace("ticket_modal_", "");
const modalConfig = config.TicketPanel?.Modals?.[originalId];
if (!modalConfig) {
return interaction.reply({
content: "❌ Aucun formulaire configuré pour ce ticket.",
flags: 64
});
}
const member = interaction.member;
const guild = interaction.guild;
const categories = config.TicketPanel.Panel.Categories;
const parentCategory = categories && categories.length > 0 ? categories[0] : null;
const staffRoles = (Array.isArray(config.staffRoles) ? config.staffRoles : [config.staffRoles])
.filter(r => r && r.trim() !== "");
const overwrites = [
{ id: guild.id, deny: [PermissionFlagsBits.ViewChannel] },
{
id: member.id,
allow: [
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ReadMessageHistory
]
}
];
for (const roleId of staffRoles) {
overwrites.push({
id: roleId,
allow: [
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ReadMessageHistory
]
});
}
const channel = await guild.channels.create({
name: `ticket-${member.user.username}`.toLowerCase(),
type: 0,
parent: parentCategory || undefined,
permissionOverwrites: overwrites
});
createTicket(member.id, channel.id);
const fieldsOutput = modalConfig.Inputs.map(input => {
const value = interaction.fields.getTextInputValue(input.CustomId);
return `**${input.Label}** : ${value}`;
}).join("\n");
const embed = new EmbedBuilder()
.setTitle(`🎟️ ${modalConfig.Title || "Nouveau ticket"}`)
.setDescription(`👤 Ouvert par: ${member}\n\n${fieldsOutput}`)
.setColor(0x5e99ff)
.setTimestamp();
await channel.send({
content: staffRoles.map(r => `<@&${r}>`).join(" "),
embeds: [embed]
});
await interaction.reply({
content: `✅ Ton ticket a été créé : ${channel}`,
flags: 64
});
const logChannel = await client.channels.fetch(config.logsChannel).catch(() => null);
if (logChannel) {
const logEmbed = new EmbedBuilder()
.setTitle("🎟️ Nouveau ticket")
.setDescription(`Formulaire utilisé: \`${originalId}\``)
.addFields(
{ name: "Utilisateur", value: `${member.user.tag} (${member.id})` },
{ name: "Salon", value: `${channel}` },
{ name: "Réponses", value: fieldsOutput }
)
.setColor(0x2ecc71)
.setTimestamp();
await logChannel.send({ embeds: [logEmbed] });
}
}
};