mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-11-17 17:23:08 +02:00
Panels!
This commit is contained in:
parent
98b35e3a81
commit
f93d058f55
@ -9,6 +9,8 @@
|
|||||||
"contributors:generate": "all-contributors generate",
|
"contributors:generate": "all-contributors generate",
|
||||||
"keygen": "node scripts/keygen",
|
"keygen": "node scripts/keygen",
|
||||||
"lint": "eslint src scripts --ext mjs --fix",
|
"lint": "eslint src scripts --ext mjs --fix",
|
||||||
|
"start": "node .",
|
||||||
|
"studio": "npx prisma studio",
|
||||||
"test": "echo \"There's nothing to test\" && exit 1"
|
"test": "echo \"There's nothing to test\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -37,7 +39,7 @@
|
|||||||
"@fastify/cors": "^8.0.0",
|
"@fastify/cors": "^8.0.0",
|
||||||
"@fastify/jwt": "^5.0.1",
|
"@fastify/jwt": "^5.0.1",
|
||||||
"@fastify/oauth2": "^5.0.0",
|
"@fastify/oauth2": "^5.0.0",
|
||||||
"@prisma/client": "^4.0.0",
|
"@prisma/client": "^4.1.0",
|
||||||
"cryptr": "^6.0.3",
|
"cryptr": "^6.0.3",
|
||||||
"discord.js": "^14.0.2",
|
"discord.js": "^14.0.2",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
@ -50,7 +52,7 @@
|
|||||||
"node-dir": "^0.1.17",
|
"node-dir": "^0.1.17",
|
||||||
"node-emoji": "^1.11.0",
|
"node-emoji": "^1.11.0",
|
||||||
"object-diffy": "^1.0.4",
|
"object-diffy": "^1.0.4",
|
||||||
"prisma": "^4.0.0",
|
"prisma": "^4.1.0",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"terminal-link": "^2.1.1",
|
"terminal-link": "^2.1.1",
|
||||||
"yaml": "^1.10.2"
|
"yaml": "^1.10.2"
|
||||||
|
@ -114,6 +114,8 @@ model Guild {
|
|||||||
archive Boolean @default(true)
|
archive Boolean @default(true)
|
||||||
blocklist Json @default("[]")
|
blocklist Json @default("[]")
|
||||||
categories Category[]
|
categories Category[]
|
||||||
|
claimButton Boolean @default(false)
|
||||||
|
closeButton Boolean @default(false)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
errorColour String @default("Red")
|
errorColour String @default("Red")
|
||||||
feedback Feedback[]
|
feedback Feedback[]
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
command:
|
buttons:
|
||||||
|
create:
|
||||||
|
emoji: '🎫'
|
||||||
|
text: 'Create a ticket'
|
||||||
|
commands:
|
||||||
log:
|
log:
|
||||||
admin:
|
admin:
|
||||||
changes: 'Changes'
|
changes: 'Changes'
|
||||||
@ -6,16 +10,21 @@ log:
|
|||||||
joined: '{user} {verb} {targetType}'
|
joined: '{user} {verb} {targetType}'
|
||||||
target:
|
target:
|
||||||
category: 'a category'
|
category: 'a category'
|
||||||
|
panel: 'a panel'
|
||||||
question: 'a question'
|
question: 'a question'
|
||||||
settings: 'the settings'
|
settings: 'the settings'
|
||||||
title:
|
title:
|
||||||
joined: '{targetType} {verb}'
|
joined: '{targetType} {verb}'
|
||||||
target:
|
target:
|
||||||
category: 'Category'
|
category: 'Category'
|
||||||
|
panel: 'Panel'
|
||||||
question: 'Question'
|
question: 'Question'
|
||||||
settings: 'Settings'
|
settings: 'Settings'
|
||||||
verb:
|
verb:
|
||||||
create: 'created'
|
create: 'created'
|
||||||
delete: 'deleted'
|
delete: 'deleted'
|
||||||
update: 'updated'
|
update: 'updated'
|
||||||
ticket:
|
tickets:
|
||||||
|
menus:
|
||||||
|
panel:
|
||||||
|
placeholder: 'Select a ticket category'
|
@ -5,7 +5,7 @@ const {
|
|||||||
const { diff: getDiff } = require('object-diffy');
|
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 => {
|
const arrToObj = obj => {
|
||||||
for (const key in obj) {
|
for (const key in obj) {
|
||||||
@ -70,6 +70,10 @@ async function logAdminEvent(client, {
|
|||||||
where: { id: guildId },
|
where: { id: guildId },
|
||||||
});
|
});
|
||||||
if (!settings.logChannel) return;
|
if (!settings.logChannel) return;
|
||||||
|
const colour = action === 'create'
|
||||||
|
? 'Green' : action === 'update'
|
||||||
|
? 'Orange' : action === 'delete'
|
||||||
|
? 'Red' : 'Default';
|
||||||
const getMessage = client.i18n.getLocale(settings.locale);
|
const getMessage = client.i18n.getLocale(settings.locale);
|
||||||
const i18nOptions = {
|
const i18nOptions = {
|
||||||
user: `<@${user.id}>`,
|
user: `<@${user.id}>`,
|
||||||
@ -79,7 +83,7 @@ async function logAdminEvent(client, {
|
|||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
const embeds = [
|
const embeds = [
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setColor('Orange')
|
.setColor(colour)
|
||||||
.setAuthor({
|
.setAuthor({
|
||||||
iconURL: user.avatarURL(),
|
iconURL: user.avatarURL(),
|
||||||
name: user.username,
|
name: user.username,
|
||||||
@ -105,7 +109,7 @@ async function logAdminEvent(client, {
|
|||||||
if (diff && diff.original) {
|
if (diff && diff.original) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.setColor('Orange')
|
.setColor(colour)
|
||||||
.setTitle(getMessage('log.admin.changes'))
|
.setTitle(getMessage('log.admin.changes'))
|
||||||
.setFields(makeDiff(diff)),
|
.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