mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-23 00:03:09 +02:00
Panels!
This commit is contained in:
parent
98b35e3a81
commit
f93d058f55
@ -9,6 +9,8 @@
|
||||
"contributors:generate": "all-contributors generate",
|
||||
"keygen": "node scripts/keygen",
|
||||
"lint": "eslint src scripts --ext mjs --fix",
|
||||
"start": "node .",
|
||||
"studio": "npx prisma studio",
|
||||
"test": "echo \"There's nothing to test\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
@ -37,7 +39,7 @@
|
||||
"@fastify/cors": "^8.0.0",
|
||||
"@fastify/jwt": "^5.0.1",
|
||||
"@fastify/oauth2": "^5.0.0",
|
||||
"@prisma/client": "^4.0.0",
|
||||
"@prisma/client": "^4.1.0",
|
||||
"cryptr": "^6.0.3",
|
||||
"discord.js": "^14.0.2",
|
||||
"dotenv": "^16.0.1",
|
||||
@ -50,7 +52,7 @@
|
||||
"node-dir": "^0.1.17",
|
||||
"node-emoji": "^1.11.0",
|
||||
"object-diffy": "^1.0.4",
|
||||
"prisma": "^4.0.0",
|
||||
"prisma": "^4.1.0",
|
||||
"semver": "^7.3.7",
|
||||
"terminal-link": "^2.1.1",
|
||||
"yaml": "^1.10.2"
|
||||
|
@ -114,6 +114,8 @@ model Guild {
|
||||
archive Boolean @default(true)
|
||||
blocklist Json @default("[]")
|
||||
categories Category[]
|
||||
claimButton Boolean @default(false)
|
||||
closeButton Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
errorColour String @default("Red")
|
||||
feedback Feedback[]
|
||||
|
@ -1,4 +1,8 @@
|
||||
command:
|
||||
buttons:
|
||||
create:
|
||||
emoji: '🎫'
|
||||
text: 'Create a ticket'
|
||||
commands:
|
||||
log:
|
||||
admin:
|
||||
changes: 'Changes'
|
||||
@ -6,16 +10,21 @@ log:
|
||||
joined: '{user} {verb} {targetType}'
|
||||
target:
|
||||
category: 'a category'
|
||||
panel: 'a panel'
|
||||
question: 'a question'
|
||||
settings: 'the settings'
|
||||
title:
|
||||
joined: '{targetType} {verb}'
|
||||
target:
|
||||
category: 'Category'
|
||||
panel: 'Panel'
|
||||
question: 'Question'
|
||||
settings: 'Settings'
|
||||
verb:
|
||||
create: 'created'
|
||||
delete: 'deleted'
|
||||
update: 'updated'
|
||||
ticket:
|
||||
tickets:
|
||||
menus:
|
||||
panel:
|
||||
placeholder: 'Select a ticket category'
|
@ -5,7 +5,7 @@ const {
|
||||
const { diff: getDiff } = require('object-diffy');
|
||||
|
||||
|
||||
const exists = thing => (typeof thing === 'string' && thing.length > 0) && thing !== null && thing !== undefined;
|
||||
const exists = thing => (typeof thing === 'string' && thing.length > 0) && (thing !== null && thing !== undefined);
|
||||
|
||||
const arrToObj = obj => {
|
||||
for (const key in obj) {
|
||||
@ -26,7 +26,7 @@ function makeDiff({
|
||||
for (const key in diff) {
|
||||
if (key === 'createdAt') continue; // object-diffy doesn't like dates
|
||||
const from = exists(diff[key].from) ? `- ${String(diff[key].from).replace(/\n/g, '\\n')}\n` : '';
|
||||
const to = exists(diff[key].to) ? `+ ${String(diff[key].to).replace(/\n/g, '\\n')}\n` : '';
|
||||
const to = exists(diff[key].to) ? `+ ${String(diff[key].to).replace(/\n/g, '\\n')}\n` : '';
|
||||
fields.push({
|
||||
inline: true,
|
||||
name: key,
|
||||
@ -70,6 +70,10 @@ async function logAdminEvent(client, {
|
||||
where: { id: guildId },
|
||||
});
|
||||
if (!settings.logChannel) return;
|
||||
const colour = action === 'create'
|
||||
? 'Green' : action === 'update'
|
||||
? 'Orange' : action === 'delete'
|
||||
? 'Red' : 'Default';
|
||||
const getMessage = client.i18n.getLocale(settings.locale);
|
||||
const i18nOptions = {
|
||||
user: `<@${user.id}>`,
|
||||
@ -79,7 +83,7 @@ async function logAdminEvent(client, {
|
||||
if (!channel) return;
|
||||
const embeds = [
|
||||
new EmbedBuilder()
|
||||
.setColor('Orange')
|
||||
.setColor(colour)
|
||||
.setAuthor({
|
||||
iconURL: user.avatarURL(),
|
||||
name: user.username,
|
||||
@ -105,7 +109,7 @@ async function logAdminEvent(client, {
|
||||
if (diff && diff.original) {
|
||||
embeds.push(
|
||||
new EmbedBuilder()
|
||||
.setColor('Orange')
|
||||
.setColor(colour)
|
||||
.setTitle(getMessage('log.admin.changes'))
|
||||
.setFields(makeDiff(diff)),
|
||||
);
|
||||
|
141
src/routes/api/admin/guilds/[guild]/panels.js
Normal file
141
src/routes/api/admin/guilds/[guild]/panels.js
Normal file
@ -0,0 +1,141 @@
|
||||
const {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle: {
|
||||
Primary,
|
||||
Secondary,
|
||||
},
|
||||
ChannelType: { GuildText },
|
||||
EmbedBuilder,
|
||||
SelectMenuBuilder,
|
||||
SelectMenuOptionBuilder,
|
||||
} = require('discord.js');
|
||||
const emoji = require('node-emoji');
|
||||
const { logAdminEvent } = require('../../../../../lib/logging');
|
||||
|
||||
module.exports.post = fastify => ({
|
||||
handler: async (req, res) => {
|
||||
/** @type {import('client')} */
|
||||
const client = res.context.config.client;
|
||||
const guild = client.guilds.cache.get(req.params.guild);
|
||||
const data = req.body;
|
||||
|
||||
const settings = await client.prisma.guild.findUnique({
|
||||
select: {
|
||||
categories: true,
|
||||
footer: true,
|
||||
locale: true,
|
||||
primaryColour: true,
|
||||
},
|
||||
where: { id: guild.id },
|
||||
});
|
||||
const getMessage = client.i18n.getLocale(settings.locale);
|
||||
const categories = settings.categories.filter(c => data.categories.includes(c.id));
|
||||
if (categories.length === 0) throw new Error('No categories');
|
||||
if (categories.length !== 1 && data.type === 'MESSAGE') throw new Error('Invalid number of categories for panel type');
|
||||
|
||||
let channel;
|
||||
if (data.channel) {
|
||||
channel = await client.channels.fetch(data.channel);
|
||||
} else {
|
||||
const allow = ['ViewChannel', 'ReadMessageHistory'];
|
||||
if (data.type === 'MESSAGE') allow.push('SendMessages');
|
||||
channel = await guild.channels.create({
|
||||
name: 'create-a-ticket',
|
||||
permissionOverwrites: [
|
||||
{
|
||||
allow,
|
||||
deny: ['AddReactions', 'AttachFiles'],
|
||||
id: guild.roles.everyone,
|
||||
},
|
||||
],
|
||||
position: 1,
|
||||
rateLimitPerUser: 15,
|
||||
reason: 'New ticket panel',
|
||||
type: GuildText,
|
||||
});
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor(settings.primaryColour)
|
||||
.setTitle(data.title)
|
||||
.setFooter({
|
||||
iconURL: guild.iconURL(),
|
||||
text: settings.footer,
|
||||
});
|
||||
|
||||
if (data.description) embed.setDescription(data.description);
|
||||
if (data.image) embed.setImage(data.image);
|
||||
if (data.thumbnail) embed.setThumbnail(data.thumbnail);
|
||||
|
||||
if (data.type === 'MESSAGE') {
|
||||
await channel.send({ embeds: [embed] });
|
||||
} else {
|
||||
const components = [];
|
||||
|
||||
if (categories.length === 1) {
|
||||
components.push(
|
||||
new ButtonBuilder()
|
||||
.setCustomId(JSON.stringify({
|
||||
action: 'createTicket',
|
||||
target: categories[0].id,
|
||||
}))
|
||||
.setStyle(Primary)
|
||||
.setLabel(getMessage('buttons.create.text'))
|
||||
.setEmoji(getMessage('buttons.create.emoji')),
|
||||
);
|
||||
} else {
|
||||
if (data.type === 'BUTTON') {
|
||||
components.push(
|
||||
...categories.map(category =>
|
||||
new ButtonBuilder()
|
||||
.setCustomId(JSON.stringify({
|
||||
action: 'createTicket',
|
||||
target: category.id,
|
||||
}))
|
||||
.setStyle(Secondary)
|
||||
.setLabel(category.name)
|
||||
.setEmoji(emoji.hasEmoji(category.emoji) ? emoji.get(category.emoji) : { id: category.emoji }),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
components.push(
|
||||
new SelectMenuBuilder()
|
||||
.setCustomId('createTicket')
|
||||
.setPlaceholder(getMessage('menus.panel.placeholder'))
|
||||
.setOptions(
|
||||
categories.map(category =>
|
||||
new SelectMenuOptionBuilder()
|
||||
.setValue(String(category.id))
|
||||
.setLabel(category.name)
|
||||
.setDescription(category.description)
|
||||
.setEmoji(emoji.hasEmoji(category.emoji) ? emoji.get(category.emoji) : { id: category.emoji }),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await channel.send({
|
||||
components: [
|
||||
new ActionRowBuilder()
|
||||
.setComponents(components),
|
||||
],
|
||||
embeds: [embed],
|
||||
});
|
||||
}
|
||||
|
||||
logAdminEvent(client, {
|
||||
action: 'create',
|
||||
guildId: guild.id,
|
||||
target: {
|
||||
id: channel.toString(),
|
||||
type: 'panel',
|
||||
},
|
||||
userId: req.user.payload.id,
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
onRequest: [fastify.authenticate, fastify.isAdmin],
|
||||
});
|
Loading…
Reference in New Issue
Block a user