# This is a combination of 12 commits.
# This is the 1st commit message: Initial commit # This is the commit message #2: added whole syswtem becuz i forgot to keep up with the github # This is the commit message #3: hihi hiha # This is the commit message #4: added startServer.sh # This is the commit message #5: hihi hiha # This is the commit message #6: fixed some packages # This is the commit message #7: fixed every bug with the stupid oop # This is the commit message #8: Revert "fixed every bug with the stupid oop" This reverts commit d2255863aa44e2504f9f2cec9e1ae5d1094cb9cd. # This is the commit message #9: added prevention of breaking the system by manually filling in the project id # This is the commit message #10: fixed bug when adding bot # This is the commit message #11: made user-id not just count up from 0 # This is the commit message #12: fixed the issue where if you load project page it woulnt show the commands until you refresh the page
This commit is contained in:
130
.gitignore
vendored
Executable file
130
.gitignore
vendored
Executable file
@@ -0,0 +1,130 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
2
README.md
Executable file
2
README.md
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
# PS-Discord-BotBuilder
|
||||||
|
a wesbite to make discord bots
|
||||||
55
example_bot/bot.js
Executable file
55
example_bot/bot.js
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
const { Client, Collection, Events, GatewayIntentBits } = require('discord.js');
|
||||||
|
const { updateCommands } = require("./updateCommands");
|
||||||
|
const { token } = require('./config.json');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
|
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||||
|
updateCommands();
|
||||||
|
|
||||||
|
|
||||||
|
/** REGISTER COMMANDS **/
|
||||||
|
client.commands = new Collection();
|
||||||
|
const foldersPath = path.join(__dirname, 'commands');
|
||||||
|
const commandFolders = fs.readdirSync(foldersPath);
|
||||||
|
|
||||||
|
for (const folder of commandFolders) {
|
||||||
|
const commandsPath = path.join(foldersPath, folder);
|
||||||
|
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||||
|
for (const file of commandFiles) {
|
||||||
|
const filePath = path.join(commandsPath, file);
|
||||||
|
const command = require(filePath);
|
||||||
|
if ('data' in command && 'execute' in command) {
|
||||||
|
client.commands.set(command.data.name, command);
|
||||||
|
} else {
|
||||||
|
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SLASH COMMAND HANDLER **/
|
||||||
|
client.on(Events.InteractionCreate, async interaction => {
|
||||||
|
if (interaction.isChatInputCommand()) {
|
||||||
|
const command = client.commands.get(interaction.commandName);
|
||||||
|
if (command) {
|
||||||
|
try {
|
||||||
|
await command.execute(interaction);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
if (!(interaction.replied || interaction.deferred)) {
|
||||||
|
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(`No command matching ${interaction.commandName} was found.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/** READY SEQUENCE **/
|
||||||
|
client.once(Events.ClientReady, c => {
|
||||||
|
console.log(`Ready! Logged in as ${c.user.tag}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.login(token);
|
||||||
269
example_bot/package-lock.json
generated
Executable file
269
example_bot/package-lock.json
generated
Executable file
@@ -0,0 +1,269 @@
|
|||||||
|
{
|
||||||
|
"name": "example_bot",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"discord.js": "^14.14.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/builders": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/formatters": "^0.3.3",
|
||||||
|
"@discordjs/util": "^1.0.2",
|
||||||
|
"@sapphire/shapeshift": "^3.9.3",
|
||||||
|
"discord-api-types": "0.37.61",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"ts-mixer": "^6.0.3",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/collection": {
|
||||||
|
"version": "1.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
|
||||||
|
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/formatters": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz",
|
||||||
|
"integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==",
|
||||||
|
"dependencies": {
|
||||||
|
"discord-api-types": "0.37.61"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/rest": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/collection": "^2.0.0",
|
||||||
|
"@discordjs/util": "^1.0.2",
|
||||||
|
"@sapphire/async-queue": "^1.5.0",
|
||||||
|
"@sapphire/snowflake": "^3.5.1",
|
||||||
|
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||||
|
"discord-api-types": "0.37.61",
|
||||||
|
"magic-bytes.js": "^1.5.0",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"undici": "5.27.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/util": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/ws": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/collection": "^2.0.0",
|
||||||
|
"@discordjs/rest": "^2.1.0",
|
||||||
|
"@discordjs/util": "^1.0.2",
|
||||||
|
"@sapphire/async-queue": "^1.5.0",
|
||||||
|
"@types/ws": "^8.5.9",
|
||||||
|
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||||
|
"discord-api-types": "0.37.61",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"ws": "^8.14.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@fastify/busboy": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sapphire/async-queue": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sapphire/shapeshift": {
|
||||||
|
"version": "3.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz",
|
||||||
|
"integrity": "sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sapphire/snowflake": {
|
||||||
|
"version": "3.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz",
|
||||||
|
"integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.1.tgz",
|
||||||
|
"integrity": "sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/ws": {
|
||||||
|
"version": "8.5.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
|
||||||
|
"integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vladfrangu/async_event_emitter": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=v14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/discord-api-types": {
|
||||||
|
"version": "0.37.61",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz",
|
||||||
|
"integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw=="
|
||||||
|
},
|
||||||
|
"node_modules/discord.js": {
|
||||||
|
"version": "14.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz",
|
||||||
|
"integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/builders": "^1.7.0",
|
||||||
|
"@discordjs/collection": "1.5.3",
|
||||||
|
"@discordjs/formatters": "^0.3.3",
|
||||||
|
"@discordjs/rest": "^2.1.0",
|
||||||
|
"@discordjs/util": "^1.0.2",
|
||||||
|
"@discordjs/ws": "^1.0.2",
|
||||||
|
"@sapphire/snowflake": "3.5.1",
|
||||||
|
"@types/ws": "8.5.9",
|
||||||
|
"discord-api-types": "0.37.61",
|
||||||
|
"fast-deep-equal": "3.1.3",
|
||||||
|
"lodash.snakecase": "4.1.1",
|
||||||
|
"tslib": "2.6.2",
|
||||||
|
"undici": "5.27.2",
|
||||||
|
"ws": "8.14.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-deep-equal": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
|
"node_modules/lodash.snakecase": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
|
||||||
|
},
|
||||||
|
"node_modules/magic-bytes.js": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw=="
|
||||||
|
},
|
||||||
|
"node_modules/ts-mixer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ=="
|
||||||
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||||
|
},
|
||||||
|
"node_modules/undici": {
|
||||||
|
"version": "5.27.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz",
|
||||||
|
"integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/busboy": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.14.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
|
||||||
|
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
example_bot/package.json
Executable file
5
example_bot/package.json
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"discord.js": "^14.14.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
82
example_bot/updateCommands.js
Executable file
82
example_bot/updateCommands.js
Executable file
@@ -0,0 +1,82 @@
|
|||||||
|
const { REST, Routes } = require('discord.js');
|
||||||
|
const { clientId, token } = require('./config.json');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
|
const generateCommandFile = (command) => {
|
||||||
|
return `const { SlashCommandBuilder } = require('discord.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('${command.name}')
|
||||||
|
.setDescription('${command.description}'),
|
||||||
|
async execute(interaction) {
|
||||||
|
await interaction.reply('${command.response}');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const updateCommands = () => {
|
||||||
|
const commands = [];
|
||||||
|
const foldersPath = path.join(__dirname, 'commands');
|
||||||
|
const utilityFolderPath = path.join(foldersPath, 'utility');
|
||||||
|
|
||||||
|
// Delete all files from ./commands/utility/ before creating new ones
|
||||||
|
fs.readdirSync(utilityFolderPath).forEach((file) => {
|
||||||
|
const filePath = path.join(utilityFolderPath, file);
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
console.log(`Deleted ${file}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// CREAYE ALL THE COMMAND FILES HERE (OVERWRITE THEM IF THEY ALREADY EXSIST)
|
||||||
|
const { commands: jsonCommands } = require('./config.json');
|
||||||
|
for (const command of jsonCommands) {
|
||||||
|
const commandFileName = `${command.name}.js`;
|
||||||
|
const commandFilePath = path.join(foldersPath, `utility/${commandFileName}`);
|
||||||
|
|
||||||
|
if (!fs.existsSync(commandFilePath)) {
|
||||||
|
// If the command file doesn't exist, create it
|
||||||
|
fs.writeFileSync(commandFilePath, generateCommandFile(command));
|
||||||
|
console.log(`Created ${commandFileName}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const folder of fs.readdirSync(foldersPath)) {
|
||||||
|
const commandsPath = path.join(foldersPath, folder);
|
||||||
|
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||||
|
for (const file of commandFiles) {
|
||||||
|
const filePath = path.join(commandsPath, file);
|
||||||
|
const command = require(filePath);
|
||||||
|
if ('data' in command && 'execute' in command) {
|
||||||
|
commands.push(command.data.toJSON());
|
||||||
|
} else {
|
||||||
|
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rest = new REST().setToken(token);
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
console.log(`⚙️ Started refreshing ${commands.length} application (/) commands.`);
|
||||||
|
|
||||||
|
const data = await rest.put(
|
||||||
|
Routes.applicationCommands(clientId),
|
||||||
|
{ body: commands },
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`✅ Successfully reloaded ${data.length} application (/) commands.`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`❌ ${error}`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
updateCommands
|
||||||
|
}
|
||||||
13
hash.js
Executable file
13
hash.js
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
|
||||||
|
// Password to be hashed
|
||||||
|
const passwordToHash = 'password_to_hash';
|
||||||
|
|
||||||
|
// Hashing the password with bcrypt
|
||||||
|
bcrypt.hash(passwordToHash, 10, (err, hash) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error hashing password:', err);
|
||||||
|
} else {
|
||||||
|
console.log('Hashed password:', hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
22
httpdocs/dashboard.html
Executable file
22
httpdocs/dashboard.html
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Dashboard</title>
|
||||||
|
<link rel="stylesheet" href="/public.css">
|
||||||
|
<link rel="stylesheet" href="/dashboard.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
||||||
|
<script src="bots.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="main">
|
||||||
|
<div id="container">
|
||||||
|
<h1>Choose the bot you want to edit</h1>
|
||||||
|
<div id="grid" class="bot-list">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
httpdocs/login.html
Executable file
24
httpdocs/login.html
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="/login.css">
|
||||||
|
<link rel="stylesheet" href="/public.css">
|
||||||
|
<title>Login</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="login-container">
|
||||||
|
<h2>Login to DiscordBotBuilder</h2>
|
||||||
|
<form action="/" method="POST">
|
||||||
|
<label for="username">Username:</label>
|
||||||
|
<input type="text" id="username" name="username" required>
|
||||||
|
|
||||||
|
<label for="password">Password:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
26
httpdocs/project.html
Executable file
26
httpdocs/project.html
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Project</title>
|
||||||
|
<link rel="stylesheet" href="/public.css">
|
||||||
|
<link rel="stylesheet" href="/project.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
||||||
|
<script src="/project.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="main">
|
||||||
|
<div id="container" onload="loadData()">
|
||||||
|
<h1 id="title"></h1>
|
||||||
|
<button id="editProjectName" onclick="editProjectName()">Edit Name</button>
|
||||||
|
<button id="exportProject" onclick="exportProject()">Export Project</button>
|
||||||
|
<h2 id="description"></h2><br>
|
||||||
|
<h3 id="section-title">Commands:</h3>
|
||||||
|
<div id="grid" class="bot-list">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2089
package-lock.json
generated
Executable file
2089
package-lock.json
generated
Executable file
File diff suppressed because it is too large
Load Diff
23
package.json
Executable file
23
package.json
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "crud-nodejs",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"archiver": "^6.0.1",
|
||||||
|
"bcrypt": "^5.1.1",
|
||||||
|
"body-parser": "^1.20.2",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"express-session": "^1.17.3",
|
||||||
|
"fs-extra": "^11.2.0",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
|
"mysql2": "^3.6.5",
|
||||||
|
"nodemon": "^3.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
109
scripts/bots.js
Executable file
109
scripts/bots.js
Executable file
@@ -0,0 +1,109 @@
|
|||||||
|
function createNewBot() {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Create Bot',
|
||||||
|
html:
|
||||||
|
'<label for="name">Name</label>' +
|
||||||
|
'<input id="name" class="swal2-input" placeholder="Project Name">' +
|
||||||
|
'<label for="id">Bot ID</label>' +
|
||||||
|
'<input id="id" class="swal2-input" placeholder="Bot ID">' +
|
||||||
|
'<label for="token">Token</label>' +
|
||||||
|
'<input id="token" class="swal2-input" placeholder="Bot Token">',
|
||||||
|
focusConfirm: false,
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
confirmButtonText: 'Create',
|
||||||
|
preConfirm: () => {
|
||||||
|
const name = Swal.getPopup().querySelector('#name').value;
|
||||||
|
const token = Swal.getPopup().querySelector('#token').value;
|
||||||
|
const clientID = Swal.getPopup().querySelector('#id').value;
|
||||||
|
|
||||||
|
// Check if both name and token are filled
|
||||||
|
if (!name || !token || !clientID) {
|
||||||
|
Swal.showValidationMessage('Please fill in both the Name and Token fields');
|
||||||
|
return false; // Prevent closing the modal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the POST request to /create-bot
|
||||||
|
return fetch('/create-bot', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name,
|
||||||
|
token: token,
|
||||||
|
clientId: clientID,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
Swal.fire('Bot Created!', 'Your bot has been successfully created.', 'success');
|
||||||
|
refreshList();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
|
Swal.fire('Error', 'There was an error creating the bot.', 'error');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function refreshList() {
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '/fetch-bots', true);
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (xhr.status == 200) {
|
||||||
|
let jsonResponse = JSON.parse(xhr.responseText);
|
||||||
|
|
||||||
|
const gridContainer = document.getElementById("grid");
|
||||||
|
gridContainer.innerHTML = '';
|
||||||
|
|
||||||
|
|
||||||
|
const specialButton = document.createElement('div');
|
||||||
|
specialButton.classList.add('grid-btn');
|
||||||
|
specialButton.id = 'special-button';
|
||||||
|
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.innerText = 'NEW BOT';
|
||||||
|
button.id = 'add-bot-button';
|
||||||
|
button.onclick = createNewBot;
|
||||||
|
|
||||||
|
specialButton.appendChild(button);
|
||||||
|
gridContainer.appendChild(specialButton);
|
||||||
|
|
||||||
|
jsonResponse.forEach(bot => {
|
||||||
|
const gridItem = document.createElement('div');
|
||||||
|
gridItem.classList.add('grid-btn');
|
||||||
|
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.innerText = bot.name;
|
||||||
|
button.dataset.projectID=bot.id;
|
||||||
|
button.addEventListener("click", (event)=>{
|
||||||
|
window.location.href=`/projects/${event.target.dataset.projectID}/`
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gridItem.appendChild(button);
|
||||||
|
gridContainer.appendChild(gridItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('Request failed. Status: ' + xhr.status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
refreshList();
|
||||||
|
});
|
||||||
266
scripts/project.js
Executable file
266
scripts/project.js
Executable file
@@ -0,0 +1,266 @@
|
|||||||
|
function getProjectId() {
|
||||||
|
let currentPage = window.location.href;
|
||||||
|
return parseInt(currentPage.split('/projects/')[1].split('/')[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editProjectName(){
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Enter Project Name',
|
||||||
|
html:
|
||||||
|
'<input id="projectName" class="swal2-input" placeholder="Project Name">',
|
||||||
|
focusConfirm: false,
|
||||||
|
preConfirm: () => {
|
||||||
|
const name = Swal.getPopup().querySelector('#projectName').value;
|
||||||
|
|
||||||
|
// Check if both name and token are filled
|
||||||
|
if (!name) {
|
||||||
|
Swal.showValidationMessage('Please fill in all the fields');
|
||||||
|
return false; // Prevent closing the modal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the POST request to /create-bot
|
||||||
|
return fetch('/rename-project', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name,
|
||||||
|
id: getProjectId()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
Swal.fire('Project Rename!', 'Your project has been successfully been renamed.', 'success').then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
|
Swal.fire('Error', 'There was an error creating the bot.', 'error');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportProject() {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Exporting...",
|
||||||
|
text: "Your project export is in progress.",
|
||||||
|
icon: "info",
|
||||||
|
showConfirmButton: false,
|
||||||
|
allowOutsideClick: false,
|
||||||
|
allowEscapeKey: false
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(`/export?id=${getProjectId()}`, { method: 'POST' })
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Request failed. Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.blob();
|
||||||
|
})
|
||||||
|
.then(blob => {
|
||||||
|
// Create a link element
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// Set the download attribute and trigger a click
|
||||||
|
link.download = `bot_builds_${getProjectId()}.zip`;
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
window.URL.revokeObjectURL(link.href);
|
||||||
|
|
||||||
|
Swal.close();
|
||||||
|
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Exported!",
|
||||||
|
text: "Your project has been exported.",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
loadData();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
Swal.fire({
|
||||||
|
title: "Export Failed",
|
||||||
|
text: "There was an error exporting your project.",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createNewCommand() {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Create Command',
|
||||||
|
html:
|
||||||
|
'<label for="name">Command Name</label>' +
|
||||||
|
'<input id="name" class="swal2-input" placeholder="Command Name">' +
|
||||||
|
'<label for="description">Description</label>' +
|
||||||
|
'<input id="description" class="swal2-input" placeholder="Command Description">'+
|
||||||
|
'<label for="response">Command Response</label>' +
|
||||||
|
'<input id="response" class="swal2-input" placeholder="Command Response">',
|
||||||
|
focusConfirm: false,
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
confirmButtonText: 'Create',
|
||||||
|
preConfirm: () => {
|
||||||
|
const name = Swal.getPopup().querySelector('#name').value;
|
||||||
|
const description = Swal.getPopup().querySelector('#description').value;
|
||||||
|
const response = Swal.getPopup().querySelector('#response').value;
|
||||||
|
|
||||||
|
// Check if both name and token are filled
|
||||||
|
if (!name || !description || !response) {
|
||||||
|
Swal.showValidationMessage('Please fill in all the fields');
|
||||||
|
return false; // Prevent closing the modal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the POST request to /create-bot
|
||||||
|
return fetch('/create-command', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
response: response,
|
||||||
|
projectId: getProjectId()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
Swal.fire('Command Created!', 'Your command has been successfully created.', 'success');
|
||||||
|
loadData();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
|
Swal.fire('Error', 'There was an error creating the bot.', 'error');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteCommand (event) {
|
||||||
|
const commandId=event.target.dataset.commandId;
|
||||||
|
const projectId = getProjectId();
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "Are you sure you want to delete this command?",
|
||||||
|
text: "You won't be able to revert this!",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
cancelButtonColor: "#d33",
|
||||||
|
confirmButtonText: "Yes, delete it!"
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", `/delete-command?commandId=${commandId}&projectId=${projectId}`);
|
||||||
|
xhr.send();
|
||||||
|
xhr.onload = () => {
|
||||||
|
if (xhr.status == 200){
|
||||||
|
Swal.fire({
|
||||||
|
title: "Deleted!",
|
||||||
|
text: "Your command has been deleted.",
|
||||||
|
icon: "success"
|
||||||
|
})
|
||||||
|
loadData();
|
||||||
|
} else {
|
||||||
|
console.error('Request failed. Status: ' + xhr.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function loadData() {
|
||||||
|
let projectId = getProjectId()
|
||||||
|
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', `/fetch-project-data?id=${projectId}`, true);
|
||||||
|
xhr.send();
|
||||||
|
xhr.onload = () => {
|
||||||
|
if (xhr.status == 200){
|
||||||
|
|
||||||
|
let jsonResponse = JSON.parse(xhr.responseText);
|
||||||
|
if (jsonResponse != {}){
|
||||||
|
document.querySelector("#title").innerHTML = jsonResponse.projectName.toUpperCase();
|
||||||
|
document.querySelector("#description").innerHTML = "Project Id: "+jsonResponse.projectId;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Request failed. Status: ' + xhr.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let xhr2 = new XMLHttpRequest();
|
||||||
|
xhr2.open('GET', `/fetch-commands?id=${projectId}`, true);
|
||||||
|
xhr2.send();
|
||||||
|
|
||||||
|
xhr2.onload = function () {
|
||||||
|
if (xhr2.status == 200) {
|
||||||
|
let jsonResponse = JSON.parse(xhr2.responseText);
|
||||||
|
console.log(jsonResponse)
|
||||||
|
|
||||||
|
const gridContainer = document.getElementById("grid");
|
||||||
|
gridContainer.innerHTML = '';
|
||||||
|
|
||||||
|
|
||||||
|
const specialButton = document.createElement('div');
|
||||||
|
specialButton.classList.add('grid-btn');
|
||||||
|
specialButton.id = 'special-button';
|
||||||
|
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.innerText = 'NEW COMMAND';
|
||||||
|
button.id = 'add-command-button';
|
||||||
|
button.onclick = createNewCommand;
|
||||||
|
|
||||||
|
specialButton.appendChild(button);
|
||||||
|
gridContainer.appendChild(specialButton);
|
||||||
|
|
||||||
|
jsonResponse.forEach(command => {
|
||||||
|
const gridItem = document.createElement('div');
|
||||||
|
gridItem.classList.add('grid-btn');
|
||||||
|
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.innerHTML = "<strong class='command-bold'>"+command.name+"</strong><br>"+command.description;
|
||||||
|
button.dataset.commandId=command.id;
|
||||||
|
button.dataset.commandResponse=command.response;
|
||||||
|
button.addEventListener("click", (event)=>{
|
||||||
|
deleteCommand(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gridItem.appendChild(button);
|
||||||
|
gridContainer.appendChild(gridItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('Request failed. Status: ' + xhr2.status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
loadData();
|
||||||
|
});
|
||||||
390
server.js
Executable file
390
server.js
Executable file
@@ -0,0 +1,390 @@
|
|||||||
|
/*
|
||||||
|
Importing all the required packages
|
||||||
|
*/
|
||||||
|
const express = require('express');
|
||||||
|
const session = require('express-session');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const mysql = require('mysql');
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
const archiver = require('archiver');
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creating some handy constants
|
||||||
|
*/
|
||||||
|
const documentRoot = `${__dirname}/httpdocs`
|
||||||
|
const webserverPort = 3000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MySQL connection.
|
||||||
|
* @returns {Object} MySQL connection object
|
||||||
|
*/
|
||||||
|
const createConnection = () => {
|
||||||
|
return mysql.createConnection({
|
||||||
|
host: "localhost",
|
||||||
|
user: "dcBB",
|
||||||
|
password: "DiscordBotBuilder",
|
||||||
|
database: "PS_DISCORD_BOT_BUILDER",
|
||||||
|
connectTimeout: 20000,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting up the express webserver
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
app.use(express.static("styles"))
|
||||||
|
app.use(express.static("scripts"))
|
||||||
|
|
||||||
|
app.use(session({secret: 'secret',resave: true,saveUninitialized: true}));
|
||||||
|
|
||||||
|
app.use( bodyParser.json() );
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
app.use(bodyParser.urlencoded({extended: true}));
|
||||||
|
app.use(express.urlencoded({extended: true}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Setting up the login system
|
||||||
|
*/
|
||||||
|
const requireLogin = (req, res, next) => {
|
||||||
|
if (!req.session.userId) {
|
||||||
|
res.redirect('/');
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Setting up all the website pages
|
||||||
|
*/
|
||||||
|
app.get("/", (req, res) => {
|
||||||
|
res.sendFile(`${documentRoot}/login.html`);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
app.get("/dashboard",requireLogin, (req, res) => {
|
||||||
|
res.sendFile(`${documentRoot}/dashboard.html`);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/projects/:projectId/", requireLogin, (req, res)=>{
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const sql = "SELECT MAX(project_id) as maxProjectID FROM Projects";
|
||||||
|
con.query(sql, (err, results) => {
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
const maxProjectID = results[0].maxProjectID;
|
||||||
|
|
||||||
|
if (parseInt(maxProjectID) < parseInt(req.params.projectId)) return res.redirect("/dashboard");
|
||||||
|
else {
|
||||||
|
res.sendFile(`${documentRoot}/project.html`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Setting up all the website posting pages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.post("/", (req, res) => {
|
||||||
|
/**
|
||||||
|
* Login Validation
|
||||||
|
*/
|
||||||
|
const { username, password } = req.body;
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const sql = "SELECT * FROM Users WHERE username = ?";
|
||||||
|
con.query(sql, [username], (err, results) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error executing login query:', err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
con.end();
|
||||||
|
|
||||||
|
if (results.length > 0) {
|
||||||
|
bcrypt.compare(password, results[0].password, (bcryptErr, isMatch) => {
|
||||||
|
if (bcryptErr) {
|
||||||
|
console.error('Error comparing passwords:', bcryptErr);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isMatch) {
|
||||||
|
req.session.userId = results[0].user_id;
|
||||||
|
res.redirect('/dashboard');
|
||||||
|
} else {
|
||||||
|
res.send('Invalid username or password');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.send('Invalid username or password');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Commands Grid
|
||||||
|
*/
|
||||||
|
app.get("/fetch-commands", requireLogin, (req, res)=> {
|
||||||
|
const projectId = req.query.id;
|
||||||
|
const userId = req.session.userId;
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||||
|
con.query(ownerCheck, [projectId, userId], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
if (results.length != 1)return res.json({});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const sql = "SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?";
|
||||||
|
con.query(sql, [projectId], (err, results) => {
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < results.length; i++){
|
||||||
|
result.push({"name": results[i]["command_name"], "description": results[i]["command_description"], "id": results[i]["command_id"], "response": results[i]["command_response"]});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/fetch-project-data", requireLogin, (req, res)=>{
|
||||||
|
const projectId = req.query.id;
|
||||||
|
const userId = req.session.userId;
|
||||||
|
|
||||||
|
let response = {};
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const sql = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?";
|
||||||
|
con.query(sql, [projectId, userId], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
if (results.length != 1) return res.json(response);
|
||||||
|
con.end();
|
||||||
|
|
||||||
|
response["projectName"] = results[0]["project_name"];
|
||||||
|
response["projectId"] = projectId;
|
||||||
|
|
||||||
|
res.json(response)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/delete-command", requireLogin, (req, res)=> {
|
||||||
|
const projectId = req.query.projectId;
|
||||||
|
const commandId = req.query.commandId;
|
||||||
|
const userId = req.session.userId;
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||||
|
con.query(ownerCheck, [projectId, userId], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
if (results.length != 1)return res.json({});
|
||||||
|
|
||||||
|
const sql = "DELETE FROM Commands WHERE command_id=?";
|
||||||
|
con.query(sql, [commandId], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
|
||||||
|
res.status(200).send("true");
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post("/create-command", requireLogin, (req, res)=> {
|
||||||
|
let name = req.body.name;
|
||||||
|
let description = req.body.description;
|
||||||
|
let response = req.body.response;
|
||||||
|
|
||||||
|
name = name.replace(" ", "-");
|
||||||
|
|
||||||
|
let projectId = req.body.projectId;
|
||||||
|
let owner = req.session.userId;
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||||
|
con.query(ownerCheck, [projectId, owner], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
if (results.length != 1)return;
|
||||||
|
|
||||||
|
const sql = "INSERT INTO Commands (project_id, command_name, command_description, command_response) VALUES (?,?,?,?)";
|
||||||
|
con.query(sql, [projectId, name, description, response], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
res.status(200).send("true");
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Projects Grid
|
||||||
|
*/
|
||||||
|
app.get("/fetch-bots", requireLogin, (req, res)=> {
|
||||||
|
const sql = "SELECT project_name, project_id FROM Projects WHERE project_owner = ?";
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
con.query(sql, [req.session.userId], (err, results) => {
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < results.length; i++){
|
||||||
|
result.push({"name": results[i]["project_name"], "id": results[i]["project_id"]});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/create-bot", requireLogin, (req, res)=> {
|
||||||
|
let name = req.body.name;
|
||||||
|
let token = req.body.token;
|
||||||
|
let clientId = req.body.clientId;
|
||||||
|
let owner = req.session.userId;
|
||||||
|
|
||||||
|
if (name.length > 20)return;
|
||||||
|
|
||||||
|
let bot = {"name": name}
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
var sql = "INSERT INTO Projects (project_name, project_owner, bot_token, bot_id) VALUES (?, ?, ?, ?)";
|
||||||
|
con.query(sql, [name, owner, token, clientId], function (err, result) {
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
res.send('true');
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post("/rename-project", requireLogin, (req,res)=>{
|
||||||
|
let name = req.body.name;
|
||||||
|
let projectId = req.body.id;
|
||||||
|
let userId = req.session.userId;
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||||
|
con.query(ownerCheck, [projectId, userId], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
if (results.length != 1)return;
|
||||||
|
|
||||||
|
const sql = "UPDATE Projects SET project_name=? WHERE project_id=?";
|
||||||
|
con.query(sql, [name, projectId], (err, results)=>{
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
res.status(200).send("true");
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
app.post("/export", requireLogin, (req, res) => {
|
||||||
|
const projectId = req.query.id;
|
||||||
|
const userId = req.session.userId;
|
||||||
|
|
||||||
|
const con = createConnection();
|
||||||
|
|
||||||
|
const ownerCheck = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?";
|
||||||
|
con.query(ownerCheck, [projectId, userId], (err, results) => {
|
||||||
|
if (err) throw err;
|
||||||
|
if (results.length !== 1) return res.json({});
|
||||||
|
|
||||||
|
const data = results[0];
|
||||||
|
const botToken = data.bot_token;
|
||||||
|
const clientId = data.bot_id;
|
||||||
|
|
||||||
|
con.query("SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?", [projectId], (err, result) => {
|
||||||
|
if (err) throw err;
|
||||||
|
con.end();
|
||||||
|
|
||||||
|
const commands = result.map(command => {
|
||||||
|
return {
|
||||||
|
name: command.command_name,
|
||||||
|
description: command.command_description,
|
||||||
|
response: command.command_response
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const jsonContent = {
|
||||||
|
token: botToken,
|
||||||
|
clientId: clientId,
|
||||||
|
commands: commands
|
||||||
|
};
|
||||||
|
|
||||||
|
const botBuildsPath = `./bot_builds/${projectId}`;
|
||||||
|
|
||||||
|
// Create the directory if it doesn't exist
|
||||||
|
fs.ensureDirSync(botBuildsPath);
|
||||||
|
|
||||||
|
// Copy everything from "./example_bot" to "./botBuilds/{id}/"
|
||||||
|
const exampleBotPath = "./example_bot";
|
||||||
|
fs.copySync(exampleBotPath, botBuildsPath);
|
||||||
|
|
||||||
|
// Write JSON to a file in the new directory
|
||||||
|
const configFile = path.join(botBuildsPath, "config.json");
|
||||||
|
fs.writeFileSync(configFile, JSON.stringify(jsonContent, null, 2));
|
||||||
|
|
||||||
|
// Create a zip file
|
||||||
|
const outputZipPath = path.join(__dirname, `./bot_builds/${projectId}.zip`);
|
||||||
|
const outputZipStream = fs.createWriteStream(outputZipPath);
|
||||||
|
const archive = archiver('zip', {
|
||||||
|
zlib: { level: 9 }
|
||||||
|
});
|
||||||
|
|
||||||
|
outputZipStream.on('close', () => {
|
||||||
|
res.download(outputZipPath, (err) => {
|
||||||
|
if (err) throw err;
|
||||||
|
fs.removeSync(outputZipPath);
|
||||||
|
fs.removeSync(botBuildsPath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.on('error', (err) => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.pipe(outputZipStream);
|
||||||
|
archive.directory(botBuildsPath, false);
|
||||||
|
archive.finalize();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Starting up the server.
|
||||||
|
*/
|
||||||
|
app.listen(webserverPort, () => {
|
||||||
|
console.log(`Bot Builder Online at http://localhost:${webserverPort}/`)
|
||||||
|
})
|
||||||
2
startServer.sh
Executable file
2
startServer.sh
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
node server.js
|
||||||
57
styles/dashboard.css
Executable file
57
styles/dashboard.css
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
:root {
|
||||||
|
--mainMargin: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
margin: var(--mainMargin);
|
||||||
|
width: calc(100% - var(--mainMargin)*2);
|
||||||
|
height: calc(100vh - var(--mainMargin)*2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
background: var(--dark-gray);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
overflow: visible !important;
|
||||||
|
border-radius: 40px;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||||
|
-moz-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||||
|
box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#grid {
|
||||||
|
width: 90%;
|
||||||
|
height: 90%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap:5%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#grid > * {
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: var(--light-gray);
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
#special-button {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-btn > button {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: none;
|
||||||
|
border:none;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
52
styles/login.css
Executable file
52
styles/login.css
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
background: var(--discord-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
background-color: var(--dark-gray);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
padding: 30px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--light-gray);
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border: 1px solid var(--discord-blue);
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--dark-steel);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 12px;
|
||||||
|
background-color: var(--discord-blue);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: var(--medium-gray);
|
||||||
|
}
|
||||||
66
styles/project.css
Executable file
66
styles/project.css
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
:root {
|
||||||
|
--mainMargin: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
margin: var(--mainMargin);
|
||||||
|
width: calc(100% - var(--mainMargin)*2);
|
||||||
|
height: calc(100vh - var(--mainMargin)*2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
background: var(--dark-gray);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
overflow: visible !important;
|
||||||
|
border-radius: 40px;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||||
|
-moz-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||||
|
box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#grid {
|
||||||
|
width: 90%;
|
||||||
|
height: 90%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap:5%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#grid > * {
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: var(--light-gray);
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
#special-button {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-btn > button {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: none;
|
||||||
|
border:none;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.command-bold {
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
|
||||||
|
#editProjectName,
|
||||||
|
#exportProject {
|
||||||
|
color: black !important;
|
||||||
|
}
|
||||||
30
styles/public.css
Executable file
30
styles/public.css
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
:root {
|
||||||
|
--discord-blue: #7289da;
|
||||||
|
--dark-gray: #424549;
|
||||||
|
--medium-gray: #36393e;
|
||||||
|
--light-gray: #282b30;
|
||||||
|
--dark-steel: #1e2124;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 100vh !important;
|
||||||
|
background: var(--discord-blue);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swal2-input {
|
||||||
|
color: black !important;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user