This commit is contained in:
Jonny_Bro (Nikita) 2023-06-22 19:36:52 +05:00
parent f61dc139f6
commit 849a93887a
96 changed files with 10351 additions and 10825 deletions

587
.d.ts vendored
View file

@ -1,342 +1,337 @@
declare module "discord-dashboard" {
let Dashboard: any
let Dashboard: any
const formTypes: formTypes
const customPagesTypes: customPagesTypes
const DISCORD_FLAGS: {
Permissions: Permissions
}
const formTypes: formTypes
const customPagesTypes: customPagesTypes
const version: string
const version: string
}
interface RateLimitSettingsObject {
windowMs: Number
max: Number
message: String
store?: any
windowMs: Number
max: Number
message: String
store?: any
}
interface Dashboard {
new (config: {
port: number
client: {
id: string
secret: string
}
redirectUri: string
domain: string
bot: any
theme: any
settings: category[]
requiredPermissions?: object,
ownerIDs: array,
useTheme404: boolean,
useThemeMaintenance: boolean,
acceptPrivacyPolicy?: boolean
noCreateServer?: boolean
SSL?: {
enabled: boolean
key: string
cert: string
}
minimizedConsoleLogs?: boolean
rateLimits?: {
manage?: RateLimitSettingsObject
guildPage?: RateLimitSettingsObject
settingsUpdatePostAPI?: RateLimitSettingsObject
discordOAuth2?: RateLimitSettingsObject
}
invite?: {
clientId: string
scopes: object
permissions: string
redirectUri: string
otherParams: string
}
supportServer?: {
slash: string
inviteUrl: string
}
guildAfterAuthorization?: {
use: boolean
guildId: string
options?: {
nickname?: string
roles?: [string]
mute?: boolean
deaf?: boolean
}
}
reportError?: (where: string, what: any) => any
assistantsSecureStorageKey?: string
}): any
DBDEvents: () => any
init: () => Promise<any>
getApp: () => any
useThirdPartyModule: (module: any) => any
new(config: {
port: number
client: {
id: string
secret: string
}
redirectUri: string
domain: string
bot: any
theme: any
settings: category[]
ownerIDs: array,
useTheme404: boolean,
useThemeMaintenance: boolean,
noCreateServer?: boolean
SSL?: {
enabled: boolean
key: string
cert: string
}
minimizedConsoleLogs?: boolean
rateLimits?: {
manage?: RateLimitSettingsObject
guildPage?: RateLimitSettingsObject
settingsUpdatePostAPI?: RateLimitSettingsObject
discordOAuth2?: RateLimitSettingsObject
}
invite?: {
clientId: string
scopes: object
permissions: string
redirectUri: string
otherParams: string
}
supportServer?: {
slash: string
inviteUrl: string
}
guildAfterAuthorization?: {
use: boolean
guildId: string
options?: {
nickname?: string
roles?: [string]
mute?: boolean
deaf?: boolean
}
}
reportError?: (where: string, what: any) => any
assistantsSecureStorageKey?: string
}): any
DBDEvents: () => any
init: () => Promise<any>
getApp: () => any
useThirdPartyModule: (module: any) => any
}
interface category {
categoryId: string
categoryName: string
categoryDescription: string
categoryOptionsList: option[]
categoryId: string
categoryName: string
categoryDescription: string
categoryOptionsList: option[]
}
interface option {
optionId?: string
optionName?: string
optionDescription?: string
title?: string
description?: string
optionType:
| {
type: string
data?: string | null
function?: any
min?: number | null
max?: number | null
disabled?: boolean | null
required?: boolean | null
themeOptions?: object | null
}
| string
getActualSet?: (options: optionOptions) => Promise<any>
setNew?: (options: optionOptions) => Promise<any>
allowedCheck?: (options: allowedCheckOption) => Promise<any>
themeOptions?: Object
optionId?: string
optionName?: string
optionDescription?: string
title?: string
description?: string
optionType:
| {
type: string
data?: string | null
function?: any
min?: number | null
max?: number | null
disabled?: boolean | null
required?: boolean | null
themeOptions?: object | null
}
| string
getActualSet?: (options: optionOptions) => Promise<any>
setNew?: (options: optionOptions) => Promise<any>
allowedCheck?: (options: allowedCheckOption) => Promise<any>
themeOptions?: Object
}
interface optionOptions {
guild: { id: string }
user: { id: string }
newData: any
guild: { id: string }
user: { id: string }
newData: any
}
interface allowedCheckOption {
guild: { id: string }
user: { id: string }
guild: { id: string }
user: { id: string }
}
interface formTypes {
select: (
list: object,
disabled?: boolean,
themeOptions?: object
) => {
type: string
data: {
keys: object
values: object
}
disabled: boolean
themeOptions: object
}
select: (
list: object,
disabled?: boolean,
themeOptions?: object
) => {
type: string
data: {
keys: object
values: object
}
disabled: boolean
themeOptions: object
}
multiSelect: (
list: object,
disabled?: boolean,
required?: boolean,
themeOptions?: object
) => {
type: string
data: {
keys: object
values: object
}
disabled: boolean | null
required: boolean | null
themeOptions: object
}
multiSelect: (
list: object,
disabled?: boolean,
required?: boolean,
themeOptions?: object
) => {
type: string
data: {
keys: object
values: object
}
disabled: boolean | null
required: boolean | null
themeOptions: object
}
input: (
placeholder?: string,
min?: number,
max?: number,
disabled?: boolean,
required?: boolean,
themeOptions?: object
) => {
type: string
data: string | null
min: number | null
max: number | null
disabled: boolean | null
required: boolean | null
themeOptions: object | null
}
input: (
placeholder?: string,
min?: number,
max?: number,
disabled?: boolean,
required?: boolean,
themeOptions?: object
) => {
type: string
data: string | null
min: number | null
max: number | null
disabled: boolean | null
required: boolean | null
themeOptions: object | null
}
textarea: (
placeholder?: string,
min?: number,
max?: number,
disabled?: boolean,
required?: boolean,
themeOptions?: object
) => {
type: string
data: string | null
min: number | null
max: number | null
disabled: boolean | null
required: boolean | null
themeOptions: object | null
}
textarea: (
placeholder?: string,
min?: number,
max?: number,
disabled?: boolean,
required?: boolean,
themeOptions?: object
) => {
type: string
data: string | null
min: number | null
max: number | null
disabled: boolean | null
required: boolean | null
themeOptions: object | null
}
switch: (
disabled?: boolean,
themeOptions?: object
) => {
type: string
disabled: boolean
themeOptions: object
}
switch: (
disabled?: boolean,
themeOptions?: object
) => {
type: string
disabled: boolean
themeOptions: object
}
checkbox: (
disabled?: boolean,
themeOptions?: object
) => {
type: string
disabled: boolean
themeOptions: object
}
checkbox: (
disabled?: boolean,
themeOptions?: object
) => {
type: string
disabled: boolean
themeOptions: object
}
channelsSelect: (
disabled?: boolean,
channelTypes?: string[],
hideNSFW?: boolean,
onlyNSFW?: boolean,
hideNoAccess?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
themeOptions: object
}
channelsSelect: (
disabled?: boolean,
channelTypes?: string[],
hideNSFW?: boolean,
onlyNSFW?: boolean,
hideNoAccess?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
themeOptions: object
}
channelsMultiSelect: (
disabled?: boolean,
required?: boolean,
channelTypes?: string[],
hideNSFW?: boolean,
onlyNSFW?: boolean,
hideNoAccess?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
required: boolean
themeOptions: object
}
channelsMultiSelect: (
disabled?: boolean,
required?: boolean,
channelTypes?: string[],
hideNSFW?: boolean,
onlyNSFW?: boolean,
hideNoAccess?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
required: boolean
themeOptions: object
}
rolesSelect: (
includeBots: boolean,
disabled?: boolean,
hideHigherRoles?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
themeOptions: object
}
rolesSelect: (
includeBots: boolean,
disabled?: boolean,
hideHigherRoles?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
themeOptions: object
}
rolesMultiSelect: (
includeBots: boolean,
disabled?: boolean,
required?: boolean,
hideHigherRoles?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
required: boolean
themeOptions: object
}
rolesMultiSelect: (
includeBots: boolean,
disabled?: boolean,
required?: boolean,
hideHigherRoles?: boolean,
themeOptions?: object
) => {
type: string
function: (client: string, guildid: string) => any
disabled: boolean
required: boolean
themeOptions: object
}
colorSelect: (
defaultState: string,
disabled?: boolean,
themeOptions?: object
) => {
type: string
data: string
disabled: boolean
themeOptions: object
}
colorSelect: (
defaultState: string,
disabled?: boolean,
themeOptions?: object
) => {
type: string
data: string
disabled: boolean
themeOptions: object
}
embedBuilder: (
defaultSettings: object,
themeOptions?: object
) => {
type: string
data: object
themeOptions: object
}
embedBuilder: (
defaultSettings: object,
themeOptions?: object
) => {
type: string
data: object
themeOptions: object
}
}
interface EmbedBuilder {
content?: string
embed: {
title?: string
description: string
color?: string | number
timestamp?: any
url?: string
author?: {
name?: string
url?: string
icon_url?: string
}
thumbnail?: {
url?: string
}
image?: {
url?: string
}
footer?: {
text?: string
icon_url?: string
}
fields?: EmbedBuilderField[]
}
content?: string
embed: {
title?: string
description: string
color?: string | number
timestamp?: any
url?: string
author?: {
name?: string
url?: string
icon_url?: string
}
thumbnail?: {
url?: string
}
image?: {
url?: string
}
footer?: {
text?: string
icon_url?: string
}
fields?: EmbedBuilderField[]
}
}
interface EmbedBuilderField {
name?: string
value?: string
inline?: boolean
name?: string
value?: string
inline?: boolean
}
interface customPagesTypes {
redirectToUrl: (
endpoint: string,
getDataFunction: any
) => {
type: string
endpoint: string
getEndpoint: any
}
redirectToUrl: (
endpoint: string,
getDataFunction: any
) => {
type: string
endpoint: string
getEndpoint: any
}
renderHtml: (
endpoint: string,
getDataFunction: any
) => {
type: string
endpoint: string
getHtml: any
}
renderHtml: (
endpoint: string,
getDataFunction: any
) => {
type: string
endpoint: string
getHtml: any
}
sendJson: (
endpoint: string,
getDataFunction: any
) => {
type: string
endpoint: string
getJson: any
}
}
sendJson: (
endpoint: string,
getDataFunction: any
) => {
type: string
endpoint: string
getJson: any
}
}

35
.gitignore vendored
View file

@ -1,33 +1,2 @@
./node_modules/
node_modules/
test/
/test
./test/
./test/
./.idea
discord-dashboard-pp
./discord-dashboard-pp
.idea
.devChannel
./.devChannel
./ExternalStatistics/index_unobfuscated.js
ExternalStatistics/index_unobfuscated.js
./dev_project.json
dev_project.json
altometra-dashboard
./altometra-dashboard
index_unobf.js
./index_unobf.js
/altometra-dashoard
altometra-dashboard/
./altometra-dashboard/
/altometra-dashoard/
./licensedDashboardClass_unobfuscated.js
./npmPublish.js
licensedDashboardClass_unobfuscated.js
npmPublish.js
updateObfuscatedIndex.js
./updateObfuscatedIndex.js
.idea
.idea
yarn-error.log
node_modules
package-lock.json

View file

@ -28,5 +28,4 @@ module.exports = (websiteTitle) => `<!DOCTYPE html>
</body>
</html>
`
</html>`;

View file

@ -1,36 +1,26 @@
const prefix = "[DBD-Storage-Handler]"
const colors = require("colors")
const Keyv = require("keyv")
const { join } = require("path")
const err = (text) => {
return `🐧${text} Do you need help? Join our Discord server: ${"https://discord.gg/CzfMGtrdaA".blue
}`
}
const prefix = "[DBD-Storage-Handler]";
const Keyv = require("keyv");
const { join } = require("path");
class Handler {
constructor(keyvAdapter) {
this.db = new Keyv(
keyvAdapter || `sqlite://${join(__dirname, "/database.sqlite")}`
)
constructor(keyvAdapter) {
this.db = new Keyv(keyvAdapter || `sqlite://${join(__dirname, "/database.sqlite")}`);
this.db.on("error", (err) =>
console.error(`${prefix} ${`Keyv connection error: ${err}`.red}`)
)
this.db.on("error", (err) => console.error(`${prefix} ${`Keyv connection error: ${err}`.red}`));
this.Category = require(`${__dirname}/structures/Category`)(this.db)
this.Option = require(`${__dirname}/structures/Option`)(this.db)
this.Category = require(`${__dirname}/structures/Category`)(this.db);
this.Option = require(`${__dirname}/structures/Option`)(this.db);
console.log(`${prefix} Database successfully initialized!`)
}
console.log(`${prefix} Database successfully initialized!`);
}
async fetch(guildId, optionId) {
return await this.db.get(`${guildId}.options.${optionId}`)
}
async fetch(guildId, optionId) {
return await this.db.get(`${guildId}.options.${optionId}`);
}
db() {
return this.db
}
db() {
return this.db;
}
}
module.exports = Handler
module.exports = Handler;

View file

@ -1,104 +1,103 @@
module.exports = (db) => {
return class Category {
constructor(
options = { categoryId: "", categoryName: "", categoryDescription: "" }
) {
this.categoryId = options.categoryId
this.categoryName = options.categoryName
this.categoryDescription = options.categoryDescription
this.categoryOptionsList = []
module.exports = db => {
return class Category {
constructor(
options = {
categoryId: "",
categoryName: "",
categoryDescription: "",
},
) {
this.categoryId = options.categoryId;
this.categoryName = options.categoryName;
this.categoryDescription = options.categoryDescription;
this.categoryOptionsList = [];
// const db = Handler.getDB()
this.db = db
}
// const db = Handler.getDB()
this.db = db;
}
/**
*
* @param {string} id - The id of the category, must be unique
* @returns
*/
setId(id) {
this.categoryId = id
/**
*
* @param {string} id - The id of the category, must be unique
* @returns
*/
setId(id) {
this.categoryId = id;
return this
}
return this;
}
/**
*
* @param {string} name - The name of the category displayed in the dashboard
* @returns
*/
setName(name) {
this.categoryName = name
/**
*
* @param {string} name - The name of the category displayed in the dashboard
* @returns
*/
setName(name) {
this.categoryName = name;
return this
}
return this;
}
/**
*
* @param {string} description - The description of the category displayed in the dashboard
* @returns
*/
setDescription(description) {
this.categoryDescription = description
/**
*
* @param {string} description - The description of the category displayed in the dashboard
* @returns
*/
setDescription(description) {
this.categoryDescription = description;
return this
}
return this;
}
/**
*
* @param {string} image - Set the image for a Soft UI category, must be a link
* @returns
*/
setImage(image) {
this.categoryImageURL = image
/**
*
* @param {string} image - Set the image for a Soft UI category, must be a link
* @returns
*/
setImage(image) {
this.categoryImageURL = image;
return this
}
return this;
}
/**
*
* @param {boolean} toggleable - Allows Soft UI category to be toggleable
* @returns
*/
setToggleable(toggleable) {
this.toggleable = toggleable
/**
*
* @param {boolean} toggleable - Allows Soft UI category to be toggleable
* @returns
*/
setToggleable(toggleable) {
this.toggleable = toggleable;
this.getActualSet = async ({ guild }) => {
return await this.db.get(
`${guild.id}.categories.${this.categoryId}.toggle`
)
}
this.getActualSet = async ({ guild }) => {
return await this.db.get(`${guild.id}.categories.${this.categoryId}.toggle`);
};
this.setNew = async ({ guild, newData }) => {
await this.db.set(
`${guild.id}.categories.${this.categoryId}.toggle`,
newData
)
}
this.setNew = async ({ guild, newData }) => {
await this.db.set(`${guild.id}.categories.${this.categoryId}.toggle`, newData);
};
return this
}
return this;
}
/**
* @param {import('./Option')[]} options - The options of the category
* @example
* new Category()
* .setId('setup')
* .setName("Setup")
* .setDescription("Setup your bot with default settings!")
* .addOptions(
* new Option()
* .setId('lang')
* .setName("Language")
* .setDescription("Change bot's language easily")
* .setType(dbd.formTypes.select({"Polish": 'pl', "English": 'en', "French": 'fr'}))
* )
*/
addOptions() {
this.categoryOptionsList.push(...arguments)
/**
* @param {import('./Option')[]} options - The options of the category
* @example
* new Category()
* .setId('setup')
* .setName("Setup")
* .setDescription("Setup your bot with default settings!")
* .addOptions(
* new Option()
* .setId('lang')
* .setName("Language")
* .setDescription("Change bot's language easily")
* .setType(dbd.formTypes.select({"Polish": 'pl', "English": 'en', "French": 'fr'}))
* )
*/
addOptions() {
this.categoryOptionsList.push(...arguments);
return this
}
}
}
return this;
}
};
};

View file

@ -1,95 +1,88 @@
const { formTypes } = require("discord-dashboard")
const { formTypes } = require("../../ModuleExportsFunctions/formTypes");
const ids = []
const err = (text) => {
return `🐧${text} Do you need help? Join our Discord server: ${
"https://discord.gg/CzfMGtrdaA".blue
}`
}
const ids = [];
module.exports = (db) => {
return class Option {
constructor(
options = {
optionId: "",
optionName: "",
optionDescription: "",
optionType: formTypes,
}
) {
//
this.optionId = options.optionId
this.optionName = options.optionName
this.optionDescription = options.optionDescription
this.optionType = options.optionType
this.categoryId = "default"
this.setNew = async ({ guild, newData }) => {
await db.set(`${guild.id}.options.${this.optionId}`, newData)
}
this.getActualSet = async ({ guild }) => {
return await db.get(`${guild.id}.options.${this.optionId}`)
}
}
/**
*
* @param {string} id - The id of the option, must be unique
* @returns
*/
setId(id) {
this.optionId = id
if (ids.includes(id))
throw new Error(err(`Option id ${id} already exists`))
else ids.push(this.optionId)
return this
}
/**
*
* @param {string} name - The name of the option displayed in the dashboard
* @returns
*/
setName(name) {
this.optionName = name
return this
}
/**
*
* @param {string} description - The description of the option displayed in the dashboard
* @returns
*/
setDescription(description) {
this.optionDescription = description
return this
}
/**
*
* @param {object} options - Set custom options for the formType
* @returns
*/
setOptions(options) {
this.themeOptions = options
}
/**
*
* @param {formTypes} type - The type of the option
* @returns
*/
setType(type) {
this.optionType = type
return this
}
}
}
return class Option {
constructor(
options = {
optionId: "",
optionName: "",
optionDescription: "",
optionType: formTypes,
},
) {
//
this.optionId = options.optionId;
this.optionName = options.optionName;
this.optionDescription = options.optionDescription;
this.optionType = options.optionType;
this.categoryId = "default";
this.setNew = async ({ guild, newData }) => {
await db.set(`${guild.id}.options.${this.optionId}`, newData);
};
this.getActualSet = async ({ guild }) => {
return await db.get(`${guild.id}.options.${this.optionId}`);
};
}
/**
*
* @param {string} id - The id of the option, must be unique
* @returns
*/
setId(id) {
this.optionId = id;
if (ids.includes(id)) throw new Error(`Option id ${id} already exists`);
else ids.push(this.optionId);
return this;
}
/**
*
* @param {string} name - The name of the option displayed in the dashboard
* @returns
*/
setName(name) {
this.optionName = name;
return this;
}
/**
*
* @param {string} description - The description of the option displayed in the dashboard
* @returns
*/
setDescription(description) {
this.optionDescription = description;
return this;
}
/**
*
* @param {object} options - Set custom options for the formType
* @returns
*/
setOptions(options) {
this.themeOptions = options;
}
/**
*
* @param {formTypes} type - The type of the option
* @returns
*/
setType(type) {
this.optionType = type;
return this;
}
};
};

View file

@ -1,109 +1,51 @@
const https = require("https")
const http = require("http")
const { Server: SocketServer } = require("socket.io")
const err = (text) => {
return (
text +
` Do you need help? Join our Discord server: ${
"https://discord.gg/CzfMGtrdaA".blue
}`
)
}
const https = require("https");
const http = require("http");
const { Server: SocketServer } = require("socket.io");
module.exports = (app, config, themeConfig, modules) => {
if (config.noCreateServer) return { io: null, server: null }
let server
if (config.noCreateServer) return { io: null, server: null };
if (!config.SSL) config.SSL = {}
if (config.SSL.enabled) {
if (!config.SSL.key || !config.SSL.cert)
console.log(
err(
`${
"discord-dashboard issue:".red
} The SSL preference for Dashboard is selected (config.SSL.enabled), but config does not include key or cert (config.SSL.key, config.SSL.cert).`
)
)
let options = {
key: config.SSL.key || "",
cert: config.SSL.cert || "",
}
try {
const https = require("https")
server = https.createServer(options, app)
} catch (e) {
console.log(
err(
`${
"discord-dashboard issue:".red
} There's a problem while creating server, check if the port specified is already on use.`
)
)
}
} else {
const http = require("http")
server = http.createServer(app)
}
let server;
let pport = ""
if (config.port !== 80 && config.port !== 443) {
pport = `:${config.port}`
}
if (!config.SSL) config.SSL = {};
if (config.SSL.enabled) {
if (!config.SSL.key || !config.SSL.cert) console.log(`${"discord-dashboard issue:".red} The SSL preference for Dashboard is selected (config.SSL.enabled), but config does not include key or cert (config.SSL.key, config.SSL.cert).`);
if (!config.minimizedConsoleLogs) {
console.log(
`
Discord Bot Dashboard
`.rainbow +
`
Thanks for using ${
"discord-dashboard".rainbow
} module! The server is up and running, so head over to the ${
`${(config.domain || "domain.com") + pport}`.blue
} website and start your fun.
const options = {
key: config.SSL.key || "",
cert: config.SSL.cert || "",
};
Remember that there are ${
"themes".rainbow
} available to make the Dashboard look better: ${
"https://dbd-docs.assistantscenter.com/#/?id=themes".blue
}
try {
server = https.createServer(options, app);
} catch (e) {
console.log(`${"discord-dashboard issue:".red} There's a problem while creating server, check if the port specified is already on use.`);
}
} else {
server = http.createServer(app);
}
If you need help with something or you don't understand something, please visit our ${
"Discord Support Server".rainbow
}: ${"https://discord.gg/CzfMGtrdaA".blue}
`
)
} else {
console.log(
`DBD Dashboard running on ${
`${(config.domain || "domain.com") + pport}`.blue
} !`
)
}
let pport = "";
if (config.port != 80 && config.port != 443) pport = `:${config.port}`;
const SocketServer = require("socket.io").Server
const io = new SocketServer(server, {
cors: {
origin: "*",
},
})
console.log(`DBD Dashboard running on ${`${(config.domain || "domain.com") + pport}`.blue} !`);
modules.forEach((module) => {
module.server({
io: io,
server: server,
config: config,
themeConfig: themeConfig,
})
})
const io = new SocketServer(server, {
cors: {
origin: "*",
},
});
server.listen(config.port)
return { server, io }
}
modules.forEach((module) => {
module.server({
io: io,
server: server,
config: config,
themeConfig: themeConfig,
});
});
server.listen(config.port);
return { server, io };
};

View file

@ -1,23 +1,23 @@
module.exports = {
redirectToUrl: (endpoint, getDataFunction) => {
return {
type: "redirect",
endpoint: endpoint,
getEndpoint: getDataFunction,
}
},
renderHtml: (endpoint, getDataFunction) => {
return {
type: "html",
endpoint: endpoint,
getHtml: getDataFunction,
}
},
sendJson: (endpoint, getDataFunction) => {
return {
type: "json",
endpoint: endpoint,
getJson: getDataFunction,
}
},
}
redirectToUrl: (endpoint, getDataFunction) => {
return {
type: "redirect",
endpoint: endpoint,
getEndpoint: getDataFunction,
};
},
renderHtml: (endpoint, getDataFunction) => {
return {
type: "html",
endpoint: endpoint,
getHtml: getDataFunction,
};
},
sendJson: (endpoint, getDataFunction) => {
return {
type: "json",
endpoint: endpoint,
getJson: getDataFunction,
};
},
};

View file

@ -1,43 +0,0 @@
module.exports = {
CREATE_INSTANT_INVITE: ["CREATE_INSTANT_INVITE", 0x1],
KICK_MEMBERS: ["KICK_MEMBERS", 0x2],
BAN_MEMBERS: ["BAN_MEMBERS", 0x4],
ADMINISTRATOR: ["ADMINISTRATOR", 0x8],
MANAGE_CHANNELS: ["MANAGE_CHANNELS", 0x10],
MANAGE_GUILD: ["MANAGE_GUILD", 0x20],
ADD_REACTIONS: ["ADD_REACTIONS", 0x40],
VIEW_AUDIT_LOG: ["VIEW_AUDIT_LOG", 0x80],
PRIORITY_SPEAKER: ["PRIORITY_SPEAKER", 0x100],
STREAM: ["STREAM", 0x200],
VIEW_CHANNEL: ["VIEW_CHANNEL", 0x400],
SEND_MESSAGES: ["SEND_MESSAGES", 0x800],
SEND_TTS_MESSAGES: ["SEND_TTS_MESSAGES", 0x1000],
MANAGE_MESSAGES: ["MANAGE_MESSAGES", 0x2000],
EMBED_LINKS: ["EMBED_LINKS", 0x4000],
ATTACH_FILES: ["ATTACH_FILES", 0x8000],
READ_MESSAGE_HISTORY: ["READ_MESSAGE_HISTORY", 0x10000],
MENTION_EVERYONE: ["MENTION_EVERYONE", 0x20000],
USE_EXTERNAL_EMOJIS: ["USE_EXTERNAL_EMOJIS", 0x40000],
VIEW_GUILD_INSIGHTS: ["VIEW_GUILD_INSIGHTS", 0x80000],
CONNECT: ["CONNECT", 0x100000],
SPEAK: ["SPEAK", 0x200000],
MUTE_MEMBERS: ["MUTE_MEMBERS", 0x400000],
DEAFEN_MEMBERS: ["DEAFEN_MEMBERS", 0x800000],
MOVE_MEMBERS: ["MOVE_MEMBERS", 0x1000000],
USE_VAD: ["USE_VAD", 0x2000000],
CHANGE_NICKNAME: ["CHANGE_NICKNAME", 0x4000000],
MANAGE_NICKNAMES: ["MANAGE_NICKNAMES", 0x8000000],
MANAGE_ROLES: ["MANAGE_ROLES", 0x10000000],
MANAGE_WEBHOOKS: ["MANAGE_WEBHOOKS", 0x20000000],
MANAGE_EMOJIS_AND_STICKERS: ["MANAGE_EMOJIS_AND_STICKERS", 0x40000000],
USE_APPLICATION_COMMANDS: ["USE_APPLICATION_COMMANDS", 0x80000000],
REQUEST_TO_SPEAK: ["REQUEST_TO_SPEAK", 0x100000000],
MANAGE_EVENTS: ["MANAGE_EVENTS", 0x200000000],
MANAGE_THREADS: ["MANAGE_THREADS", 0x400000000],
CREATE_PUBLIC_THREADS: ["CREATE_PUBLIC_THREADS", 0x800000000],
CREATE_PRIVATE_THREADS: ["CREATE_PRIVATE_THREADS", 0x1000000000],
USE_EXTERNAL_STICKERS: ["USE_EXTERNAL_STICKERS", 0x2000000000],
SEND_MESSAGES_IN_THREADS: ["SEND_MESSAGES_IN_THREADS", 0x4000000000],
START_EMBEDDED_ACTIVITIES: ["START_EMBEDDED_ACTIVITIES", 0x8000000000],
MODERATE_MEMBERS: ["MODERATE_MEMBERS", 0x10000000000],
}

View file

@ -1,346 +1,294 @@
const discordPermissions = require("./discordPermissions")
const { Permissions } = require("discord.js");
module.exports = {
select: (list, disabled, themeOptions = {}) => {
if (!list)
throw new Error(
err("List in the 'select' form type cannot be empty.")
)
if (typeof list != "object")
throw new Error(
err("List in the 'select' form type should be an JSON object.")
)
let keys = Object.keys(list)
let values = Object.values(list)
return {
type: "select",
data: {
keys,
values,
},
disabled: disabled || false,
themeOptions,
}
},
multiSelect: (list, disabled, required, themeOptions = {}) => {
if (!list)
throw new Error(
err("List in the 'select' form type cannot be empty.")
)
if (typeof list != "object")
throw new Error(
err("List in the 'select' form type should be an JSON object.")
)
let keys = Object.keys(list)
let values = Object.values(list)
return {
type: "multiSelect",
data: {
keys,
values,
},
disabled: disabled || false,
required: required || false,
themeOptions,
}
},
input: (placeholder, min, max, disabled, required, themeOptions = {}) => {
if (min) {
if (isNaN(min))
throw new Error(
err("'min' in the 'input' form type should be an number.")
)
}
if (max) {
if (isNaN(max))
throw new Error(
err("'max' in the 'input' form type should be an number.")
)
}
if (min && max) {
if (min > max)
throw new Error(
err(
"'min' in the 'input' form type cannot be higher than 'max'."
)
)
}
return {
type: "input",
data: placeholder,
min: min || null,
max: max || null,
disabled: disabled || false,
required: required || false,
themeOptions,
}
},
textarea: (
placeholder,
min,
max,
disabled,
required,
themeOptions = {}
) => {
if (min) {
if (isNaN(min))
throw new Error(
err("'min' in the 'input' form type should be an number.")
)
}
if (max) {
if (isNaN(max))
throw new Error(
err("'max' in the 'input' form type should be an number.")
)
}
if (min && max) {
if (min > max)
throw new Error(
err(
"'min' in the 'input' form type cannot be higher than 'max'."
)
)
}
return {
type: "textarea",
data: placeholder,
min: min || null,
max: max || null,
disabled: disabled || false,
required: required || false,
themeOptions,
}
},
switch: (disabled, themeOptions = {}) => {
return {
type: "switch",
disabled: disabled,
themeOptions,
}
},
checkbox: (disabled, themeOptions = {}) => {
return {
type: "checkbox",
disabled: disabled,
themeOptions,
}
},
channelsSelect: (
disabled,
channelTypes = ["GUILD_TEXT"],
hideNSFW,
onlyNSFW,
hideNoAccess,
themeOptions = {}
) => {
return {
type: "channelsSelect",
function: (client, guildid, userid) => {
let listCount = {}
let list = {
"-": "",
}
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
client.guilds.cache
.get(guildid)
.channels.cache.forEach((channel) => {
if (!channelTypes.includes(channel.type)) return
if (hideNSFW && channel.nsfw) return
if (onlyNSFW && !channel.nsfw) return
if (hideNoAccess) {
if (!user.permissionsIn(channel).has('0x800') || !user.permissionsIn(channel).has('0x400')) return
if (!bot.permissionsIn(channel).has('0x800') || !bot.permissionsIn(channel).has('0x800')) return
}
listCount[channel.name]
? (listCount[channel.name] =
listCount[channel.name] + 1)
: (listCount[channel.name] = 1)
if (list[channel.name])
list[
`${channel.name} (${listCount[channel.name]})`
] = channel.id
else list[channel.name] = channel.id
})
select: (list, disabled, themeOptions = {}) => {
if (!list) throw new Error(console.log("List in the 'select' form type cannot be empty."));
if (typeof list != "object") throw new Error(console.log("List in the 'select' form type should be an JSON object."));
let myObj = list
let keys = Object.keys(myObj),
i = null,
len = keys.length
const keys = Object.keys(list);
const values = Object.values(list);
keys.sort()
list = {}
return {
type: "select",
data: {
keys,
values,
},
disabled: disabled || false,
themeOptions,
};
},
multiSelect: (list, disabled, required, themeOptions = {}) => {
if (!list) throw new Error(console.log("List in the 'select' form type cannot be empty."));
if (typeof list != "object") throw new Error(console.log("List in the 'select' form type should be an JSON object."));
for (i = 0; i < len; i++) {
k = keys[i]
list[k] = myObj[k]
}
const keys = Object.keys(list);
const values = Object.values(list);
return {
values: Object.values(list),
keys: Object.keys(list),
}
},
disabled,
themeOptions,
}
},
channelsMultiSelect: (
disabled,
required,
channelTypes = ["GUILD_TEXT"],
hideNSFW,
onlyNSFW,
hideNoAccess,
themeOptions = {}
) => {
return {
type: "channelsMultiSelect",
function: (client, guildid, userid) => {
let listCount = {}
let list = {}
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
client.guilds.cache
.get(guildid)
.channels.cache.forEach((channel) => {
if (!channelTypes.includes(channel.type)) return
if (hideNSFW && channel.nsfw) return
if (onlyNSFW && !channel.nsfw) return
if (hideNoAccess) {
if (!user.permissionsIn(channel).has('0x800') || !user.permissionsIn(channel).has('0x400')) return
if (!bot.permissionsIn(channel).has('0x800') || !bot.permissionsIn(channel).has('0x800')) return
}
listCount[channel.name]
? (listCount[channel.name] =
listCount[channel.name] + 1)
: (listCount[channel.name] = 1)
if (list[channel.name])
list[
`${channel.name} (${listCount[channel.name]})`
] = channel.id
else list[channel.name] = channel.id
})
return {
type: "multiSelect",
data: {
keys,
values,
},
disabled: disabled || false,
required: required || false,
themeOptions,
};
},
input: (placeholder, min, max, disabled, required, themeOptions = {}) => {
if (min && isNaN(min)) throw new Error(console.log("'min' in the 'input' form type should be an number."));
if (max && isNaN(max)) throw new Error(console.log("'max' in the 'input' form type should be an number."));
if ((min && max) && (min > max)) throw new Error(console.log("'min' in the 'input' form type cannot be higher than 'max'."));
let myObj = list
let keys = Object.keys(myObj),
i = null,
len = keys.length
return {
type: "input",
data: placeholder,
min: min || null,
max: max || null,
disabled: disabled || false,
required: required || false,
themeOptions,
};
},
textarea: (placeholder, min, max, disabled, required, themeOptions = {}) => {
if (min && isNaN(min)) throw new Error(console.log("'min' in the 'input' form type should be an number."));
if (max && isNaN(max)) throw new Error(console.log("'max' in the 'input' form type should be an number."));
if ((min && max) && (min > max)) throw new Error(console.log("'min' in the 'input' form type cannot be higher than 'max'."));
keys.sort()
list = {}
return {
type: "textarea",
data: placeholder,
min: min || null,
max: max || null,
disabled: disabled || false,
required: required || false,
themeOptions,
};
},
switch: (disabled, themeOptions = {}) => {
return {
type: "switch",
disabled: disabled,
themeOptions,
};
},
checkbox: (disabled, themeOptions = {}) => {
return {
type: "checkbox",
disabled: disabled,
themeOptions,
};
},
channelsSelect: (disabled, channelTypes = ["GUILD_TEXT"], hideNSFW, onlyNSFW, hideNoAccess, themeOptions = {}) => {
return {
type: "channelsSelect",
function: (client, guildid, userid) => {
const listCount = {};
let list = {
"-": "",
};
for (i = 0; i < len; i++) {
k = keys[i]
list[k] = myObj[k]
}
const guild = client.guilds.cache.get(guildid),
user = guild.members.cache.get(userid),
bot = guild.members.cache.get(client.user.id);
return {
values: Object.values(list),
keys: Object.keys(list),
}
},
disabled,
required,
themeOptions,
}
},
rolesMultiSelect: (disabled, required, includeBots, hideHigherRoles, themeOptions = {}) => {
return {
type: "rolesMultiSelect",
function: (client, guildid, userid) => {
let listCount = {}
const list = []
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
client.guilds.cache.get(guildid).channels.cache.forEach((channel) => {
if (!channelTypes.includes(channel.type)) return;
if (hideNSFW && channel.nsfw) return;
if (onlyNSFW && !channel.nsfw) return;
if (hideNoAccess) {
if (!user.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !user.permissionsIn(channel).has(Permissions.FLAGS.VIEW_CHANNEL)) return;
if (!bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES)) return;
}
client.guilds.cache.get(guildid).roles.cache.forEach((role) => {
if (role.managed && !includeBots) return
if (role.id === guildid) return // @everyone role
if (hideHigherRoles) {
if (role.position >= user.roles.highest.position) return
if (role.position >= bot.roles.highest.position) return
}
listCount[role.name]
? (listCount[role.name] = listCount[role.name] + 1)
: (listCount[role.name] = 1)
if (listCount[role.name] > 1)
list.push({ key: `${role.name} (${listCount[role.name]})`, value: role.id, position: role.position })
else list.push({ key: role.name, value: role.id, position: role.position })
})
listCount[channel.name] ? (listCount[channel.name] = listCount[channel.name] + 1) : (listCount[channel.name] = 1);
list.sort((a, b) => b.position - a.position)
if (list[channel.name]) list[`${channel.name} (${listCount[channel.name]})`] = channel.id;
else list[channel.name] = channel.id;
});
const sortedList = {}
list.forEach(({ key, value }) => (sortedList[key] = value))
const myObj = list;
let i = null;
const keys = Object.keys(myObj),
len = keys.length;
return {
values: Object.values(sortedList),
keys: Object.keys(sortedList),
}
},
disabled,
required,
themeOptions,
}
},
rolesSelect: (disabled, includeBots, hideHigherRoles, themeOptions = {}) => {
return {
type: "rolesSelect",
function: (client, guildid, userid) => {
let listCount = {}
const list = [{ key: '-', value: '' }]
const guild = client.guilds.cache.get(guildid)
const user = guild.members.cache.get(userid)
const bot = guild.members.cache.get(client.user.id)
client.guilds.cache.get(guildid).roles.cache.forEach((role) => {
if (role.managed && !includeBots) return
if (role.id === guildid) return // @everyone role
if (hideHigherRoles) {
if (role.position >= user.roles.highest.position) return
if (role.position >= bot.roles.highest.position) return
}
listCount[role.name]
? (listCount[role.name] = listCount[role.name] + 1)
: (listCount[role.name] = 1)
if (listCount[role.name] > 1)
list.push({ key: `${role.name} (${listCount[role.name]})`, value: role.id, position: role.position })
else list.push({ key: role.name, value: role.id, position: role.position })
})
keys.sort();
list = {};
list.sort((a, b) => b.position - a.position)
for (i = 0; i < len; i++) {
const k = keys[i];
list[k] = myObj[k];
}
const sortedList = {}
list.forEach(({ key, value }) => (sortedList[key] = value))
return {
values: Object.values(list),
keys: Object.keys(list),
};
},
disabled,
themeOptions,
};
},
channelsMultiSelect: (disabled, required, channelTypes = ["GUILD_TEXT"], hideNSFW, onlyNSFW, hideNoAccess, themeOptions = {}) => {
return {
type: "channelsMultiSelect",
function: (client, guildid, userid) => {
const listCount = {};
let list = {};
const guild = client.guilds.cache.get(guildid);
const user = guild.members.cache.get(userid);
const bot = guild.members.cache.get(client.user.id);
return {
values: Object.values(sortedList),
keys: Object.keys(sortedList),
}
},
disabled,
themeOptions,
}
},
colorSelect: (defaultState, disabled, themeOptions = {}) => {
return {
type: "colorSelect",
data: defaultState,
disabled,
themeOptions,
}
},
embedBuilder: (defaultSettings, disabled, themeOptions = {}) => {
return {
type: "embedBuilder",
data: defaultSettings,
disabled,
themeOptions,
}
},
}
client.guilds.cache.get(guildid).channels.cache.forEach(channel => {
if (!channelTypes.includes(channel.type)) return;
if (hideNSFW && channel.nsfw) return;
if (onlyNSFW && !channel.nsfw) return;
if (hideNoAccess) {
if (!user.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !user.permissionsIn(channel).has(Permissions.FLAGS.VIEW_CHANNEL)) return;
if (!bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES) || !bot.permissionsIn(channel).has(Permissions.FLAGS.SEND_MESSAGES)) return;
}
listCount[channel.name] ? (listCount[channel.name] = listCount[channel.name] + 1) : (listCount[channel.name] = 1);
if (list[channel.name]) list[`${channel.name} (${listCount[channel.name]})`] = channel.id;
else list[channel.name] = channel.id;
});
const myObj = list;
let i = null;
const keys = Object.keys(myObj),
len = keys.length;
keys.sort();
list = {};
for (i = 0; i < len; i++) {
const k = keys[i];
list[k] = myObj[k];
}
return {
values: Object.values(list),
keys: Object.keys(list),
};
},
disabled,
required,
themeOptions,
};
},
rolesMultiSelect: (disabled, required, includeBots, hideHigherRoles, themeOptions = {}) => {
return {
type: "rolesMultiSelect",
function: (client, guildid, userid) => {
const listCount = {};
const list = [];
const guild = client.guilds.cache.get(guildid);
const user = guild.members.cache.get(userid);
const bot = guild.members.cache.get(client.user.id);
client.guilds.cache.get(guildid).roles.cache.forEach((role) => {
if (role.managed && !includeBots) return;
if (role.id === guildid) return; // @everyone role
if (hideHigherRoles) {
if (role.position >= user.roles.highest.position) return;
if (role.position >= bot.roles.highest.position) return;
}
listCount[role.name] ? (listCount[role.name] = listCount[role.name] + 1) : (listCount[role.name] = 1);
if (listCount[role.name] > 1)
list.push({
key: `${role.name} (${listCount[role.name]})`,
value: role.id,
position: role.position,
});
else list.push({
key: role.name,
value: role.id,
position: role.position,
});
});
list.sort((a, b) => b.position - a.position);
const sortedList = {};
list.forEach(({ key, value }) => (sortedList[key] = value));
return {
values: Object.values(sortedList),
keys: Object.keys(sortedList),
};
},
disabled,
required,
themeOptions,
};
},
rolesSelect: (disabled, includeBots, hideHigherRoles, themeOptions = {}) => {
return {
type: "rolesSelect",
function: (client, guildid, userid) => {
const listCount = {};
const list = [{
key: "-",
value: "",
}];
const guild = client.guilds.cache.get(guildid);
const user = guild.members.cache.get(userid);
const bot = guild.members.cache.get(client.user.id);
client.guilds.cache.get(guildid).roles.cache.forEach((role) => {
if (role.managed && !includeBots) return;
if (role.id === guildid) return; // @everyone role
if (hideHigherRoles) {
if (role.position >= user.roles.highest.position) return;
if (role.position >= bot.roles.highest.position) return;
}
listCount[role.name] ? (listCount[role.name] = listCount[role.name] + 1) : (listCount[role.name] = 1);
if (listCount[role.name] > 1)
list.push({
key: `${role.name} (${listCount[role.name]})`,
value: role.id,
position: role.position,
});
else list.push({
key: role.name,
value: role.id,
position: role.position,
});
});
list.sort((a, b) => b.position - a.position);
const sortedList = {};
list.forEach(({ key, value }) => (sortedList[key] = value));
return {
values: Object.values(sortedList),
keys: Object.keys(sortedList),
};
},
disabled,
themeOptions,
};
},
colorSelect: (defaultState, disabled, themeOptions = {}) => {
return {
type: "colorSelect",
data: defaultState,
disabled,
themeOptions,
};
},
embedBuilder: (defaultSettings, disabled, themeOptions = {}) => {
return {
type: "embedBuilder",
data: defaultSettings,
disabled,
themeOptions,
};
},
};

File diff suppressed because it is too large Load diff

View file

@ -1,416 +1,397 @@
const router = require("express").Router()
const fetch = require("node-fetch")
const router = require("express").Router();
const RL = require("express-rate-limit");
const safeStorage = require("assistants-safe-storage");
const DiscordOauth2 = require("discord-oauth2")
const oauth = new DiscordOauth2()
const DiscordOauth2 = require("discord-oauth2");
const oauth = new DiscordOauth2();
module.exports = (app, config, themeConfig) => {
const scopes = config.guildAfterAuthorization?.use
? ["identify", "guilds", "guilds.join"]
: ["identify", "guilds"]
const RL = require("express-rate-limit")
const RateLimits = config.rateLimits || {}
let RateFunctions = {}
const storage = new safeStorage(config.bot.config.token);
const scopes = config.guildAfterAuthorization?.use ? ["identify", "guilds", "guilds.join"] : ["identify", "guilds"];
const NoRL = (req, res, next) => next()
const RateLimits = config.rateLimits || {};
const RateFunctions = {};
if (RateLimits.discordOAuth2) {
RateFunctions.discordOAuth2 = RL.rateLimit({
windowMs: RateLimits.discordOAuth2.windowMs,
max: RateLimits.discordOAuth2.max,
message: RateLimits.discordOAuth2.message,
store: RateLimits.discordOAuth2.store || new RL.MemoryStore(),
})
}
const NoRL = (req, res, next) => next();
router.get("/", (req, res) => {
const clientId = req.client.id
const redirectUri = req.redirectUri
if (RateLimits.discordOAuth2) {
RateFunctions.discordOAuth2 = RL.rateLimit({
windowMs: RateLimits.discordOAuth2.windowMs,
max: RateLimits.discordOAuth2.max,
message: RateLimits.discordOAuth2.message,
store: RateLimits.discordOAuth2.store || new RL.MemoryStore(),
});
}
let newPage = "/"
if (themeConfig.landingPage?.enabled) newPage = "/dash"
req.session.r = req.query.r || newPage
router.get("/", (req, res) => {
const clientId = req.client.id;
const redirectUri = req.redirectUri;
const authorizeUrl = `https://discord.com/api/oauth2/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(
redirectUri
)}&response_type=code&scope=${scopes.join("%20")}`
res.redirect(authorizeUrl)
})
let newPage = "/";
if (themeConfig.landingPage?.enabled) newPage = "/dash";
router.get("/status", async (req, res) => {
res.send(req.session?.discordAuthStatus)
})
req.session.r = req.query.r || newPage;
router.get(
"/callback",
RateFunctions.discordOAuth2 ? RateFunctions.discordOAuth2 : NoRL,
async (req, res) => {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: null,
},
}
const clientId = req.client.id
const clientSecret = req.client.secret
const redirectUri = req.redirectUri
const authorizeUrl = `https://discord.com/api/oauth2/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${scopes.join("%20")}`;
const accessCode = req.query.code
if (!accessCode)
return res.redirect("/?error=NoAccessCodeReturnedFromDiscord")
res.redirect(authorizeUrl);
});
res.redirect("/loading")
router.get("/status", async (req, res) => {
res.send(req.session?.discordAuthStatus);
});
let OAuth2Response
let OAuth2UserResponse
let OAuth2GuildsResponse
router.get("/callback", RateFunctions.discordOAuth2 ? RateFunctions.discordOAuth2 : NoRL, async (req, res) => {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: null,
},
};
/*
Get Discord OAuth2 API Response with Access Code gained
*/
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Requesting token...",
},
}
req.session.save(function (err) {})
OAuth2Response = await oauth.tokenRequest({
clientId,
clientSecret,
const clientId = req.client.id;
const clientSecret = req.client.secret;
const redirectUri = req.redirectUri;
code: accessCode,
scope: scopes.join(" "),
grantType: "authorization_code",
const accessCode = req.query.code;
if (!accessCode) return res.redirect("/?error=NoAccessCodeReturnedFromDiscord");
redirectUri,
})
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2Response (line 86)",
err
)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
}
res.redirect("/loading");
/*
Get User from Discord OAuth2 API using gained access_token and update its values with tag and avatarURL
*/
let OAuth2Response;
let OAuth2UserResponse;
let OAuth2GuildsResponse;
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Getting User...",
},
}
req.session.save(function (err) {})
OAuth2UserResponse = await oauth.getUser(
OAuth2Response.access_token
)
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2UserResponse (line 118)",
err
)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
}
OAuth2UserResponse.tag = `${OAuth2UserResponse.username}#${OAuth2UserResponse.discriminator}`
OAuth2UserResponse.avatarURL = OAuth2UserResponse.avatar
? `https://cdn.discordapp.com/avatars/${OAuth2UserResponse.id}/${OAuth2UserResponse.avatar}.png?size=1024`
: null
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Requesting token...",
},
};
/*
Save user token in Assistants Secure Storage
*/
req.session.save(function () {});
try {
req.AssistantsSecureStorage.SaveUser(
OAuth2UserResponse.id,
OAuth2Response.access_token
)
} catch (err) {
req.config.reportError(
"Discord.js Route - Assistants Secure Storage (line 141)",
err
)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
}
OAuth2Response = await oauth.tokenRequest({
clientId,
clientSecret,
/*
Save user in session
*/
code: accessCode,
scope: scopes.join(" "),
grantType: "authorization_code",
req.session.user = OAuth2UserResponse
req.session.loggedInLastTime = true
redirectUri,
});
} catch (err) {
console.log("Discord.js Route - OAuth2Response (line 88)\n" + err);
/*
Register user to DBD Stats and emit userLoggedIn event
*/
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
};
try {
req.DBDEvents.emit("userLoggedIn", OAuth2UserResponse)
} catch (err) {
req.config.reportError("Discord.js Route - Register and DBDEvents emit userLoggedIn (line 170)", err)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
}
req.session.save(function () {});
/*
Gain and update session with user guilds
*/
return;
}
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Getting List of User Guilds...",
},
}
req.session.save(function (err) {})
OAuth2GuildsResponse = await oauth.getUserGuilds(
OAuth2Response.access_token
)
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse (line 201)",
err
)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
}
req.session.guilds = OAuth2GuildsResponse || []
/*
Get User from Discord OAuth2 API using gained access_token and update its values with tag and avatarURL
*/
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Getting User...",
},
};
/*
Loop and fetch each guild into bots cache
*/
req.session.save(function () {});
if (!req.config.disableResolvingGuildCache) {
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Resolving guilds cache...",
},
}
req.session.save(function (err) {})
for (let g of OAuth2GuildsResponse) {
try {
await req.bot.guilds.fetch(g.id)
} catch (err) {}
}
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse Whole Loop (line 239)",
err
)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
}
req.session.save(function (err) {})
return
}
}
OAuth2UserResponse = await oauth.getUser(OAuth2Response.access_token);
} catch (err) {
console.log("Discord.js Route - OAuth2UserResponse (line 122)\n" + err);
/*
If joining specific guild after authorization is enabled, do it
*/
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
};
if (req.guildAfterAuthorization.use == true) {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Authorizing user with guild...",
},
}
req.session.save(function (err) {})
try {
await oauth.addMember({
accessToken: OAuth2Response.access_token,
botToken: req.botToken,
guildId: req.guildAfterAuthorization.guildId,
userId: OAuth2UserResponse.id,
req.session.save(function () {});
...(req.guildAfterAuthorization.options || {}),
/*
options?: {
nickname?: string,
roles?: [string],
mute?: boolean,
deaf?: boolean,
}
*/
})
} catch (err) {
req.config.reportError(
"Discord.js Route - guildAfterAuthorization (line 287)",
err
)
}
}
return;
}
OAuth2UserResponse.tag = `${OAuth2UserResponse.username}#${OAuth2UserResponse.discriminator}`;
OAuth2UserResponse.avatarURL = OAuth2UserResponse.avatar ? `https://cdn.discordapp.com/avatars/${OAuth2UserResponse.id}/${OAuth2UserResponse.avatar}.png?size=1024` : null;
req.session.discordAuthStatus = {
loading: false,
success: true,
state: {
error: null,
data: null,
},
}
req.session.save(function (err) {})
/*
Save user token in Assistants Secure Storage
*/
try {
storage.SaveUser(OAuth2UserResponse.id, OAuth2Response.access_token);
} catch (err) {
console.log("Discord.js Route - Assistants Secure Storage (line 147)\n" + err);
return
}
)
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
};
router.get("/logout", (req, res) => {
let r = req.query.r || "/"
req.session.destroy()
res.redirect(r)
})
req.session.save(function () {});
router.get("/guilds/reload", async (req, res) => {
if (!req.session.user) return res.redirect("/discord")
return;
}
/*
Fetch user token
*/
/*
Save user in session
*/
req.session.user = OAuth2UserResponse;
req.session.loggedInLastTime = true;
const access_token = req.AssistantsSecureStorage.GetUser(
req.session.user.id
)
if (!access_token)
return res.send({
error: true,
message: "You don't have any access_token saved.",
login_again_text: true,
})
/*
Register user to DBD Stats and emit userLoggedIn event
*/
try {
req.DBDEvents.emit("userLoggedIn", OAuth2UserResponse);
} catch (err) {
console.log("Discord.js Route - DBDStats register and DBDEvent emit userLoggedIn (line 173)\n" + err);
/*
Gain and update session with user guilds
*/
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
};
req.session.save(function () {});
let OAuth2GuildsResponse
return;
}
try {
OAuth2GuildsResponse = await oauth.getUserGuilds(access_token)
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse for ReloadGuilds (line 335)",
err
)
return res.send({
error: true,
message:
"An error occured. Access_token is wrong or you're being rate limited.",
login_again_text: true,
})
}
req.session.guilds = OAuth2GuildsResponse || []
/*
Gain and update session with user guilds
*/
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Getting List of User Guilds...",
},
};
/*
Loop and fetch each guild into bots cache
*/
req.session.save(function () {});
try {
const Promises = []
for (let g of OAuth2GuildsResponse) {
Promises.push(
new Promise(async (resolve, reject) => {
try {
await req.bot.guilds.fetch(g.id)
} catch (err) {}
resolve(1)
})
)
try {
await Promises.all(Promises)
} catch (err) {}
}
} catch (err) {
req.config.reportError(
"Discord.js Route - OAuth2GuildsResponse Whole Loop for ReloadGuilds (line 363)",
err
)
return res.send({
error: true,
message:
"An error occured. Access_token is wrong or you're being rate limited.",
login_again_text: true,
})
}
OAuth2GuildsResponse = await oauth.getUserGuilds(OAuth2Response.access_token);
} catch (err) {
req.config.reportError("Discord.js Route - OAuth2GuildsResponse (line 205)\n" + err);
/*
Success
*/
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
};
return res.send({
error: false,
message: null,
login_again_text: false,
})
})
req.session.save(function () {});
return router
}
return;
}
req.session.guilds = OAuth2GuildsResponse || [];
/*
Loop and fetch each guild into bots cache
*/
if (!req.config.disableResolvingGuildCache) {
try {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Resolving guilds cache...",
},
};
req.session.save(function () {});
for (const g of OAuth2GuildsResponse) {
try {
await req.bot.guilds.fetch(g.id);
} catch (e) { /* ... */ }
}
} catch (err) {
console.log("Discord.js Route - OAuth2GuildsResponse Whole Loop (line 244)" + err);
req.session.discordAuthStatus = {
loading: false,
success: false,
state: {
error: err,
data: null,
},
};
req.session.save(function () {});
return;
}
}
/*
If joining specific guild after authorization is enabled, do it
*/
if (req.guildAfterAuthorization.use == true) {
req.session.discordAuthStatus = {
loading: true,
success: null,
state: {
error: null,
data: "Authorizing user with guild...",
},
};
req.session.save(function () {});
try {
await oauth.addMember({
accessToken: OAuth2Response.access_token,
botToken: req.botToken,
guildId: req.guildAfterAuthorization.guildId,
userId: OAuth2UserResponse.id,
...(req.guildAfterAuthorization.options || {}),
/*
options?: {
nickname?: string,
roles?: [string],
mute?: boolean,
deaf?: boolean,
}
*/
});
} catch (err) {
req.config.reportError("Discord.js Route - guildAfterAuthorization (line 295)" + err);
}
}
req.session.discordAuthStatus = {
loading: false,
success: true,
state: {
error: null,
data: null,
},
};
req.session.save(function () {});
return;
});
router.get("/logout", (req, res) => {
const r = req.query.r || "/";
req.session.destroy();
res.redirect(r);
});
router.get("/guilds/reload", async (req, res) => {
if (!req.session.user) return res.redirect("/discord");
/*
Fetch user token
*/
const access_token = storage.GetUser(req.session.user.id);
if (!access_token)
return res.send({
error: true,
message: "You don't have any access_token saved.",
login_again_text: true,
});
/*
Gain and update session with user guilds
*/
let OAuth2GuildsResponse;
try {
OAuth2GuildsResponse = await oauth.getUserGuilds(access_token);
} catch (err) {
req.config.reportError("Discord.js Route - OAuth2GuildsResponse for ReloadGuilds (line 342)" + err);
return res.send({
error: true,
message: "An error occured. Access_token is wrong or you're being rate limited.",
login_again_text: true,
});
}
req.session.guilds = OAuth2GuildsResponse || [];
/*
Loop and fetch each guild into bots cache
*/
try {
const Promises = [];
for (const g of OAuth2GuildsResponse) {
Promises.push(
// eslint-disable-next-line no-unused-vars, no-async-promise-executor
new Promise(async (resolve, reject) => {
try {
await req.bot.guilds.fetch(g.id);
} catch (e) { /* ... */ }
resolve(1);
}),
);
try {
await Promises.all(Promises);
} catch (e) { /* ... */ }
}
} catch (err) {
console.log("Discord.js Route - OAuth2GuildsResponse Whole Loop for ReloadGuilds (line 375)" + err);
return res.send({
error: true,
message: "An error occured. Access_token is wrong or you're being rate limited.",
login_again_text: true,
});
}
/*
Success
*/
return res.send({
error: false,
message: null,
login_again_text: false,
});
});
return router;
};

View file

@ -1,122 +1,91 @@
const Discord = require("discord.js")
const router = require("express").Router()
const router = require("express").Router();
// eslint-disable-next-line no-unused-vars
module.exports = (app, config, themeConfig, modules) => {
router.get(
themeConfig.landingPage?.enabled ? "/dash" : "/",
async (req, res) => {
let customThemeOptions
if (themeConfig?.customThemeOptions?.index) {
customThemeOptions = await themeConfig.customThemeOptions.index(
{ req: req, res: res, config: config }
)
}
res.render("index", {
req: req,
themeConfig: req.themeConfig,
bot: config.bot,
customThemeOptions: customThemeOptions || {},
config,
require,
})
}
)
router.get(themeConfig.landingPage?.enabled ? "/dash" : "/", async (req, res) => {
let customThemeOptions;
if (themeConfig.landingPage?.enabled)
router.get("/", async (req, res) => {
res.setHeader("Content-Type", "text/html")
res.send(await themeConfig.landingPage.getLandingPage(req, res))
})
if (themeConfig?.customThemeOptions?.index) {
customThemeOptions = await themeConfig.customThemeOptions.index({
req: req,
res: res,
config: config,
});
}
router.get("/loading", async (req, res) => {
if (!req.session?.discordAuthStatus?.loading)
return res.redirect("/manage")
res.render("index", {
req: req,
themeConfig: req.themeConfig,
bot: config.bot,
customThemeOptions: customThemeOptions || {},
config,
require,
});
});
res.render("loading", { req, themeConfig, bot: config.bot })
})
if (themeConfig.landingPage?.enabled)
router.get("/", async (req, res) => {
res.setHeader("Content-Type", "text/html");
res.send(await themeConfig.landingPage.getLandingPage(req, res));
});
router.get("/invite", (req, res) => {
let config = req.config
config.invite ? null : (config.invite = {})
const scopes = config.invite.scopes || ["bot"]
router.get("/loading", async (req, res) => {
if (!req.session?.discordAuthStatus?.loading)
return res.redirect("/manage");
if (req.query.redirect && !req.query.g)
return res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}&response_type=code&redirect_uri=${req.query.redirect}${
config.invite.otherParams || ""
}`
)
if (req.query.redirect && req.query.g)
return res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}&response_type=code&redirect_uri=${
req.query.redirect
}&guild_id=${req.query.g}${config.invite.otherParams || ""}`
)
res.render("loading", {
req,
themeConfig,
bot: config.bot,
});
});
if (req.query.g) {
let thingymabob = config.invite.redirectUri
? `&response_type=code&redirect_uri=${config.invite.redirectUri}`
: null;
if(!thingymabob) thingymabob = config.invite.specialredirectUri
? `&response_type=code&redirect_uri=${config.invite.specialRedirectUri.replace("{SERVER}", req.query.g)}`
: "";
return res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}${thingymabob}&guild_id=${req.query.g}${config.invite.otherParams || ""}`
)
}
router.get("/invite", (req, res) => {
const config = req.config;
config.invite ? null : (config.invite = {});
res.redirect(
`https://discord.com/oauth2/authorize?client_id=${
config.invite.clientId || config.bot.user.id
}&scope=${scopes.join("%20")}&permissions=${
config.invite.permissions || "0"
}${
config.invite.redirectUri
? `&response_type=code&redirect_uri=${config.invite.redirectUri}`
: ""
}${config.invite.otherParams || ""}`
)
})
const scopes = config.invite.scopes || ["bot"];
if (!config.supportServer) config.supportServer = {}
if (req.query.redirect && !req.query.g)
return res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}&response_type=code&redirect_uri=${req.query.redirect}${config.invite.otherParams || ""}`);
if (req.query.redirect && req.query.g)
return res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}&response_type=code&redirect_uri=${req.query.redirect}&guild_id=${req.query.g}${config.invite.otherParams || ""}`);
router.get(config.supportServer.slash || "/support-server", (req, res) => {
let config = req.config
config.supportServer ? null : (config.supportServer = {})
if (!config.supportServer.inviteUrl)
return res.send({
error: true,
message:
"No inviteUrl defined (discord-dashboard config.supportServer).",
})
if (
!config.supportServer.inviteUrl
.toLowerCase()
.startsWith("https://discord.gg/") &&
!config.supportServer.inviteUrl
.toLowerCase()
.startsWith("https://discord.com/")
)
return res.send({
error: true,
message:
"Invite url should start with 'https://discord.gg/' or 'https://discord.com/'.",
})
res.redirect(config.supportServer.inviteUrl)
})
if (req.query.g) {
let thingymabob = config.invite.redirectUri ? `&response_type=code&redirect_uri=${config.invite.redirectUri}` : null;
if (!thingymabob) thingymabob = config.invite.specialredirectUri ? `&response_type=code&redirect_uri=${config.invite.specialRedirectUri.replace("{SERVER}", req.query.g)}` : "";
return router
}
return res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}${thingymabob}&guild_id=${req.query.g}${config.invite.otherParams || ""}`);
}
res.redirect(`https://discord.com/oauth2/authorize?client_id=${config.invite.clientId || config.bot.user.id}&scope=${scopes.join("%20")}&permissions=${config.invite.permissions || "0"}${config.invite.redirectUri ? `&response_type=code&redirect_uri=${config.invite.redirectUri}` : ""}${config.invite.otherParams || ""}`);
});
if (!config.supportServer) config.supportServer = {};
router.get(config.supportServer.slash || "/support-server", (req, res) => {
const config = req.config;
config.supportServer ? null : (config.supportServer = {});
if (!config.supportServer.inviteUrl)
return res.send({
error: true,
message: "No inviteUrl defined (discord-dashboard config.supportServer).",
});
if (!config.supportServer.inviteUrl
.toLowerCase()
.startsWith("https://discord.gg/") &&
!config.supportServer.inviteUrl
.toLowerCase()
.startsWith("https://discord.com/")
) return res.send({
error: true,
message: "Invite url should start with 'https://discord.gg/' or 'https://discord.com/'.",
});
res.redirect(config.supportServer.inviteUrl);
});
return router;
};

View file

@ -1,47 +1,52 @@
const EventEmitter = require('events');
const DBDEvents = new EventEmitter();
const version = require("./package.json").version;
const EventEmitter = require("events"),
express = require("express"),
app = express(),
session = require("express-session"),
bodyParser = require("body-parser"),
partials = require("express-partials"),
router = require("./router"),
initServer = require("./InitFunctions/initServer");
const err = (text) => {
return text + ` Do you need help? Join our Discord server: ${'https://discord.gg/CzfMGtrdaA'.blue}`;
}
const version = require("./package.json").version;
const DBDEvents = new EventEmitter();
class Dashboard {
constructor(config) {
let notSetYetAndRequired = [];
if (!config.port) notSetYetAndRequired.push('port');
if (!config.theme) notSetYetAndRequired.push('theme');
if (!config.client) notSetYetAndRequired.push('client');
if (!config.redirectUri) notSetYetAndRequired.push('redirectUri');
if (!config.bot) notSetYetAndRequired.push('bot');
if (!config.settings) notSetYetAndRequired.push('settings');
if (!config.domain) notSetYetAndRequired.push('domain');
if (notSetYetAndRequired[0]) throw new Error(err(`You need to define some more things: ${notSetYetAndRequired.join(', ')}.`));
const notSetYetAndRequired = [];
if (!config.port) notSetYetAndRequired.push("port");
if (!config.theme) notSetYetAndRequired.push("theme");
if (!config.client) notSetYetAndRequired.push("client");
if (!config.redirectUri) notSetYetAndRequired.push("redirectUri");
if (!config.bot) notSetYetAndRequired.push("bot");
if (!config.settings) notSetYetAndRequired.push("settings");
if (!config.domain) notSetYetAndRequired.push("domain");
if (notSetYetAndRequired[0]) throw new Error(`You need to define some more things: ${notSetYetAndRequired.join(", ")}.`);
this.config = config;
this.modules = [];
}
async init() {
const modules = this.modules;
const config = this.config;
const express = require('express');
const app = express();
const session = require('express-session');
const bodyParser = require('body-parser');
const partials = require('express-partials');
const v13support = require('discord.js').version.slice(0, 2) == "13";
const config = this.config,
modules = this.modules;
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(partials());
app.set('views', config.theme.viewsPath);
app.use(express.static(config.theme.staticPath));app.use('/', express.static(config.theme.staticPath));app.use('/:a/', express.static(config.theme.staticPath));app.use('/:a/:b/', express.static(config.theme.staticPath));app.use('/:a/:b/:c/', express.static(config.theme.staticPath));app.use('/:a/:b/:c/:d/', express.static(config.theme.staticPath));
app.set('view engine', 'ejs');
let sessionData = {
secret: config.cookiesSecret || 'total_secret_cookie_secret',
app.use(express.static(config.theme.staticPath));
app.use("/", express.static(config.theme.staticPath));
app.use("/:a/", express.static(config.theme.staticPath));
app.use("/:a/:b/", express.static(config.theme.staticPath));
app.use("/:a/:b/:c/", express.static(config.theme.staticPath));
app.use("/:a/:b/:c/:d/", express.static(config.theme.staticPath));
app.set("views", config.theme.viewsPath);
app.set("view engine", "ejs");
const sessionData = {
secret: config.cookiesSecret || "total_secret_cookie_secret",
resave: true,
saveUninitialized: true,
cookie: {
@ -49,13 +54,14 @@ class Dashboard {
maxAge: 253402300799999,
},
};
config.sessionSaveSession ? sessionData.store = config.sessionSaveSession : null;
app.use(session(sessionData));
let themeConfig = config.theme.themeConfig;
const themeConfig = config.theme.themeConfig;
app.get('*', (req,res,next) => {
DBDEvents.emit('websiteView', req.session.user ? req.session.user : {loggedIn: false});
app.get("*", (req, res, next) => {
DBDEvents.emit("websiteView", req.session.user ? req.session.user : { loggedIn: false });
next();
});
@ -63,7 +69,7 @@ class Dashboard {
app.use((req, res, next) => {
req.DBDEvents = DBDEvents;
if(req.session.loggedInLastTime == true){
if (req.session.loggedInLastTime == true) {
req.displayLoggedInInfo = true;
req.session.loggedInLastTime = false;
}
@ -77,18 +83,20 @@ class Dashboard {
req.botToken = config.bot.token;
req.guildAfterAuthorization = config.guildAfterAuthorization || {};
req.websiteTitle = config.websiteTitle || "Discord Web Dashboard";
req.iconUrl = config.iconUrl || 'https://www.nomadfoods.com/wp-content/uploads/2018/08/placeholder-1-e1533569576673.png';
req.websiteTitle = config.websiteTitle || "Discord Bot Dashboard";
req.iconUrl = config.iconUrl || "https://www.nomadfoods.com/wp-content/uploads/2018/08/placeholder-1-e1533569576673.png";
req.app = app;
req.config = config;
next();
});
require('./router')(app, config, themeConfig, modules);
router(app, config, themeConfig, modules);
this.app = app;
let sio = require('./InitFunctions/initServer')(app, config, themeConfig, modules);
const sio = initServer(app, config, themeConfig, modules);
this.server = sio.server;
this.io = sio.io;
}
@ -104,8 +112,8 @@ class Dashboard {
module.exports = {
Dashboard,
formTypes: require('./ModuleExportsFunctions/formTypes'),
customPagesTypes: require('./ModuleExportsFunctions/customPagesTypes'),
formTypes: require("./ModuleExportsFunctions/formTypes"),
customPagesTypes: require("./ModuleExportsFunctions/customPagesTypes"),
DBDEvents,
version
}
version,
};

View file

@ -1,19 +1,14 @@
{
"name": "discord-dashboard",
"version": "2.3.61",
"description": "Create an Dashboard for your bot in 10 minutes without APIs knowledge and slapping code from scratch!",
"version": "1.0",
"description": "dashboard",
"main": "index.js",
"directories": {
"test": "test"
},
"typings": ".d.ts",
"dependencies": {
"assistants-safe-storage": "^1.0.0",
"body-parser": "^1.20.0",
"colors": "^1.4.0",
"cookie-parser": "^1.4.6",
"discord-dashboard": "^2.3.39",
"discord-dashboard-pp-system": "^1.0.2",
"discord-oauth2": "^2.10.0",
"discord.js": "*",
"ejs": "^3.1.8",
@ -24,32 +19,103 @@
"https": "^1.0.0",
"keyv": "^4.5.2",
"node-fetch": "^2.6.7",
"readline-sync": "^1.4.10",
"socket.io": "^4.5.1",
"uuid": "^8.3.2"
"quick.db": "^7.1.3",
"socket.io": "^4.5.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "breftejk",
"license": "CC BY-NC-SA 4.0",
"homepage": "https://dbd-docs.assistantscenter.com/",
"keywords": [
"discord",
"discord.js",
"discordjs",
"discord dashboard",
"discord web dashboard",
"web dashboard",
"dashboard"
],
"repository": {
"type": "git",
"url": "https://github.com/Assistants-Center/Discord.js-Web-Dashboard.git"
},
"devDependencies": {
"dbd-dark-dashboard": "^1.6.58",
"eslint": "^8.23.0",
"javascript-obfuscator": "^4.0.0",
"prettier": "2.7.1"
},
"eslintConfig": {
"env": {
"commonjs": true,
"es6": true,
"es2020": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {
"arrow-spacing": [
"warn",
{
"before": true,
"after": true
}
],
"comma-dangle": [
"error",
"always-multiline"
],
"comma-spacing": "error",
"comma-style": "error",
"dot-location": [
"error",
"property"
],
"handle-callback-err": "off",
"indent": [
"error",
"tab",
{
"SwitchCase": 1
}
],
"keyword-spacing": "error",
"max-nested-callbacks": [
"error",
{
"max": 4
}
],
"max-statements-per-line": [
"error",
{
"max": 2
}
],
"no-console": "off",
"no-multi-spaces": "error",
"no-multiple-empty-lines": [
"error",
{
"max": 2,
"maxEOF": 1,
"maxBOF": 0
}
],
"no-trailing-spaces": [
"error"
],
"no-var": "error",
"object-curly-spacing": [
"error",
"always"
],
"prefer-const": "error",
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"yoda": "error"
}
}
}

282
router.js
View file

@ -1,173 +1,137 @@
const cookieParser = require("cookie-parser"),
underMaintenancePageDefault = require("./underMaintenancePageDefault"),
error404pageDefault = require("./404pagedefault");
const mainRouter = require("./Routes/main"),
dashboardRouter = require("./Routes/dashboard"),
discordRouter = require("./Routes/discord");
module.exports = (app, config, themeConfig, modules) => {
app.use(require("cookie-parser")())
app.use(cookieParser());
app.use((req, res, next) => {
req.bot = config.bot
next()
})
app.use((req, res, next) => {
req.bot = config.bot;
next();
});
if (themeConfig.defaultLocales) {
app.use((req, res, next) => {
if (req.cookies?.lang) req.lang = req.cookies.lang
else req.lang = req.acceptsLanguages()[0].replace("-", "")
if (themeConfig.defaultLocales) {
app.use((req, res, next) => {
if (req.cookies?.lang) req.lang = req.cookies.lang;
else req.lang = req.acceptsLanguages()[0].replace("-", "");
if (themeConfig.locales) {
if (Object.keys(themeConfig.locales).includes(req.lang)) {
req.locales = themeConfig.locales[req.lang]
} else {
req.locales =
themeConfig.locales[Object.keys(themeConfig.locales)[0]]
}
} else {
req.locales =
themeConfig.defaultLocales[
Object.keys(themeConfig.defaultLocales).includes(
req.lang
)
? req.lang
: "enUS"
]
}
if (themeConfig.locales) {
if (Object.keys(themeConfig.locales).includes(req.lang)) req.locales = themeConfig.locales[req.lang];
else req.locales = themeConfig.locales[Object.keys(themeConfig.locales)[0]];
} else
req.locales = themeConfig.defaultLocales[Object.keys(themeConfig.defaultLocales).includes(req.lang) ? req.lang : "enUS"];
next()
})
}
next();
});
}
app.use(
"/discord",
require("./Routes/discord")(app, config, themeConfig, modules)
)
app.use("/discord", discordRouter(app, config, themeConfig, modules));
if (config.useUnderMaintenance) {
app.get(
config.underMaintenanceAccessPage || "/total-secret-get-access",
(req, res) => {
res.send(`
<form action="${config.domain}${
config.underMaintenanceAccessPage ||
"/total-secret-get-access"
}" method="POST" >
<input id="accessKey" name="accessKey"/>
<button role="submit">Submit</button>
</form>
`)
}
)
if (config.useUnderMaintenance) {
app.get(config.underMaintenanceAccessPage || "/total-secret-get-access", (req, res) => {
res.send(`
<form action="${config.domain}${config.underMaintenanceAccessPage || "/total-secret-get-access"}" method="POST" >
<input id="accessKey" name="accessKey"/>
<button role="submit">Submit</button>
</form>
`);
});
app.post(
config.underMaintenanceAccessPage || "/total-secret-get-access",
(req, res) => {
if (!req.body) req.body = {}
const accessKey = req.body.accessKey
if (accessKey != config.underMaintenanceAccessKey)
return res.send("Wrong key.")
req.session.umaccess = true
res.redirect("/")
}
)
app.post(config.underMaintenanceAccessPage || "/total-secret-get-access", (req, res) => {
if (!req.body) req.body = {};
app.use((req, res, next) => {
if (req.originalUrl.startsWith("/loading")) return next()
if (!req.session.umaccess && !req.session.user) {
if (!config.useThemeMaintenance)
return res.send(
config.underMaintenanceCustomHtml ||
require("./underMaintenancePageDefault")(
config.underMaintenance,
false
)
)
else
res.render("maintenance", {
req: req,
bot: config.bot,
themeConfig: req.themeConfig,
loggedIn: false,
defaultMaintenanceConfig: config.underMaintenance || {},
})
} else if (
!req.session.umaccess &&
config.ownerIDs &&
!config.ownerIDs.includes(req.session.user.id)
) {
if (!config.useThemeMaintenance)
return res.send(
config.underMaintenanceCustomHtml ||
require("./underMaintenancePageDefault")(
config.underMaintenance,
true
)
)
else
res.render("maintenance", {
req: req,
bot: config.bot,
themeConfig: req.themeConfig,
loggedIn: true,
defaultMaintenanceConfig: config.underMaintenance || {},
})
} else next()
})
}
const accessKey = req.body.accessKey;
app.use("/", require("./Routes/main")(app, config, themeConfig, modules))
app.use(
"/",
require("./Routes/dashboard")(app, config, themeConfig, modules)
)
if (accessKey != config.underMaintenanceAccessKey) return res.send("Wrong key.");
config.theme.init(app, config)
req.session.umaccess = true;
res.redirect("/");
});
let customPages = config.customPages || []
customPages.forEach((p) => {
if (p.type == "redirect") {
app.get(p.endpoint, async (req, res) => {
let endpoint = await p.getEndpoint({
user: req.session.user || {},
req,
})
res.redirect(endpoint)
})
} else if (p.type == "html") {
app.get(p.endpoint, async (req, res) => {
let html = await p.getHtml({
user: req.session.user || {},
req,
})
res.send(html)
})
} else if (p.type == "json") {
app.get(p.endpoint, async (req, res) => {
let json = await p.getJson({
user: req.session.user || {},
req,
})
res.send(json)
})
}
})
app.use((req, res, next) => {
if (req.originalUrl.startsWith("/loading")) return next();
modules.forEach((module) => {
module.app({
app: app,
config: this.config,
themeConfig: themeConfig,
})
})
if (!req.session.umaccess && !req.session.user) {
if (!config.useThemeMaintenance)
return res.send(config.underMaintenanceCustomHtml || underMaintenancePageDefault(config.underMaintenance, false));
else
res.render("maintenance", {
req: req,
bot: config.bot,
themeConfig: req.themeConfig,
loggedIn: false,
defaultMaintenanceConfig: config.underMaintenance || {},
});
} else if (!req.session.umaccess && config.ownerIDs && !config.ownerIDs.includes(req.session.user.id)) {
if (!config.useThemeMaintenance)
return res.send(config.underMaintenanceCustomHtml || underMaintenancePageDefault(config.underMaintenance, true));
else
res.render("maintenance", {
req: req,
bot: config.bot,
themeConfig: req.themeConfig,
loggedIn: true,
defaultMaintenanceConfig: config.underMaintenance || {},
});
} else next();
});
}
if (!config.useTheme404) {
app.get("*", (req, res) => {
let text =
config.html404 ||
require("./404pagedefault")(
config.websiteTitle || themeConfig.websiteName
)
res.send(
text.replace(
"{{websiteTitle}}",
config.websiteTitle || themeConfig.websiteName
)
)
})
}
}
app.use("/", mainRouter(app, config, themeConfig, modules));
app.use("/", dashboardRouter(app, config, themeConfig, modules));
config.theme.init(app, config);
const customPages = config.customPages || [];
customPages.forEach(p => {
if (p.type == "redirect") {
app.get(p.endpoint, async (req, res) => {
const endpoint = await p.getEndpoint({
user: req.session.user || {},
req,
});
res.redirect(endpoint);
});
} else if (p.type == "html") {
app.get(p.endpoint, async (req, res) => {
const html = await p.getHtml({
user: req.session.user || {},
req,
});
res.send(html);
});
} else if (p.type == "json") {
app.get(p.endpoint, async (req, res) => {
const json = await p.getJson({
user: req.session.user || {},
req,
});
res.send(json);
});
}
});
modules.forEach(module => {
module.app({
app: app,
config: this.config,
themeConfig: themeConfig,
});
});
if (!config.useTheme404) {
app.get("*", (req, res) => {
const text = config.html404 || error404pageDefault(config.websiteTitle || themeConfig.websiteName);
res.send(text.replace("{{websiteTitle}}", config.websiteTitle || themeConfig.websiteName));
});
}
};

File diff suppressed because it is too large Load diff

View file

@ -1,288 +1,289 @@
const icons = [
'address-book',
'address-card',
'adjust',
'air-freshener',
'align-center',
'align-left',
'align-right',
'ambulance',
'angle-double-down',
'angle-double-left',
'angle-double-right',
'angle-double-up',
'angle-down',
'angle-left',
'angle-right',
'angle-up',
'archive',
'arrow-alt-circle-down',
'arrow-alt-circle-left',
'arrow-alt-circle-right',
'arrow-alt-circle-up',
'arrow-down',
'arrow-left',
'arrow-right',
'arrow-up',
'arrows-alt',
'arrows-alt-h',
'arrows-alt-v',
'assistive-listening-systems',
'asterisk',
'at',
'atlas',
'award',
'backspace',
'backward',
'bahai',
'ban',
'band-aid',
'bars',
'battery-empty',
'battery-full',
'battery-half',
'battery-quarter',
'battery-three-quarters',
'bed',
'beer',
'bell',
'bell-slash',
'birthday-cake',
'bolt',
'bomb',
'bone',
'book',
'book-dead',
'book-medical',
'book-open',
'bookmark',
'border-all',
'border-none',
'border-style',
'bowling-ball',
'box',
'box-open',
'briefcase',
'broadcast-tower',
'bug',
'building',
'bullhorn',
'calculator',
'calendar',
'calendar-alt',
'calendar-check',
'calendar-day',
'calendar-minus',
'calendar-plus',
'calendar-times',
'calendar-week',
'camera',
'caret-down',
'caret-left',
'caret-right',
'caret-up',
'certificate',
'chair',
'chalkboard',
'charging-station',
'chart-bar',
'chart-line',
'chart-pie',
'check',
'check-circle',
'check-square',
'circle',
'circle-notch',
'clipboard',
'clock',
'clone',
'cloud',
'cloud-download-alt',
'cloud-meatball',
'cloud-moon',
'cloud-moon-rain',
'cloud-rain',
'cloud-showers-heavy',
'cloud-sun',
'cloud-sun-rain',
'cloud-upload-alt',
'code',
'code-branch',
'cog',
'cogs',
'columns',
'comment',
'comment-alt',
'comment-dollar',
'comment-dots',
'comment-medical',
'comment-slash',
'comments',
'comments-dollar',
'compact-disc',
'compass',
'compress-alt',
'cookie',
'cookie-bite',
'copy',
'credit-card',
'crop',
'crop-alt',
'cut',
'database',
'desktop',
'edit',
'envelope',
'envelope-open',
'eraser',
'ethernet',
'exchange-alt',
'exclamation',
'exclamation-circle',
'exclamation-triangle',
'expand',
'expand-alt',
'external-link-alt',
'eye',
'eye-dropper',
'eye-slash',
'fan',
'file',
'file-alt',
'file-archive',
'file-audio',
'file-code',
'file-download',
'fill',
'fill-drip',
'filter',
'fingerprint',
'fire',
'fire-alt',
'folder',
'folder-open',
'forward',
'gamepad',
'ghost',
'gift',
'gifts',
'globe',
'globe-africa',
'globe-asia',
'globe-europe',
'headphones',
'headphones-alt',
'headset',
'heart',
'heart-broken',
'heartbeat',
'history',
'home',
'info',
'keyboard',
'layer-group',
'list',
'lock',
'lock-open',
'map-marker',
'map-marker-alt',
'microphone',
'microphone-alt',
'microphone-alt-slash',
'minus',
'mobile',
'mobile-alt',
'moon',
'mouse',
'mouse-pointer',
'music',
'network-wired',
'neuter',
'paperclip',
'paste',
'pause',
'paw',
'pen',
'pencil-alt',
'percent',
'percentage',
'phone',
'phone-alt',
'phone-slash',
'phone-volume',
'photo-video',
'power-off',
'question',
'question-circle',
'redo',
'redo-alt',
'reply',
'robot',
'rocket',
'rss',
'satellite-dish',
'save',
'search',
'server',
'shapes',
'share',
'share-alt',
'shield-alt',
'signal',
'skull',
'skull-crossbones',
'sliders-h',
'sort',
'spinner',
'times',
'times-circle',
'toggle-off',
'toggle-on',
'toolbox',
'tools',
'trash',
'trash-alt',
'tv',
'undo',
'undo-alt',
'unlink',
'unlock',
'unlock-alt',
'upload',
'user',
'user-alt',
'volume-down',
'volume-mute',
'volume-off',
'volume-up',
'wifi',
'wrench'
]
"address-book",
"address-card",
"adjust",
"air-freshener",
"align-center",
"align-left",
"align-right",
"ambulance",
"angle-double-down",
"angle-double-left",
"angle-double-right",
"angle-double-up",
"angle-down",
"angle-left",
"angle-right",
"angle-up",
"archive",
"arrow-alt-circle-down",
"arrow-alt-circle-left",
"arrow-alt-circle-right",
"arrow-alt-circle-up",
"arrow-down",
"arrow-left",
"arrow-right",
"arrow-up",
"arrows-alt",
"arrows-alt-h",
"arrows-alt-v",
"assistive-listening-systems",
"asterisk",
"at",
"atlas",
"award",
"backspace",
"backward",
"bahai",
"ban",
"band-aid",
"bars",
"battery-empty",
"battery-full",
"battery-half",
"battery-quarter",
"battery-three-quarters",
"bed",
"beer",
"bell",
"bell-slash",
"birthday-cake",
"bolt",
"bomb",
"bone",
"book",
"book-dead",
"book-medical",
"book-open",
"bookmark",
"border-all",
"border-none",
"border-style",
"bowling-ball",
"box",
"box-open",
"briefcase",
"broadcast-tower",
"bug",
"building",
"bullhorn",
"calculator",
"calendar",
"calendar-alt",
"calendar-check",
"calendar-day",
"calendar-minus",
"calendar-plus",
"calendar-times",
"calendar-week",
"camera",
"caret-down",
"caret-left",
"caret-right",
"caret-up",
"certificate",
"chair",
"chalkboard",
"charging-station",
"chart-bar",
"chart-line",
"chart-pie",
"check",
"check-circle",
"check-square",
"circle",
"circle-notch",
"clipboard",
"clock",
"clone",
"cloud",
"cloud-download-alt",
"cloud-meatball",
"cloud-moon",
"cloud-moon-rain",
"cloud-rain",
"cloud-showers-heavy",
"cloud-sun",
"cloud-sun-rain",
"cloud-upload-alt",
"code",
"code-branch",
"cog",
"cogs",
"columns",
"comment",
"comment-alt",
"comment-dollar",
"comment-dots",
"comment-medical",
"comment-slash",
"comments",
"comments-dollar",
"compact-disc",
"compass",
"compress-alt",
"cookie",
"cookie-bite",
"copy",
"credit-card",
"crop",
"crop-alt",
"cut",
"database",
"desktop",
"edit",
"envelope",
"envelope-open",
"eraser",
"ethernet",
"exchange-alt",
"exclamation",
"exclamation-circle",
"exclamation-triangle",
"expand",
"expand-alt",
"external-link-alt",
"eye",
"eye-dropper",
"eye-slash",
"fan",
"file",
"file-alt",
"file-archive",
"file-audio",
"file-code",
"file-download",
"fill",
"fill-drip",
"filter",
"fingerprint",
"fire",
"fire-alt",
"folder",
"folder-open",
"forward",
"gamepad",
"ghost",
"gift",
"gifts",
"globe",
"globe-africa",
"globe-asia",
"globe-europe",
"headphones",
"headphones-alt",
"headset",
"heart",
"heart-broken",
"heartbeat",
"history",
"home",
"info",
"keyboard",
"layer-group",
"list",
"lock",
"lock-open",
"map-marker",
"map-marker-alt",
"microphone",
"microphone-alt",
"microphone-alt-slash",
"minus",
"mobile",
"mobile-alt",
"moon",
"mouse",
"mouse-pointer",
"music",
"network-wired",
"neuter",
"paperclip",
"paste",
"pause",
"paw",
"pen",
"pencil-alt",
"percent",
"percentage",
"phone",
"phone-alt",
"phone-slash",
"phone-volume",
"photo-video",
"power-off",
"question",
"question-circle",
"redo",
"redo-alt",
"reply",
"robot",
"rocket",
"rss",
"satellite-dish",
"save",
"search",
"server",
"shapes",
"share",
"share-alt",
"shield-alt",
"signal",
"skull",
"skull-crossbones",
"sliders-h",
"sort",
"spinner",
"times",
"times-circle",
"toggle-off",
"toggle-on",
"toolbox",
"tools",
"trash",
"trash-alt",
"tv",
"undo",
"undo-alt",
"unlink",
"unlock",
"unlock-alt",
"upload",
"user",
"user-alt",
"volume-down",
"volume-mute",
"volume-off",
"volume-up",
"wifi",
"wrench",
];
const otherIcons = [
'youtube',
'discord',
'node',
'apple',
'sellsy',
'app-store',
'cloudflare',
'dev',
'github-alt',
'gitlab',
'google',
'itunes-note',
'node-js',
'npm',
'spotify',
'usb',
'windows'
]
"youtube",
"discord",
"node",
"apple",
"sellsy",
"app-store",
"cloudflare",
"dev",
"github-alt",
"gitlab",
"google",
"itunes-note",
"node-js",
"npm",
"spotify",
"usb",
"windows",
];
function run() {
return {
icons,
otherIcons
}
return {
icons,
otherIcons,
};
}
module.exports = run()
module.exports = run();

View file

@ -1,69 +1,48 @@
const colors = require('colors')
const npmUpdater = require('./utils/updater/npm')
const fileUpdater = require('./utils/updater/files')
const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} `
const Keyv = require('keyv')
const path = require('path')
const consolePrefix = `${"[".blue}${"dbd-soft-ui".yellow}${"]".blue} `;
const Keyv = require("keyv");
const path = require("path");
const { readFileSync } = require("fs");
module.exports = (themeConfig = {}) => {
return {
themeCodename: 'softui',
viewsPath: path.join(__dirname, '/views'),
staticPath: path.join(__dirname, '/views/src'),
themeConfig: {
...themeConfig,
defaultLocales: require('./locales.js')
},
messages: {
error: {
addonLicense: `${consolePrefix}${'Failed to initialise {{ADDON}}.\nThe license this addon was installed with does not match your current discord-dashboard license.'
.cyan
}`
},
success: {
addonLoaded: `${consolePrefix}${'Successfully loaded {{ADDON}}.'.cyan
}`
}
},
embedBuilderComponent: require('fs').readFileSync(
path.join(__dirname, '/embedBuilderComponent.txt'),
'utf8'
),
init: async (app, config) => {
if(!config?.useTheme404) return console.log(`${consolePrefix}${'You need to set useTheme404 to true in your DBD config otherwise Soft-UI will not work correctly!\n\nDashboard has not fully initialised due to this. Pages will 404!'.red}`);
return {
themeCodename: "softui",
viewsPath: path.join(__dirname, "/views"),
staticPath: path.join(__dirname, "/views/src"),
themeConfig: {
...themeConfig,
defaultLocales: require("./locales.js"),
},
messages: {
error: {
addonLicense: `${consolePrefix}${"Failed to initialise {{ADDON}}.\nThe license this addon was installed with does not match your current discord-dashboard license.".cyan}`,
},
success: {
addonLoaded: `${consolePrefix}${"Successfully loaded {{ADDON}}.".cyan}`,
},
},
embedBuilderComponent: readFileSync(path.join(__dirname, "/embedBuilderComponent.txt"), "utf8"),
init: async (app, config) => {
if (!config?.useTheme404) return console.log(`${consolePrefix}${"You need to set useTheme404 to true in your DBD config otherwise Soft-UI will not work correctly!\n\nDashboard has not fully initialised due to this. Pages will 404!".red}`);
let outdated = false
; (async () => {
let check = await npmUpdater.update()
await fileUpdater.update()
if (!check) outdated = true
})()
const db = new Keyv(themeConfig.dbdriver || "sqlite://" + path.join(__dirname, "/database.sqlite"));
const db = new Keyv(
themeConfig.dbdriver ||
'sqlite://' + path.join(__dirname, '/database.sqlite')
)
db.on("error", (err) => {
console.log("Connection Error", err);
process.exit();
});
db.on('error', (err) => {
console.log('Connection Error', err)
process.exit()
})
themeConfig = { ...themeConfig, defaultLocales: require("./locales.js") };
themeConfig = {
...themeConfig,
defaultLocales: require('./locales.js')
}
require("./utils/functions/errorHandler")(config, themeConfig, db);
require("./utils/functions/settingsPage")(config, themeConfig, db);
// await require('./utils/addonManager').execute(themeConfig, config, app, module.exports.messages);
require("./utils/initPages").init(config, themeConfig, app, db);
},
};
};
require('./utils/functions/errorHandler')(config, themeConfig, db)
require('./utils/functions/settingsPage')(config, themeConfig, db)
// await require('./utils/addonManager').execute(themeConfig, config, app, module.exports.messages);
require('./utils/initPages').init(config, themeConfig, app, db)
}
}
}
module.exports.partials = __dirname + '/views/partials'
module.exports.formTypes = require('./utils/formtypes')
module.exports.Feed = require('./utils/feedHandler')
module.exports.cmdHandler = require('./utils/cmdHandler')
module.exports.version = require('./package.json').version
module.exports.partials = __dirname + "/views/partials";
module.exports.formTypes = require("./utils/formtypes");
module.exports.Feed = require("./utils/feedHandler");
module.exports.cmdHandler = require("./utils/cmdHandler");
module.exports.version = require("./package.json").version;

View file

@ -1,95 +1,94 @@
module.exports = {
enUS: {
name: 'English',
index: {
feeds: ['Current Users', 'CPU', 'System Platform', 'Server Count'],
card: {
category: 'Soft UI',
title: 'Assistants - The center of everything',
description:
"Assistants Discord Bot management panel. Assistants Bot was created to give others the ability to do what they want. Just.<br>That's an example text.<br><br><b><i>Feel free to use HTML</i></b>",
footer: 'Learn More',
image: '/img/soft-ui.webp',
linkText: 'Learn more'
},
feedsTitle: 'Feeds',
graphTitle: 'Graphs'
},
manage: {
settings: {
memberCount: 'Members',
info: {
info: 'Info',
server: 'Server Information'
}
}
},
privacyPolicy: {
title: 'Privacy Policy',
description: 'Privacy Policy and Terms of Service'
},
partials: {
sidebar: {
dash: 'Dashboard',
manage: 'Manage Guilds',
commands: 'Commands',
pp: 'Privacy Policy',
admin: 'Admin',
account: 'Account Pages',
login: 'Sign In',
logout: 'Sign Out'
},
navbar: {
home: 'Home',
pages: {
manage: 'Manage Guilds',
settings: 'Manage Guilds',
commands: 'Commands',
pp: 'Privacy Policy',
admin: 'Admin Panel',
error: 'Error',
credits: 'Credits',
debug: 'Debug',
leaderboard: 'Leaderboard',
profile: 'Profile',
maintenance: 'Under Maintenance'
}
},
title: {
pages: {
manage: 'Manage Guilds',
settings: 'Manage Guilds',
commands: 'Commands',
pp: 'Privacy Policy',
admin: 'Admin Panel',
error: 'Error',
credits: 'Credits',
debug: 'Debug',
leaderboard: 'Leaderboard',
profile: 'Profile',
maintenance: 'Under Maintenance'
}
},
preloader: {
text: 'Page is loading...'
},
premium: {
title: 'Want more from Assistants?',
description: 'Check out premium features below!',
buttonText: 'Become Premium'
},
settings: {
title: 'Site Configuration',
description: 'Configurable Viewing Options',
theme: {
title: 'Site Theme',
description: 'Make the site more appealing for your eyes!'
},
language: {
title: 'Site Language',
description: 'Select your preferred language!'
}
}
}
}
}
enUS: {
name: "English",
index: {
feeds: ["Current Users", "CPU", "System Platform", "Server Count"],
card: {
category: "Soft UI",
title: "Assistants - The center of everything",
description: "Assistants Discord Bot management panel. Assistants Bot was created to give others the ability to do what they want. Just.<br>That's an example text.<br><br><b><i>Feel free to use HTML</i></b>",
footer: "Learn More",
image: "/img/soft-ui.webp",
linkText: "Learn more",
},
feedsTitle: "Feeds",
graphTitle: "Graphs",
},
manage: {
settings: {
memberCount: "Members",
info: {
info: "Info",
server: "Server Information",
},
},
},
privacyPolicy: {
title: "Privacy Policy",
description: "Privacy Policy and Terms of Service",
},
partials: {
sidebar: {
dash: "Dashboard",
manage: "Manage Guilds",
commands: "Commands",
pp: "Privacy Policy",
admin: "Admin",
account: "Account Pages",
login: "Sign In",
logout: "Sign Out",
},
navbar: {
home: "Home",
pages: {
manage: "Manage Guilds",
settings: "Manage Guilds",
commands: "Commands",
pp: "Privacy Policy",
admin: "Admin Panel",
error: "Error",
credits: "Credits",
debug: "Debug",
leaderboard: "Leaderboard",
profile: "Profile",
maintenance: "Under Maintenance",
},
},
title: {
pages: {
manage: "Manage Guilds",
settings: "Manage Guilds",
commands: "Commands",
pp: "Privacy Policy",
admin: "Admin Panel",
error: "Error",
credits: "Credits",
debug: "Debug",
leaderboard: "Leaderboard",
profile: "Profile",
maintenance: "Under Maintenance",
},
},
preloader: {
text: "Page is loading...",
},
premium: {
title: "Want more from Assistants?",
description: "Check out premium features below!",
buttonText: "Become Premium",
},
settings: {
title: "Site Configuration",
description: "Configurable Viewing Options",
theme: {
title: "Site Theme",
description: "Make the site more appealing for your eyes!",
},
language: {
title: "Site Language",
description: "Select your preferred language!",
},
},
},
},
};

View file

@ -1,18 +1,8 @@
{
"name": "dbd-soft-ui",
"version": "1.6.48-beta.1",
"description": "dashboard theme",
"version": "1.0",
"typings": "dbd-soft-ui.d.ts",
"author": {
"name": "iMidnight"
},
"contributors": [
"PlainDevelopment",
"Breftejk"
],
"bugs": {
"url": "https://github.com/Assistants-Center/dbd-soft-ui/issues"
},
"bundleDependencies": [],
"dependencies": {
"@keyv/sqlite": "^3.6.1",
"colors": "1.4.0",
@ -21,29 +11,100 @@
"nodeactyl": "^3.2.2",
"quick.db": "^7.1.3"
},
"deprecated": false,
"description": "Soft UI DBD Theme: An awesome - feature packed theme to use with discord-dashboard!",
"homepage": "https://softui.assistantscenter.com/",
"keywords": [
"discord",
"discord.js",
"discordjs",
"discord dashboard",
"discord web dashboard",
"web dashboard",
"dashboard"
],
"license": "MIT",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/Assistants-Center/DBD-Soft-UI.git"
},
"scripts": {
"test": "echo \"Error: no test specified\""
},
"devDependencies": {
"express": "^4.18.2",
"eslint": "^8.23.0",
"prettier": "2.7.1"
},
"eslintConfig": {
"env": {
"commonjs": true,
"es6": true,
"es2020": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {
"arrow-spacing": [
"warn",
{
"before": true,
"after": true
}
],
"comma-dangle": [
"error",
"always-multiline"
],
"comma-spacing": "error",
"comma-style": "error",
"dot-location": [
"error",
"property"
],
"handle-callback-err": "off",
"indent": [
"error",
"tab",
{
"SwitchCase": 1
}
],
"keyword-spacing": "error",
"max-nested-callbacks": [
"error",
{
"max": 4
}
],
"max-statements-per-line": [
"error",
{
"max": 2
}
],
"no-console": "off",
"no-multi-spaces": "error",
"no-multiple-empty-lines": [
"error",
{
"max": 2,
"maxEOF": 1,
"maxBOF": 0
}
],
"no-trailing-spaces": [
"error"
],
"no-var": "error",
"object-curly-spacing": [
"error",
"always"
],
"prefer-const": "error",
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"yoda": "error"
}
}
}

View file

@ -1,27 +1,24 @@
const npmUpdater = require('../../utils/updater/npm')
const fileUpdater = require('../../utils/updater/files')
module.exports = {
page: '/control',
execute: async (req, res, app, config, themeConfig, info) => {
const { uuid, action } = req.query
if (!uuid && action && req.query.type) {
if (req.query.type === 'npm') await npmUpdater.update()
if (req.query.type === 'live') await fileUpdater.update()
return res.redirect('/admin?result=true')
}
if (!uuid || !action) return res.sendStatus(412)
page: "/control",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
const { uuid, action } = req.query;
try {
if (action === 'start') await themeConfig.nodeactyl.startServer(uuid)
if (action === 'restart') await themeConfig.nodeactyl.restartServer(uuid)
if (action === 'stop') await themeConfig.nodeactyl.stopServer(uuid)
if (action === 'kill') await themeConfig.nodeactyl.killServer(uuid)
} catch (error) {
console.error(error)
return res.redirect('/admin?result=false')
}
return res.redirect('/admin?result=true')
}
}
if (!uuid && action && req.query.type) {
return res.redirect("/admin?result=true");
}
if (!uuid || !action) return res.sendStatus(412);
try {
if (action === "start") await themeConfig.nodeactyl.startServer(uuid);
if (action === "restart") await themeConfig.nodeactyl.restartServer(uuid);
if (action === "stop") await themeConfig.nodeactyl.stopServer(uuid);
if (action === "kill") await themeConfig.nodeactyl.killServer(uuid);
} catch (error) {
console.error(error);
return res.redirect("/admin?result=false");
}
return res.redirect("/admin?result=true");
}
};

View file

@ -1,193 +1,197 @@
const db = require('quick.db')
const { icons, otherIcons } = require('../../icons')
const db = require("quick.db");
const { icons, otherIcons } = require("../../icons");
module.exports = {
page: '/feed',
execute: async (req, res, app, config, themeConfig, info) => {
if (req.query.action === 'delete') {
const deleteFeed = req.query.feed
if (!deleteFeed) return res.redirect('/admin?error=invalidFeed')
if (!/^\d+$/.test(deleteFeed))
return res.redirect('/admin?error=invalidFeed')
if (deleteFeed !== '1' && deleteFeed !== '2' && deleteFeed !== '3')
return res.redirect('/admin?error=invalidFeed')
if (deleteFeed === '1') {
if (!db.get('feeds.one'))
return res.redirect('/admin?error=invalidFeed')
if (db.get('feeds.two')) {
const f = await db.get('feeds.two')
await db.set('feeds.one', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
} else {
await db.delete('feeds.one')
}
if (db.get('feeds.three')) {
const f = await db.get('feeds.three')
await db.set('feeds.two', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
await db.delete('feeds.three')
}
} else if (deleteFeed === '2') {
if (!db.get('feeds.two'))
return res.redirect('/admin?error=invalidFeed')
if (db.get('feeds.one')) {
const f = await db.get('feeds.one')
await db.set('feeds.two', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
await db.delete('feeds.one')
} else {
await db.delete('feeds.two')
}
} else if (deleteFeed === '3') {
if (!db.get('feeds.three'))
return res.redirect('/admin?error=invalidFeed')
await db.delete('feeds.three')
if (db.get('feeds.two')) {
const f = await db.get('feeds.two')
await db.set('feeds.three', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
}
if (db.get('feeds.one')) {
const f = await db.get('feeds.one')
await db.set('feeds.two', {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff
})
}
}
return res.redirect('/admin')
} else if (req.query.action === 'create') {
const { color, description, icon } = req.query
if (!color || !description || !icon)
return res.redirect('/admin?error=missingData')
if (
color !== 'red' &&
color !== 'orange' &&
color !== 'pink' &&
color !== 'gray' &&
color !== 'green' &&
color !== 'blue' &&
color !== 'dark'
)
return res.redirect('/admin?error=invalidData')
if (description.length < 3 || description.length > 128)
return res.redirect('/admin?error=invalidData')
if (!icons.includes(icon) && !otherIcons.includes(icon))
return res.redirect('/admin?error=invalidData')
let diff
let col
if (otherIcons.includes(icon)) diff = true
if (color === 'red') col = 'danger'
if (color === 'orange') col = 'warning'
if (color === 'pink') col = 'primary'
if (color === 'gray') col = 'secondary'
if (color === 'green') col = 'success'
if (color === 'blue') col = 'info'
if (color === 'dark') col = 'dark'
if (
db.get('feeds.three') &&
db.get('feeds.two') &&
db.get('feeds.one')
) {
await db.delete('feeds.one')
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.two', {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.one', {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
} else {
if (!db.get('feeds.three'))
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
else if (!db.get('feeds.two')) {
const f3 = db.get('feeds.three')
await db.set('feeds.two', {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
} else {
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.one', {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.two', {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
}
}
return res.redirect('/admin')
}
}
}
page: "/feed",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
if (req.query.action === "delete") {
const deleteFeed = req.query.feed;
if (!deleteFeed) return res.redirect("/admin?error=invalidFeed");
if (!/^\d+$/.test(deleteFeed)) return res.redirect("/admin?error=invalidFeed");
if (deleteFeed !== "1" && deleteFeed !== "2" && deleteFeed !== "3") return res.redirect("/admin?error=invalidFeed");
if (deleteFeed === "1") {
if (!db.get("feeds.one")) return res.redirect("/admin?error=invalidFeed");
if (db.get("feeds.two")) {
const f = await db.get("feeds.two");
await db.set("feeds.one", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
} else await db.delete("feeds.one");
if (db.get("feeds.three")) {
const f = await db.get("feeds.three");
await db.set("feeds.two", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
await db.delete("feeds.three");
}
} else if (deleteFeed === "2") {
if (!db.get("feeds.two")) return res.redirect("/admin?error=invalidFeed");
if (db.get("feeds.one")) {
const f = await db.get("feeds.one");
await db.set("feeds.two", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
await db.delete("feeds.one");
} else {
await db.delete("feeds.two");
}
} else if (deleteFeed === "3") {
if (!db.get("feeds.three")) return res.redirect("/admin?error=invalidFeed");
await db.delete("feeds.three");
if (db.get("feeds.two")) {
const f = await db.get("feeds.two");
await db.set("feeds.three", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
}
if (db.get("feeds.one")) {
const f = await db.get("feeds.one");
await db.set("feeds.two", {
color: f.color,
description: f.description,
published: f.published,
icon: f.icon,
diff: f.diff,
});
}
}
return res.redirect("/admin");
} else if (req.query.action === "create") {
const { color, description, icon } = req.query;
if (!color || !description || !icon) return res.redirect("/admin?error=missingData");
if (color !== "red" && color !== "orange" && color !== "pink" && color !== "gray" && color !== "green" && color !== "blue" && color !== "dark") return res.redirect("/admin?error=invalidData");
if (description.length < 3 || description.length > 128) return res.redirect("/admin?error=invalidData");
if (!icons.includes(icon) && !otherIcons.includes(icon)) return res.redirect("/admin?error=invalidData");
let diff;
let col;
if (otherIcons.includes(icon)) diff = true;
if (color === "red") col = "danger";
if (color === "orange") col = "warning";
if (color === "pink") col = "primary";
if (color === "gray") col = "secondary";
if (color === "green") col = "success";
if (color === "blue") col = "info";
if (color === "dark") col = "dark";
if (db.get("feeds.three") && db.get("feeds.two") && db.get("feeds.one")) {
await db.delete("feeds.one");
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff,
});
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
} else {
if (!db.get("feeds.three")) {
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
} else if (!db.get("feeds.two")) {
const f3 = db.get("feeds.three");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
} else {
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff,
});
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
}
}
return res.redirect("/admin");
}
},
};

View file

@ -1,48 +1,45 @@
const db = require('quick.db')
const db = require("quick.db");
module.exports = {
page: '/admin',
execute: async (req, res, app, config, themeConfig, info, database) => {
if (!req.session.user) return res.redirect('/discord?r=/admin/')
if (!config.ownerIDs?.includes(req.session.user.id))
return res.redirect('/')
if (!themeConfig.nodeactyl && themeConfig.admin?.pterodactyl?.enabled)
return res.send(
'Unable to contact Pterodactyl, are your details correct?'
)
page: "/admin",
execute: async (req, res, app, config, themeConfig, info, database) => {
if (!req.session.user) return res.redirect("/discord?r=/admin/");
if (!config.ownerIDs?.includes(req.session.user.id)) return res.redirect("/");
if (!themeConfig.nodeactyl && themeConfig.admin?.pterodactyl?.enabled) return res.send("Unable to contact Pterodactyl, are your details correct?");
async function getServers() {
if (!themeConfig?.admin?.pterodactyl?.enabled) return []
const serverData = []
for (const uuid of themeConfig?.admin?.pterodactyl?.serverUUIDs) {
let dataStatus = await themeConfig?.nodeactyl?.getServerStatus(uuid)
let data = await themeConfig?.nodeactyl?.getServerDetails(uuid)
serverData.push({
name: data.name.toString(),
uuid: data.uuid.toString(),
desc: data.description.toString(),
node: data.node.toString(),
status: dataStatus.toString()
})
}
return serverData
}
async function getServers() {
if (!themeConfig?.admin?.pterodactyl?.enabled) return [];
let allFeedsUsed = false
if (db.get('feeds.one') && db.get('feeds.two') && db.get('feeds.three'))
allFeedsUsed = true
const d = await getServers()
res.render('admin', {
req,
sData: d,
ldata: await database.get('logs'),
themeConfig: req.themeConfig,
node: themeConfig.nodeactyl,
bot: config.bot,
allFeedsUsed,
config,
require
})
}
}
const serverData = [];
const serverUUIDS = themeConfig?.admin?.pterodactyl?.serverUUIDs;
for (const uuid of serverUUIDS) {
const dataStatus = await themeConfig?.nodeactyl?.getServerStatus(uuid);
const data = await themeConfig?.nodeactyl?.getServerDetails(uuid);
serverData.push({
name: data.name.toString(),
uuid: data.uuid.toString(),
desc: data.description.toString(),
node: data.node.toString(),
status: dataStatus.toString(),
});
}
return serverData;
}
const d = await getServers();
res.render("admin", {
req,
sData: d,
ldata: await database.get("logs"),
themeConfig: req.themeConfig,
node: themeConfig.nodeactyl,
bot: config.bot,
allFeedsUsed: (db.get("feeds.one") && db.get("feeds.two") && db.get("feeds.three")) ? true : false,
config,
require,
});
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/blacklisted',
execute: async (req, res, app, config, themeConfig, info) => {
res.render('blacklisted', {
req,
config,
themeConfig,
info
})
}
}
page: "/blacklisted",
execute: async (req, res, app, config, themeConfig, info) => {
res.render("blacklisted", {
req,
config,
themeConfig,
info,
});
},
};

View file

@ -1,12 +1,12 @@
module.exports = {
page: '/commands',
execute: async (req, res, app, config, themeConfig, info) => {
if (themeConfig.commands)
res.render('commands.ejs', {
req,
config,
themeConfig,
info
})
}
}
page: "/commands",
execute: async (req, res, app, config, themeConfig, info) => {
if (themeConfig.commands)
res.render("commands", {
req,
config,
themeConfig,
info,
});
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/credits',
execute: async (req, res, app, config, themeConfig, info) => {
res.render('credits', {
req: req,
config,
themeConfig,
info
})
}
}
page: "/credits",
execute: async (req, res, app, config, themeConfig, info) => {
res.render("credits", {
req: req,
config,
themeConfig,
info,
});
},
};

View file

@ -1,70 +1,45 @@
const fetch = require('node-fetch')
const fs = require('fs')
let DBD = require('discord-dashboard')
const fetch = require("node-fetch");
const fs = require("fs");
const DBD = require("../../../../index");
module.exports = {
page: '/debug',
execute: async (req, res, app, config, themeConfig, info) => {
/*
Do not remove this page.
It will be used with support in the discord server.
*/
if (!req.session.user) return res.redirect('/discord?r=/debug/')
if (!config.ownerIDs?.includes(req.session.user.id))
return res.redirect('/')
page: "/debug",
execute: async (req, res, app, config, themeConfig, info) => {
/*
Do not remove this page.
It will be used with support in the discord server.
*/
if (!req.session.user) return res.redirect("/discord?r=/debug/");
if (!config.ownerIDs?.includes(req.session.user.id)) return res.redirect("/");
let onlineFiles = {
index: await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/index.ejs`
),
guild: await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guild.ejs`
),
guilds: await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guilds.ejs`
)
}
const onlineFiles = {
index: await fetch("https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/index.ejs"),
guild: await fetch("https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guild.ejs"),
guilds: await fetch("https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/guilds.ejs"),
};
onlineFiles.index = await onlineFiles.index.text()
onlineFiles.guild = await onlineFiles.guild.text()
onlineFiles.guilds = await onlineFiles.guilds.text()
let localFiles = {
index: await fs.readFileSync(
`${__dirname}/../..//views/index.ejs`,
'utf-8'
),
guild: await fs.readFileSync(
`${__dirname}/../../views/settings.ejs`,
'utf-8'
),
guilds: await fs.readFileSync(
`${__dirname}/../../views/guilds.ejs`,
'utf-8'
)
}
onlineFiles.index = await onlineFiles.index.text();
onlineFiles.guild = await onlineFiles.guild.text();
onlineFiles.guilds = await onlineFiles.guilds.text();
let onlineV = await fetch(
`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/utils/updater/versionsOnline.json`
)
const localV = require(`${__dirname}/../../utils/updater/versions.json`)
onlineV = await onlineV.json()
const localFiles = {
index: await fs.readFileSync(`${__dirname}/../../views/index.ejs`, "utf-8"),
guild: await fs.readFileSync(`${__dirname}/../../views/settings.ejs`, "utf-8"),
guilds: await fs.readFileSync(`${__dirname}/../../views/guilds.ejs`, "utf-8"),
};
res.render('debug', {
license: require(`discord-dashboard`).licenseInfo().type, // replace with discord-dashboard
onlineV,
localV,
onlineFiles,
localFiles,
rawUptime: process.uptime(),
nodeVersion: process.version,
themeConfig,
discordVersion: require('discord.js').version,
dbdVersion: DBD.version,
themeVersion: require(`dbd-soft-ui`).version,
themePartials: require(`${__dirname}/../../utils/updater/versions.json`),
req,
config,
info
})
}
}
res.render("debug", {
onlineFiles,
localFiles,
rawUptime: process.uptime(),
nodeVersion: process.version,
themeConfig,
discordVersion: require("discord.js").version,
dbdVersion: DBD.version,
themeVersion: require("dbd-soft-ui").version,
req,
config,
info,
});
},
};

View file

@ -1,8 +1,8 @@
module.exports = {
page: '/shards/get',
execute: async (req, res, app, config, themeConfig, info, db) => {
let returned = await db.get('stats')
page: "/shards/get",
execute: async (req, res, app, config, themeConfig, info, db) => {
const returned = await db.get("stats");
res.json(returned)
}
}
res.json(returned);
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/privacy-policy',
execute: async (req, res, app, config, themeConfig, info) => {
res.render('pp', {
req,
config,
themeConfig,
info
})
}
}
page: "/privacy-policy",
execute: async (req, res, app, config, themeConfig, info) => {
res.render("pp", {
req,
config,
themeConfig,
info,
});
},
};

View file

@ -1,11 +1,11 @@
module.exports = {
page: '/settings/:id/:category',
execute: async (req, res, app, config, themeConfig, info) => {
const categoryExists = config.settings?.find(
(s) => s.categoryId === req.params.category
)
if (!categoryExists) return config.errorPage(req, res, null, 404)
page: "/settings/:id/:category",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
const categoryExists = config.settings?.find(s => s.categoryId === req.params.category);
await config.guildSettings(req, res, false, req.params.category)
}
}
if (!categoryExists) return config.errorPage(req, res, null, 404);
await config.guildSettings(req, res, false, req.params.category);
},
};

View file

@ -1,6 +1,7 @@
module.exports = {
page: '/settings/:id/',
execute: async (req, res, app, config, themeConfig, info) => {
await config.guildSettings(req, res, true)
}
}
page: "/settings/:id/",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
await config.guildSettings(req, res, true);
},
};

View file

@ -1,11 +1,12 @@
module.exports = {
page: '/shards',
execute: async (req, res, app, config, themeConfig, info, db) => {
res.render('shards', {
req: req,
config,
themeConfig,
info
})
}
}
page: "/shards",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info, db) => {
res.render("shards", {
req: req,
config,
themeConfig,
info,
});
},
};

View file

@ -1,476 +1,392 @@
module.exports = {
page: '/guild/update/:guildId/',
execute: async (req, res, app, config, themeConfig, info) => {
const data = req.body
page: "/guild/update/:guildId/",
// eslint-disable-next-line no-unused-vars
execute: async (req, res, app, config, themeConfig, info) => {
const data = req.body;
let setNewRes
let errors = []
let successes = []
let setNewRes;
const errors = [];
const successes = [];
if (!req.session?.user)
return res.send({
success: false,
message: 'User is not logged in'
})
if (!req.session?.user) return res.send({
success: false,
message: "User is not logged in",
});
const userGuildMemberObject = config.bot.guilds.cache
.get(req.params.guildId)
.members.cache.get(req.session.user.id)
const guildObject = config.bot.guilds.cache.get(req.params.guildId)
const userGuildMemberObject = config.bot.guilds.cache.get(req.params.guildId).members.cache.get(req.session.user.id);
const guildObject = config.bot.guilds.cache.get(req.params.guildId);
let category = config.settings?.find((c) => c.categoryId == req.query.categoryId)
const category = config.settings?.find(c => c.categoryId == req.query.categoryId);
const catO = [];
const catToggle = [];
let catO = [];
let catToggle = [];
if (data.categoryToggle) {
for (const s of data.categoryToggle) {
if (!config.useCategorySet) try {
const category = config.settings?.find(c => c?.categoryId == s.id);
if (data.categoryToggle) {
for (const s of data.categoryToggle) {
if (!config.useCategorySet) try {
let category = config.settings?.find(
(c) => c?.categoryId == s.id
)
await category.setNew({
guild: { id: req.params.guildId },
newData: s.value
})
} catch (err) {
errors.push(`Category ${s.id} %is%Failed to save%is%categoryToggle`);
}
else {
if (category?.categoryId == s.id) catO.push({
optionId: category.categoryId == s.id ? "categoryToggle" : s.id,
data: s.value
});
else catToggle.push({
optionId: s.id,
data: s.value
});
}
}
if ("categoryToggle" in data && !category) {
return res.send({
success: true,
message: "Saved toggle",
errors: [],
successes: [],
})
}
}
await category.setNew({
guild: { id: req.params.guildId },
newData: s.value,
});
} catch (err) {
errors.push(`Category ${s.id} %is%Failed to save%is%categoryToggle`);
}
else {
if (category?.categoryId == s.id) catO.push({
optionId: category.categoryId == s.id ? "categoryToggle" : s.id,
data: s.value,
});
else catToggle.push({
optionId: s.id,
data: s.value,
});
}
}
if ("categoryToggle" in data && !category) {
return res.send({
success: true,
message: "Saved toggle",
errors: [],
successes: [],
});
}
}
if (!category)
return res.send({
error: true,
message: "No category found",
})
if (!category) return res.send({
error: true,
message: "No category found",
});
const subOptions = category.categoryOptionsList.filter((o) => o.optionType.type == "multiRow")
.map((o) => o.optionType.options)
.flat()
const subOptions = category.categoryOptionsList.filter(o => o.optionType.type == "multiRow").map(o => o.optionType.options).flat();
const newOptionsList = [
...category.categoryOptionsList.filter((o) => o.optionType.type != "multiRow"),
...subOptions
]
const newOptionsList = [
...category.categoryOptionsList.filter((o) => o.optionType.type != "multiRow"),
...subOptions,
];
if (data.options) for (let option of newOptionsList) {
let d = data.options.find((o) => o.id === option.optionId);
let canUse = {}
if (data.options)
for (const option of newOptionsList) {
const d = data.options.find(o => o.id === option.optionId);
let canUse = {};
if (!d && !d?.id) continue;
if (!d && !d?.id) continue;
if (option.allowedCheck) canUse = await option.allowedCheck({
guild: { id: req.params.guildId },
user: { id: req.session.user.id },
})
else canUse = { allowed: true, errorMessage: null }
if (option.allowedCheck) canUse = await option.allowedCheck({
guild: { id: req.params.guildId },
user: { id: req.session.user.id },
});
else canUse = {
allowed: true,
errorMessage: null,
};
if (canUse.allowed == false) {
setNewRes = { error: canUse.errorMessage }
errors.push(
option.optionName +
"%is%" +
setNewRes.error +
"%is%" +
option.optionId
)
} else if (option.optionType != "spacer") {
if (config.useCategorySet) {
if (option.optionType.type == "rolesMultiSelect" || option.optionType.type == "channelsMultiSelect" || option.optionType.type == "multiSelect" || option.optionType.type == 'tagInput') {
if (!d.value || d.value == null || d.value == undefined) catO.push({
optionId: option.optionId,
data: [],
})
else if (typeof d.value != "object") catO.push({
optionId: option.optionId,
data: [d.value],
})
else catO.push({
optionId: option.optionId,
data: d.value,
})
} else if (option.optionType.type == "switch") {
if (
d.value ||
d.value == null ||
d.value == undefined ||
d.value == false
) {
if (d.value || d.value == null || d.value == undefined || d.value == false) {
if (d.value == null || d.value == undefined || d.value == false)
catO.push({
optionId: option.optionId,
data: false
});
else
catO.push({
optionId: option.optionId,
data: true
});
}
}
} else if (option.optionType.type == "embedBuilder") {
if (
d.value == null ||
d.value == undefined
)
catO.push({
optionId: option.optionId,
data: option.optionType.data,
})
else {
try {
const parsedResponse = JSON.parse(
d.value
)
catO.push({
optionId: option.optionId,
data: parsedResponse,
})
} catch (err) {
catO.push({
optionId: option.optionId,
data: option.optionType.data,
})
}
}
} else {
if (
d.value == undefined ||
d.value == null
)
catO.push({
optionId: option.optionId,
data: null,
})
else
catO.push({
optionId: option.optionId,
data: d.value,
})
}
} else {
if (
option.optionType.type ==
'rolesMultiSelect' ||
option.optionType.type ==
'channelsMultiSelect' ||
option.optionType.type == 'multiSelect' ||
option.optionType.type == 'tagInput'
) {
if (
!d.value ||
d.value == null ||
d.value == undefined
) {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: []
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else if (
typeof d.value != 'object'
) {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: [d.value]
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: d.value
})
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
}
} else if (
option.optionType.type == 'embedBuilder'
) {
if (
d.value !== null ||
d.value !== undefined
) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: JSON.parse(
d.value
)
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
try {
const parsedResponse = JSON.parse(
d.value
)
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: parsedResponse
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(
option.optionName
)
}
} catch (err) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData:
option.optionType.data
})) || {}
setNewRes = {
error: 'JSON parse for embed builder went wrong, your settings have been reset.'
}
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(
option.optionName
)
}
}
}
} else {
if (
d.value == undefined ||
d.value == null
) {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: null
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
} else {
setNewRes =
(await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject
},
user: {
id: req.session.user.id,
object: userGuildMemberObject
},
newData: d.value
})) || {}
setNewRes ? null : (setNewRes = {})
if (setNewRes.error) {
errors.push(
option.optionName +
'%is%' +
setNewRes.error +
'%is%' +
option.optionId
)
} else {
successes.push(option.optionName)
}
}
}
}
}
}
if (canUse.allowed == false) {
setNewRes = {
error: canUse.errorMessage,
};
if (config.useCategorySet && catO.length) {
let sNR = await category.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
data: catO,
})
sNR ? null : (sNR = {})
if (sNR.error) {
errors.push(category.categoryId + "%is%" + sNR.error)
} else {
successes.push(category.categoryId)
}
}
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
} else if (option.optionType != "spacer") {
if (config.useCategorySet) {
if (option.optionType.type == "rolesMultiSelect" || option.optionType.type == "channelsMultiSelect" || option.optionType.type == "multiSelect" || option.optionType.type == "tagInput") {
if (!d.value || d.value == null || d.value == undefined) catO.push({
optionId: option.optionId,
data: [],
});
else if (typeof d.value != "object") catO.push({
optionId: option.optionId,
data: [d.value],
});
else catO.push({
optionId: option.optionId,
data: d.value,
});
} else if (option.optionType.type == "switch") {
if (d.value || d.value == null || d.value == undefined || d.value == false) {
if (d.value || d.value == null || d.value == undefined || d.value == false) {
if (d.value == null || d.value == undefined || d.value == false)
catO.push({
optionId: option.optionId,
data: false,
});
else
catO.push({
optionId: option.optionId,
data: true,
});
}
}
} else if (option.optionType.type == "embedBuilder") {
if (d.value == null || d.value == undefined)
catO.push({
optionId: option.optionId,
data: option.optionType.data,
});
else {
try {
const parsedResponse = JSON.parse(d.value);
if (config.useCategorySet && catToggle.length) for (const opt of catToggle) {
let cat = config.settings?.find((c) => c.categoryId == opt.optionId);
catO.push({
optionId: option.optionId,
data: parsedResponse,
});
} catch (err) {
catO.push({
optionId: option.optionId,
data: option.optionType.data,
});
}
}
} else {
if (d.value == undefined || d.value == null)
catO.push({
optionId: option.optionId,
data: null,
});
else
catO.push({
optionId: option.optionId,
data: d.value,
});
}
} else {
if (option.optionType.type == "rolesMultiSelect" || option.optionType.type == "channelsMultiSelect" || option.optionType.type == "multiSelect" || option.optionType.type == "tagInput") {
if (!d.value || d.value == null || d.value == undefined) {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: [],
});
if (!cat) {
errors.push(`Category ${opt.optionId} %is%Doesn't exist%is%categoryToggle`);
continue;
}
setNewRes ? null : (setNewRes = {});
try {
await cat.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
data: [{
optionId: "categoryToggle",
data: opt.data
}],
});
} catch (err) {
errors.push(`Category ${opt.optionId} %is%${err}%is%categoryToggle`);
}
}
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
} else if (typeof d.value != "object") {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: [d.value],
});
req.DBDEvents.emit('guildSettingsUpdated', {
user: req.session.user,
changes: { successes, errors }
})
setNewRes ? null : (setNewRes = {});
res.send({
success: true,
message: 'saved changed',
errors,
successes
})
}
}
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
} else {
setNewRes = await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: d.value,
});
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
}
} else if (option.optionType.type == "embedBuilder") {
if (d.value !== null || d.value !== undefined) {
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: JSON.parse(
d.value,
),
})) || {};
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
} else {
try {
const parsedResponse = JSON.parse(d.value);
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: parsedResponse,
})) || {};
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
} catch (err) {
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: option.optionType.data,
})) || {};
setNewRes = {
error: "JSON parse for embed builder went wrong, your settings have been reset.",
};
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
}
}
} else {
if (d.value == undefined || d.value == null) {
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: null,
})) || {};
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
} else {
setNewRes = (await option.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
newData: d.value,
})) || {};
setNewRes ? null : (setNewRes = {});
if (setNewRes.error)
errors.push(option.optionName + "%is%" + setNewRes.error + "%is%" + option.optionId);
else
successes.push(option.optionName);
}
}
}
}
}
if (config.useCategorySet && catO.length) {
let sNR = await category.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
data: catO,
});
sNR ? null : (sNR = {});
if (sNR.error)
errors.push(category.categoryId + "%is%" + sNR.error);
else
successes.push(category.categoryId);
}
if (config.useCategorySet && catToggle.length)
for (const opt of catToggle) {
const cat = config.settings?.find(c => c.categoryId == opt.optionId);
if (!cat) {
errors.push(`Category ${opt.optionId} %is%Doesn't exist%is%categoryToggle`);
continue;
}
try {
await cat.setNew({
guild: {
id: req.params.guildId,
object: guildObject,
},
user: {
id: req.session.user.id,
object: userGuildMemberObject,
},
data: [{
optionId: "categoryToggle",
data: opt.data,
}],
});
} catch (err) {
errors.push(`Category ${opt.optionId} %is%${err}%is%categoryToggle`);
}
}
req.DBDEvents.emit("guildSettingsUpdated", {
user: req.session.user,
changes: {
successes,
errors,
},
});
res.send({
success: true,
message: "saved changed",
errors,
successes,
});
},
};

View file

@ -1,23 +1,21 @@
module.exports = {
page: '/stats/logs/update',
execute: async (req, res, app, config, themeConfig, info, db) => {
if (
'Bearer ' + themeConfig.admin?.logs?.key !==
req.headers.authorization
)
return res.json({ status: 'Invalid sharding key' })
page: "/stats/logs/update",
execute: async (req, res, app, config, themeConfig, info, db) => {
if ("Bearer " + themeConfig.admin?.logs?.key !== req.headers.authorization) return res.json({ status: "Invalid sharding key" });
const logs = await db.get('logs')
const logs = await db.get("logs");
let newLogs = []
let newLogs = [];
if (!logs || !logs.length || !logs[0])
newLogs = [req.body]
else
newLogs = [req.body, ...logs]
if (!logs || !logs.length || !logs[0])
newLogs = [req.body];
else
newLogs = [req.body, ...logs];
await db.set('logs', newLogs)
await db.set("logs", newLogs);
res.json({ status: 'Completed' })
}
}
res.json({
status: "Completed",
});
},
};

View file

@ -1,36 +1,34 @@
module.exports = {
page: '/stats/shards/update',
execute: async (req, res, app, config, themeConfig, info, db) => {
if (
'Bearer ' + themeConfig.shardspage?.key !==
req.headers.authorization
)
return res.json({ status: 'Invalid sharding key' })
page: "/stats/shards/update",
execute: async (req, res, app, config, themeConfig, info, db) => {
if ("Bearer " + themeConfig.shardspage?.key !== req.headers.authorization) return res.json({ status: "Invalid sharding key" });
const stats = await db.get('stats')
const stats = await db.get("stats");
const clean = req.body.map((s) => {
if (!stats) return {
...s,
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping]
}
const clean = req.body.map((s) => {
if (!stats) return {
...s,
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
};
const currentSaved = stats?.find((x) => x.id === s.id)
if (!currentSaved) return {
...s,
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping]
}
const currentSaved = stats?.find((x) => x.id === s.id);
if (!currentSaved) return {
...s,
ping: [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
};
const nextPing = currentSaved?.ping?.slice(1, 10)
const nextPing = currentSaved?.ping?.slice(1, 10);
return {
...s,
ping: nextPing ? [...nextPing, s.ping] : [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
}
})
return {
...s,
ping: nextPing ? [...nextPing, s.ping] : [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping],
};
});
await db.set('stats', clean)
await db.set("stats", clean);
res.json({ status: 'Completed' })
}
}
res.json({
status: "Completed",
});
},
};

View file

@ -1,52 +1,42 @@
module.exports = (commands, prefix) => {
if (!commands)
throw new Error('No commands were provided to the Soft UI cmdHandler.')
if (!prefix) prefix = '!'
if (!commands) throw new Error("No commands were provided to the Soft UI cmdHandler.");
if (!prefix) prefix = "/";
let finalCategories = []
let categories = []
const finalCategories = [];
const categories = [];
commands.map((cmd) => {
if (!categories.includes(cmd.category)) {
categories.push(cmd.category)
}
})
commands.map(cmd => {
if (!categories.includes(cmd.category)) categories.push(cmd.category);
});
for (const category of categories) {
if (
category.toLowerCase().includes('admin') ||
category.toLowerCase().includes('owner') ||
category.toLowerCase().includes('development')
)
continue
let commandsArr = []
for (const category of categories) {
if (category.toLowerCase().includes("admin") || category.toLowerCase().includes("owner") || category.toLowerCase().includes("development") || category.toLowerCase().includes("suncountry") || category.toLowerCase().includes("iat")) continue;
const commandsArr = [];
commands
.filter((cmd) => cmd.category === category)
.map((cmd) => {
let obj = {
commandName: cmd.name,
commandUsage: `${cmd.usage ? cmd.usage : `${prefix}${cmd.name}`}`,
commandDescription: cmd.description,
commandAlias: cmd.aliases?.join(', ') || 'None'
}
commandsArr.push(obj)
})
commands.filter(cmd => cmd.category === category).map(cmd => {
const obj = {
commandName: cmd.name,
commandUsage: `${cmd.usage ? cmd.usage : `${prefix}${cmd.name}`}`,
commandDescription: cmd.description,
commandAlias: cmd.aliases?.join(", ") || "None",
};
commandsArr.push(obj);
});
const categoryObj = {
categoryId: category,
category: `${capitalizeFirstLetter(category)}`,
subTitle: `${capitalizeFirstLetter(category)} commands`,
list: commandsArr
}
const categoryObj = {
categoryId: category,
category: `${capitalizeFirstLetter(category)}`,
subTitle: `${capitalizeFirstLetter(category)} commands`,
list: commandsArr,
};
finalCategories.push(categoryObj)
}
finalCategories.push(categoryObj);
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
return finalCategories
}
return finalCategories;
};

View file

@ -1,165 +1,171 @@
const db = require('quick.db')
const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} `
const colors = require('colors')
const { icons, otherIcons } = require('../icons')
const db = require("quick.db");
const consolePrefix = `${"[".blue}${"dbd-soft-ui".yellow}${"]".blue} `;
const colors = require("colors");
const { icons, otherIcons } = require("../icons");
module.exports = class Feed {
constructor() {
this.setColor = function (color) {
if (!color) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid color.')}`.cyan}`);
if (
color !== 'red' &&
color !== 'orange' &&
color !== 'pink' &&
color !== 'gray' &&
color !== 'green' &&
color !== 'blue' &&
color !== 'dark'
) {
throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid color.')}`.cyan}`);
}
constructor() {
this.setColor = function (color) {
if (!color) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid color.")}`.cyan}`);
if (color !== "red" && color !== "orange" && color !== "pink" && color !== "gray" && color !== "green" && color !== "blue" && color !== "dark") throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid color.")}`.cyan}`);
this.color = color;
return this;
}
this.color = color;
return this;
};
this.setDescription = function (description) {
if (!description) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid description.')}`.cyan}`);
if (description.length < 3 || description.length > 128) console.log(`${consolePrefix}${'Invalid description'.cyan}`);
this.description = description;
return this;
}
this.setDescription = function (description) {
if (!description) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid description.")}`.cyan}`);
if (description.length < 3 || description.length > 128) console.log(`${consolePrefix}${"Invalid description".cyan}`);
this.setIcon = function (icon) {
if (!icon) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid icon.')}`.cyan}`);
if (!icons.includes(icon) && !otherIcons.includes(icon)) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red('Invalid icon.')}`.cyan}`);
this.icon = icon;
return this;
}
this.description = description;
return this;
};
this.getFeed = function (id) {
if (!id) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red('Invalid id.')}`.cyan}`);
let feedName = '';
switch (id) {
case 1:
feedName = 'one';
break;
case 2:
feedName = 'two';
break;
case 3:
feedName = 'three';
break;
case "all":
feedName = 'all';
break;
default:
throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red('Invalid id.')}`.cyan}`);
}
this.setIcon = function (icon) {
if (!icon) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid icon.")}`.cyan}`);
if (!icons.includes(icon) && !otherIcons.includes(icon)) throw new Error(`${consolePrefix}${`Failed to modify feed. ${colors.red("Invalid icon.")}`.cyan}`);
let feed = db.get(`feeds${feedName === "all" ? "" : `.${feedName}`}`)
if (!feed) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red('Feed not found.')}`.cyan}`);
this.feed = feed;
return this;
}
this.icon = icon;
return this;
};
this.delete = function () {
if (!this.feed)throw new Error(`${consolePrefix}${`Failed to delete feed. ${colors.red('Feed not selected')}`.cyan}`);
db.delete(`feeds.${this.feed.id}`);
return this;
}
this.getFeed = function (id) {
if (!id) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red("Invalid id.")}`.cyan}`);
this.send = async function () {
const { color, description, icon } = this;
let feedName = "";
switch (id) {
case 1:
feedName = "one";
break;
case 2:
feedName = "two";
break;
case 3:
feedName = "three";
break;
case "all":
feedName = "all";
break;
default:
throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red("Invalid id.")}`.cyan}`);
}
let diff;
let col;
if (otherIcons.includes(icon)) diff = true;
const feed = db.get(`feeds${feedName === "all" ? "" : `.${feedName}`}`);
if (color === 'red') col = 'danger';
if (color === 'orange') col = 'warning';
if (color === 'pink') col = 'primary';
if (color === 'gray') col = 'secondary';
if (color === 'green') col = 'success';
if (color === 'blue') col = 'info';
if (color === 'dark') col = 'dark';
if (!feed) throw new Error(`${consolePrefix}${`Failed to get feed. ${colors.red("Feed not found.")}`.cyan}`);
if (db.get('feeds.three') && db.get('feeds.two') && db.get('feeds.one')) {
await db.delete('feeds.one')
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.two', {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.one', {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
} else {
if (!db.get('feeds.three')) {
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
} else if (!db.get('feeds.two')) {
const f3 = db.get('feeds.three')
await db.set('feeds.two', {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
} else {
const f3 = db.get('feeds.three')
const f2 = db.get('feeds.two')
await db.set('feeds.one', {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff
})
await db.set('feeds.two', {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff
})
await db.set('feeds.three', {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff
})
}
}
}
}
}
this.feed = feed;
return this;
};
this.delete = function () {
if (!this.feed) throw new Error(`${consolePrefix}${`Failed to delete feed. ${colors.red("Feed not selected")}`.cyan}`);
db.delete(`feeds.${this.feed.id}`);
return this;
};
this.send = async function () {
const { color, description, icon } = this;
let diff;
let col;
if (otherIcons.includes(icon)) diff = true;
if (color === "red") col = "danger";
if (color === "orange") col = "warning";
if (color === "pink") col = "primary";
if (color === "gray") col = "secondary";
if (color === "green") col = "success";
if (color === "blue") col = "info";
if (color === "dark") col = "dark";
if (db.get("feeds.three") && db.get("feeds.two") && db.get("feeds.one")) {
await db.delete("feeds.one");
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff,
});
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
} else {
if (!db.get("feeds.three")) {
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
} else if (!db.get("feeds.two")) {
const f3 = db.get("feeds.three");
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
} else {
const f3 = db.get("feeds.three");
const f2 = db.get("feeds.two");
await db.set("feeds.one", {
color: f2.color,
description: f2.description,
published: f2.published,
icon: f2.icon,
diff: f2.diff,
});
await db.set("feeds.two", {
color: f3.color,
description: f3.description,
published: f3.published,
icon: f3.icon,
diff: f3.diff,
});
await db.set("feeds.three", {
color: col,
description: description,
published: Date.now(),
icon: icon,
diff: diff,
});
}
}
};
}
};

View file

@ -1,63 +1,63 @@
module.exports = {
multiRow: (options) => {
// Validate Data
if (options && (!options.length || !options[0])) throw new Error("Options in the 'collapsable' form type should be an array.");
multiRow: (options) => {
// Validate Data
if (options && (!options.length || !options[0])) throw new Error("Options in the 'collapsable' form type should be an array.");
const hasType = (object) => object.hasOwnProperty('optionType') && object.optionType?.hasOwnProperty('type');
const hasType = object => Object.prototype.hasOwnProperty.call(object, "optionType") && Object.prototype.hasOwnProperty.call(object.optionType, "type");
if (options && !options.every(hasType)) throw new Error("Invalid form type provided in the 'multiRow' form type.");
if (options && !options.every(hasType)) throw new Error("Invalid form type provided in the 'multiRow' form type.");
if (options && options.find(obj => obj.optionType.type == "multiRow")) throw new Error("You cannot use the form type 'multiRow' in the 'multiRow' form type.");
if (options && options.find(obj => obj.optionType.type == "multiRow")) throw new Error("You cannot use the form type 'multiRow' in the 'multiRow' form type.");
return {
type: "multiRow",
options
}
},
spacer: (themeOptions = {}) => {
return {
type: 'spacer',
themeOptions
}
},
emojiPicker: (disabled, themeOptions = {}) => {
return {
type: 'emojiPicker',
disabled,
themeOptions
}
},
slider: (min, max, step, disabled, themeOptions = {}) => {
return {
type: 'slider',
min,
max,
step,
disabled,
themeOptions
}
},
date: (disabled, themeOptions = {}) => {
return {
type: 'date',
disabled,
themeOptions
}
},
numberPicker: (min, max, disabled, themeOptions = {}) => {
return {
type: 'numberPicker',
min,
max,
disabled,
themeOptions
}
},
tagInput: (disabled, themeOptions = {}) => {
return {
type: 'tagInput',
disabled,
themeOptions
}
}
}
return {
type: "multiRow",
options,
};
},
spacer: (themeOptions = {}) => {
return {
type: "spacer",
themeOptions,
};
},
emojiPicker: (disabled, themeOptions = {}) => {
return {
type: "emojiPicker",
disabled,
themeOptions,
};
},
slider: (min, max, step, disabled, themeOptions = {}) => {
return {
type: "slider",
min,
max,
step,
disabled,
themeOptions,
};
},
date: (disabled, themeOptions = {}) => {
return {
type: "date",
disabled,
themeOptions,
};
},
numberPicker: (min, max, disabled, themeOptions = {}) => {
return {
type: "numberPicker",
min,
max,
disabled,
themeOptions,
};
},
tagInput: (disabled, themeOptions = {}) => {
return {
type: "tagInput",
disabled,
themeOptions,
};
},
};

View file

@ -1,47 +1,44 @@
module.exports = function (config, themeConfig) {
config.errorPage = function (req, res, error, type) {
if (type == 404) {
title = themeConfig?.error?.error404?.title || '404'
subtitle =
themeConfig?.error?.error404?.subtitle || 'Page not found'
description =
themeConfig?.error?.error404?.description ||
'The page you are looking for does not exist.'
}
config.errorPage = function (req, res, error, type) {
let title, subtitle, description = null;
title = themeConfig?.error?.dbdError?.title || type.toString()
subtitle = themeConfig?.error?.dbdError?.subtitle || 'An error occurred'
description =
themeConfig?.error?.dbdError?.description ||
'Please contact us if the issue persists or try again later.'
if (type == 404) {
title = themeConfig?.error?.error404?.title || "404";
subtitle = themeConfig?.error?.error404?.subtitle || "Page not found";
description = themeConfig?.error?.error404?.description || "The page you are looking for does not exist.";
}
if (error) {
console.error(error)
}
title = themeConfig?.error?.dbdError?.title || type.toString();
subtitle = themeConfig?.error?.dbdError?.subtitle || "An error occurred";
description =
themeConfig?.error?.dbdError?.description ||
"Please contact us if the issue persists or try again later.";
if (themeConfig?.error?.errorHandler)
themeConfig.error.errorHandler({
req,
res,
error: {
type,
path: error?.path || null,
error: error?.stack || `Page ${req.originalUrl} not found!`
},
user: req?.session?.user || null
})
if (error) console.error(error);
return res.render('error', {
strError: error?.stack?.split('\n'),
req,
bot: config.bot,
config,
type,
themeConfig,
title,
subtitle,
description,
error: error || undefined
})
}
}
if (themeConfig?.error?.errorHandler)
themeConfig.error.errorHandler({
req,
res,
error: {
type,
path: error?.path || null,
error: error?.stack || `Page ${req.originalUrl} not found!`,
},
user: req?.session?.user || null,
});
return res.render("error", {
strError: error?.stack?.split("\n"),
req,
bot: config.bot,
config,
type,
themeConfig,
title,
subtitle,
description,
error: error || undefined,
});
};
};

View file

@ -1,399 +1,266 @@
const Discord = require('discord.js')
const { Permissions } = require("discord.js");
module.exports = function (config, themeConfig) {
config.guildSettings = async function (req, res, home, category) {
if (!req.session.user) return res.redirect('/discord?r=/guild/' + req.params.id)
// eslint-disable-next-line no-unused-vars
config.guildSettings = async function (req, res, home, category) {
if (!req.session.user) return res.redirect("/discord?r=/guild/" + req.params.id);
let bot = config.bot
if (!bot.guilds.cache.get(req.params.id)) {
try {
await bot.guilds.fetch(req.params.id)
} catch (err) { }
}
const bot = config.bot;
if (!bot.guilds.cache.get(req.params.id)) {
try {
await bot.guilds.fetch(req.params.id);
} catch (e) { /* ... */ }
}
if (!bot.guilds.cache.get(req.params.id)) return res.redirect('/manage?error=noPermsToManageGuild')
if (
!bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id)
) {
try {
await bot.guilds.cache
.get(req.params.id)
.members.fetch(req.session.user.id)
} catch (err) { }
}
for (let PermissionRequired of req.requiredPermissions) {
let converted = PermissionRequired[0]
const DiscordJsVersion = Discord.version.split('.')[0]
if (DiscordJsVersion === '14') converted = await convert14(PermissionRequired[0])
if (!bot.guilds.cache.get(req.params.id)) return res.redirect("/manage?error=noPermsToManageGuild");
if (!bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id)) {
try {
await bot.guilds.cache.get(req.params.id).members.fetch(req.session.user.id);
} catch (e) { /* ... */ }
}
if (
!bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id)
.permissions.has(converted)
) {
return res.redirect('/manage?error=noPermsToManageGuild')
}
}
// for (const PermissionRequired of req.requiredPermissions) {
// const permissionsReq = Permissions.FLAGS[PermissionRequired[0]];
if (bot.guilds.cache.get(req.params.id).channels.cache.size < 1) {
try {
await bot.guilds.cache.get(req.params.id).channels.fetch()
} catch (err) { }
}
// if (!bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id).permissions.has(permissionsReq))
// return res.redirect("/manage?error=noPermsToManageGuild");
// }
if (bot.guilds.cache.get(req.params.id).roles.cache.size < 2) {
try {
await bot.guilds.cache.get(req.params.id).roles.fetch()
} catch (err) { }
}
if (bot.guilds.cache.get(req.params.id).channels.cache.size < 1) {
try {
await bot.guilds.cache.get(req.params.id).channels.fetch();
} catch (e) { /* ... */ }
}
let actual = {}
let toggle = {}
let premium = {}
if (bot.guilds.cache.get(req.params.id).roles.cache.size < 2) {
try {
await bot.guilds.cache.get(req.params.id).roles.fetch();
} catch (e) { /* ... */ }
}
let canUseList = {}
const actual = {};
const toggle = {};
const premium = {};
if (config.settings?.length) for (const category of config.settings) {
if (!canUseList[category.categoryId]) canUseList[category.categoryId] = {};
if (!actual[category.categoryId]) actual[category.categoryId] = {}
const canUseList = {};
if (config.useCategorySet) {
let catGAS = await category.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id),
},
user: {
id: req.session.user.id,
object: bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id),
},
});
if (config.settings?.length)
for (const category of config.settings) {
if (!canUseList[category.categoryId]) canUseList[category.categoryId] = {};
if (!actual[category.categoryId]) actual[category.categoryId] = {};
if (category.toggleable) {
if (!toggle[category.categoryId]) {
toggle[category.categoryId] = {}
}
toggle[category.categoryId] = catGAS.find(o => o.optionId === "categoryToggle") || null;
catGAS = catGAS.filter((c) => c.optionId !== 'categoryToggle')
}
if (category.premium) {
if (!premium[category.categoryId]) {
premium[category.categoryId] = {}
}
premium[category.categoryId] = await s.premiumUser({
guild: {
id: req.params.id
},
user: {
id: req.session.user.id,
tag: req.session.user.tag
}
})
}
if (config.useCategorySet) {
let catGAS = await category.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id),
},
user: {
id: req.session.user.id,
object: bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id),
},
});
if (category.premium && premium[category.categoryId] == false) return res.redirect(
`/settings/${req.params.id}?error=premiumRequired`
)
if (category.toggleable) {
if (!toggle[category.categoryId]) {
toggle[category.categoryId] = {};
}
toggle[category.categoryId] = catGAS.find(o => o.optionId === "categoryToggle") || null;
catGAS = catGAS.filter(c => c.optionId !== "categoryToggle");
}
if (category.premium) {
if (!premium[category.categoryId]) premium[category.categoryId] = {};
for (const o of catGAS) {
if (!o || !o?.optionId) {
console.log(
"WARNING: You haven't set the optionId for a category option in your config. This is required for the category option to work."
)
continue;
}
const option = category.categoryOptionsList.find(
(c) => c.optionId == o.optionId
)
if (option) {
if (option.allowedCheck) {
const canUse = await option.allowedCheck({
guild: {
id: req.params.id,
},
user: {
id: req.session.user.id,
},
})
premium[category.categoryId] = await category.premiumUser({
guild: {
id: req.params.id,
},
user: {
id: req.session.user.id,
tag: req.session.user.tag,
},
});
}
if (typeof canUse != "object")
throw new TypeError(
`${category.categoryId} category option with id ${option.optionId} allowedCheck function need to return {allowed: Boolean, errorMessage: String | null}`
)
canUseList[category.categoryId][
option.optionId
] = canUse
} else {
canUseList[category.categoryId][
option.optionId
] = {
allowed: true,
errorMessage: null,
}
}
if (category.premium && premium[category.categoryId] == false)
return res.redirect(`/settings/${req.params.id}?error=premiumRequired`);
if (option.optionType !== "spacer") {
if (!actual[category.categoryId]) {
actual[category.categoryId] = {}
}
if (
!actual[category.categoryId][
option.optionId
]
) {
actual[category.categoryId][
option.optionId
] = o.data
}
} else actual[category.categoryId][option.optionId] = {
type: 'spacer',
themeOptions: option.themeOptions
}
} else console.log(`WARNING: Option ${o.optionId} in category ${category.categoryId} doesn't exist in your config.`)
for (const o of catGAS) {
if (!o || !o?.optionId) {
console.log("WARNING: You haven't set the optionId for a category option in your config. This is required for the category option to work.");
continue;
}
}
} else for (const s of config.settings) {
if (!canUseList[s.categoryId]) canUseList[s.categoryId] = {}
if (s.toggleable) {
if (!toggle[s.categoryId]) {
toggle[s.categoryId] = {}
}
toggle[s.categoryId] = await s.getActualSet({
guild: {
id: req.params.id
}
})
}
if (s.premium) {
if (!premium[s.categoryId]) {
premium[s.categoryId] = {}
}
premium[s.categoryId] = await s.premiumUser({
guild: {
id: req.params.id
},
user: {
id: req.session.user.id,
tag: req.session.user.tag
}
})
}
const option = category.categoryOptionsList.find(c => c.optionId == o.optionId);
if (category) {
if (s.premium && premium[category] == false) {
return res.redirect(
`/settings/${req.params.id}?error=premiumRequired`
)
}
}
if (option) {
if (option.allowedCheck) {
const canUse = await option.allowedCheck({
guild: { id: req.params.id },
user: { id: req.session.user.id },
});
for (const c of s.categoryOptionsList) {
if (c.allowedCheck) {
const canUse = await c.allowedCheck({
guild: { id: req.params.id },
user: { id: req.session.user.id }
})
if (typeof canUse != 'object') {
throw new TypeError(
`${s.categoryId} category option with id ${c.optionId} allowedCheck function need to return {allowed: Boolean, errorMessage: String | null}`
)
}
canUseList[s.categoryId][c.optionId] = canUse
} else {
canUseList[s.categoryId][c.optionId] = {
allowed: true,
errorMessage: null
}
}
if (typeof canUse != "object") throw new TypeError(`${category.categoryId} category option with id ${option.optionId} allowedCheck function need to return {allowed: Boolean, errorMessage: String | null}`);
if (!actual[s.categoryId]) actual[s.categoryId] = {}
canUseList[category.categoryId][option.optionId] = canUse;
} else {
canUseList[category.categoryId][option.optionId] = {
allowed: true,
errorMessage: null,
};
}
if (c.optionType.type == 'spacer') {
actual[s.categoryId][c.optionId] = {
type: 'spacer',
themeOptions: c.themeOptions
}
} else if (
c.optionType.type == 'collapsable' ||
c.optionType.type == 'modal'
) {
for (const item of c.optionType.options) {
if (
item.optionType.type == 'channelsMultiSelect' ||
item.optionType.type == 'roleMultiSelect' ||
item.optionType.type == 'tagInput'
) {
actual[s.categoryId][item.optionId] = []
}
}
} else {
if (!actual[s.categoryId]) {
actual[s.categoryId] = {}
}
if (!actual[s.categoryId][c.optionId]) {
if (c.optionType.type === "multiRow") {
for (const item of c.optionType.options) {
actual[s.categoryId][item.optionId] = await item.getActualSet(
{
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id)
},
user: {
id: req.session.user.id,
object: bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id)
}
}
)
}
continue
}
actual[s.categoryId][c.optionId] = await c.getActualSet(
{
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id)
},
user: {
id: req.session.user.id,
object: bot.guilds.cache
.get(req.params.id)
.members.cache.get(req.session.user.id)
}
}
)
}
}
}
}
}
if (option.optionType !== "spacer") {
if (!actual[category.categoryId]) actual[category.categoryId] = {};
let errors
let success
// boo
if (req.session.errors) {
if (String(req.session.errors).includes('%is%')) {
errors = req.session.errors.split('%and%')
}
}
if (!actual[category.categoryId][option.optionId])
actual[category.categoryId][option.optionId] = o.data;
} else actual[category.categoryId][option.optionId] = {
type: "spacer",
themeOptions: option.themeOptions,
};
} else console.log(`WARNING: Option ${o.optionId} in category ${category.categoryId} doesn't exist in your config.`);
}
} else
for (const s of config.settings) {
if (!canUseList[s.categoryId]) canUseList[s.categoryId] = {};
if (req.session.success) {
if (typeof req.session.success == 'boolean') {
success = true
} else {
if (String(req.session.success).includes('%is%')) {
success = req.session.success.split('%and%')
}
}
}
if (s.toggleable) {
if (!toggle[s.categoryId]) toggle[s.categoryId] = {};
req.session.errors = null
req.session.success = null
toggle[s.categoryId] = await s.getActualSet({
guild: {
id: req.params.id,
},
});
}
if (s.premium) {
if (!premium[s.categoryId]) premium[s.categoryId] = {};
const guild = bot.guilds.cache.get(req.params.id)
let gIcon
premium[s.categoryId] = await s.premiumUser({
guild: {
id: req.params.id,
},
user: {
id: req.session.user.id,
tag: req.session.user.tag,
},
});
}
if (!guild.iconURL()) gIcon = themeConfig?.icons?.noGuildIcon
else gIcon = guild.iconURL()
if (category)
if (s.premium && premium[category] == false)
return res.redirect(`/settings/${req.params.id}?error=premiumRequired`);
res.render('settings', {
successes: success,
errors: errors,
settings: config.settings,
actual: actual,
toggle,
premium,
canUseList,
bot: config.bot,
guild,
userid: req.session.user.id,
gIcon,
req: req,
guildid: req.params.id,
themeConfig: req.themeConfig,
config
})
}
}
for (const c of s.categoryOptionsList) {
if (c.allowedCheck) {
const canUse = await c.allowedCheck({
guild: { id: req.params.id },
user: { id: req.session.user.id },
});
async function convert14(perm) {
var final = 'NULL'
if (typeof canUse != "object") throw new TypeError(`${s.categoryId} category option with id ${c.optionId} allowedCheck function need to return {allowed: Boolean, errorMessage: String | null}`);
switch (perm) {
case 'CREATE_INSTANT_INVITE':
final = 'CreateInstantInvite'
break
case 'KICK_MEMBERS':
final = 'KickMembers'
break
case 'BAN_MEMBERS':
final = 'BanMembers'
break
case 'ADMINISTRATOR':
final = 'Administrator'
break
case 'MANAGE_CHANNELS':
final = 'ManageChannels'
break
case 'MANAGE_GUILD':
final = 'ManageGuild'
break
case 'ADD_REACTIONS':
final = 'AddReactions'
break
case 'VIEW_AUDIT_LOG':
final = 'ViewAuditLog'
break
case 'PRIORITY_SPEAKER':
final = 'PrioritySpeaker'
break
case 'STREAM':
final = 'Stream'
break
case 'VIEW_CHANNEL':
final = 'ViewChannel'
break
case 'SEND_MESSAGES':
final = 'SendMessages'
break
case 'SEND_TTS_MESSAGES':
final = 'SendTTSMessages'
break
case 'MANAGE_MESSAGES':
final = 'ManageMessages'
break
case 'EMBED_LINKS':
final = 'ManageMessages'
break
case 'ATTACH_FILES':
final = 'AttachFiles'
break
case 'READ_MESSAGE_HISTORY':
final = 'ReadMessageHistory'
break
case 'MENTION_EVERYONE':
final = 'MentionEveryone'
break
case 'USE_EXTERNAL_EMOJIS':
final = 'UseExternalEmojis'
break
case 'VIEW_GUILD_INSIGHTS':
final = 'ViewGuildInsughts'
break
case 'CONNECT':
final = 'Connect'
break
case 'SPEAK':
final = 'Speak'
break
}
canUseList[s.categoryId][c.optionId] = canUse;
} else {
canUseList[s.categoryId][c.optionId] = {
allowed: true,
errorMessage: null,
};
}
return final
}
if (!actual[s.categoryId]) actual[s.categoryId] = {};
if (c.optionType.type == "spacer") {
actual[s.categoryId][c.optionId] = {
type: "spacer",
themeOptions: c.themeOptions,
};
} else if (c.optionType.type == "collapsable" || c.optionType.type == "modal") {
for (const item of c.optionType.options) {
if (item.optionType.type == "channelsMultiSelect" || item.optionType.type == "roleMultiSelect" || item.optionType.type == "tagInput")
actual[s.categoryId][item.optionId] = [];
}
} else {
if (!actual[s.categoryId]) actual[s.categoryId] = {};
if (!actual[s.categoryId][c.optionId]) {
if (c.optionType.type === "multiRow") {
for (const item of c.optionType.options) {
actual[s.categoryId][item.optionId] = await item.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id),
},
user: {
id: req.session.user.id,
object: bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id),
},
});
}
continue;
}
actual[s.categoryId][c.optionId] = await c.getActualSet({
guild: {
id: req.params.id,
object: bot.guilds.cache.get(req.params.id),
},
user: {
id: req.session.user.id,
object: bot.guilds.cache.get(req.params.id).members.cache.get(req.session.user.id),
},
});
}
}
}
}
}
let errors;
let success;
if (req.session.errors) {
if (String(req.session.errors).includes("%is%")) {
errors = req.session.errors.split("%and%");
}
}
if (req.session.success) {
if (typeof req.session.success == "boolean")
success = true;
else {
if (String(req.session.success).includes("%is%")) {
success = req.session.success.split("%and%");
}
}
}
req.session.errors = null;
req.session.success = null;
const guild = bot.guilds.cache.get(req.params.id);
let gIcon;
if (!guild.iconURL()) gIcon = themeConfig?.icons?.noGuildIcon;
else gIcon = guild.iconURL();
res.render("settings", {
successes: success,
errors: errors,
settings: config.settings,
actual: actual,
toggle,
premium,
canUseList,
bot: config.bot,
guild,
userid: req.session.user.id,
gIcon,
req: req,
guildid: req.params.id,
themeConfig: req.themeConfig,
config,
});
};
};

View file

@ -1,89 +1,66 @@
const fs = require('fs')
const colors = require('colors')
const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} `
const Nodeactyl = require('nodeactyl')
const fs = require("fs");
const colors = require("colors");
const consolePrefix = `${"[".blue}${"dbd-soft-ui".yellow}${"]".blue} `;
const Nodeactyl = require("nodeactyl");
module.exports = {
init: async function (config, themeConfig, app, db) {
let info;
if (themeConfig?.customThemeOptions?.info) info = await themeConfig.customThemeOptions.info({ config: config });
if(themeConfig?.admin?.pterodactyl?.enabled) {
themeConfig.nodeactyl = new Nodeactyl.NodeactylClient(
themeConfig.admin?.pterodactyl?.panelLink,
themeConfig.admin?.pterodactyl?.apiKey
)
init: async function (config, themeConfig, app, db) {
let info;
if (themeConfig?.customThemeOptions?.info) info = await themeConfig.customThemeOptions.info({ config: config });
try {
await themeConfig.nodeactyl.getAccountDetails();
} catch (error) {
console.log(`${consolePrefix}${('Failed to connect to Pterodactyl panel!\nEnsure you\'ve used a CLIENT api key, (found at ' + themeConfig.admin.pterodactyl.panelLink + '/account/api)').red}`);
}
}
const eventFolders = fs.readdirSync(`${__dirname}/../pages`)
if (themeConfig?.admin?.pterodactyl?.enabled) {
themeConfig.nodeactyl = new Nodeactyl.NodeactylClient(themeConfig.admin?.pterodactyl?.panelLink, themeConfig.admin?.pterodactyl?.apiKey);
for (const folder of eventFolders) {
const eventFiles = fs
.readdirSync(`${__dirname}/../pages/${folder}`)
.filter((file) => file.endsWith('.js'));
for (const file of eventFiles) {
const e = require(`${__dirname}/../pages/${folder}/${file}`);
try {
if (folder === 'admin') {
await app.get(e.page, async function (req, res) {
if (!req.session.user) return res.sendStatus(401)
if (!config.ownerIDs?.includes(req.session.user.id)) return res.sendStatus(403);
e.execute(
req,
res,
app,
config,
themeConfig,
info,
db
)
})
} else if (folder === 'post') {
await app.post(e.page, function (req, res) {
e.execute(
req,
res,
app,
config,
themeConfig,
info,
db
)
})
} else if (folder === 'get') {
await app.use(e.page, async function (req, res) {
e.execute(
req,
res,
app,
config,
themeConfig,
info,
db
)
})
}
} catch (error) {
console.log(`${consolePrefix}${'Failed to load:'.cyan} ${colors.red(e.page)}`);
console.log(`Page handler ${file}: ${error}`);
}
}
}
try {
await themeConfig.nodeactyl.getAccountDetails();
} catch (error) {
console.log(`${consolePrefix}${("Failed to connect to Pterodactyl panel!\nEnsure you've used a CLIENT api key, (found at " + themeConfig.admin.pterodactyl.panelLink + "/account/api)").red}`);
}
}
app.use('*', async function (req, res) {
res.status(404)
config.errorPage(req, res, undefined, 404)
})
const eventFolders = fs.readdirSync(`${__dirname}/../pages`);
app.use((err, req, res, next) => {
res.status(500)
config.errorPage(req, res, err, 500)
})
for (const folder of eventFolders) {
const eventFiles = fs.readdirSync(`${__dirname}/../pages/${folder}`).filter((file) => file.endsWith(".js"));
console.log(`${consolePrefix}${'Initialised all pages!'.cyan}`);
}
}
for (const file of eventFiles) {
const e = require(`${__dirname}/../pages/${folder}/${file}`);
try {
if (folder === "admin") {
await app.get(e.page, async function (req, res) {
if (!req.session.user) return res.sendStatus(401);
if (!config.ownerIDs?.includes(req.session.user.id)) return res.sendStatus(403);
e.execute(req, res, app, config, themeConfig, info, db);
});
} else if (folder === "post") {
await app.post(e.page, function (req, res) {
e.execute(req, res, app, config, themeConfig, info, db);
});
} else if (folder === "get") {
await app.use(e.page, async function (req, res) {
e.execute(req, res, app, config, themeConfig, info, db);
});
}
} catch (error) {
console.log(`${consolePrefix}${"Failed to load:".cyan} ${colors.red(e.page)}`);
console.log(`Page handler ${file}: ${error}`);
}
}
}
app.use("*", async function (req, res) {
res.status(404);
config.errorPage(req, res, undefined, 404);
});
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
res.status(500);
config.errorPage(req, res, err, 500);
});
console.log(`${consolePrefix}${"Initialised all pages!".cyan}`);
},
};

View file

@ -1,80 +0,0 @@
const fetch = require('node-fetch')
const fs = require('fs')
const consolePrefix = `\x1b[34m[\x1b[33mdbd-soft-ui\x1b[34m]\x1b[36m `
const colors = require('colors')
async function update() {
let failed3 = 0
let failed4 = 0
try {
await fetch(`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/utils/updater/versionsOnline.json`);
} catch (error) {
failed3++
console.log(`${consolePrefix}Failed to check live for updates.`)
}
if (failed3 === 0) {
let checkArray = await fetch(`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/utils/updater/versionsOnline.json`);
try {
checkArray = await checkArray.json()
} catch (error) {
failed4++
console.log(`${consolePrefix}Failed to check live for updates.`)
}
if (failed4 === 0) {
let latestVersions = [];
let currentVersions = fs.readFileSync(__dirname + '/versions.json');
currentVersions = JSON.parse(currentVersions);
let needsUpdating = [];
for (const latestFile of checkArray) {
if (latestFile.version > currentVersions[latestFile.name]) {
needsUpdating.push({
name: latestFile.name,
type: latestFile.type
})
const { name, type } = latestFile
if (type === 'partial') {
let failedFile = 0
let fileRaw = await fetch(`https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/partials/${name}.ejs`);
try {
fileRaw = await fileRaw.text()
} catch (error) {
failedFile++
console.log(
`${consolePrefix}Failed to update ${colors.red(
name
)}.`
)
}
if (failedFile === 0) {
await fs.writeFileSync(
`${__dirname}/../../views/partials/${name}.ejs`,
fileRaw
)
currentVersions[name] = latestFile.version
await fs.writeFileSync(
`${__dirname}/versions.json`,
JSON.stringify(currentVersions)
)
console.log(
`${consolePrefix}Successfully updated ${colors.green(
name
)}`
)
}
}
}
}
}
}
}
exports.update = async () => {
await update()
}

View file

@ -1,3 +0,0 @@
exports.update = () => {
return;
}

View file

@ -1,17 +0,0 @@
{
"colorscheme": "1.0.64",
"feeds": "1.0.62",
"footer": "1.0.1",
"graph": "1.0.2",
"iconsList": "1.0.0",
"meta": "0.0.0",
"navbar": "1.0.11",
"popup": "1.1.5",
"preload": "0.0.0",
"preloader": "1.1.14",
"premium": "1.0.0",
"scripts": "0.0.0",
"secret": "1.0.0",
"sidebar": "0.0.0",
"theme": "1.1.0"
}

View file

@ -1,57 +0,0 @@
[
{
"name": "colorscheme",
"version": "1.0.64",
"type": "partial"
},
{
"name": "footer",
"version": "1.0.1",
"type": "partial"
},
{
"name": "graph",
"version": "1.0.2",
"type": "partial"
},
{
"name": "iconsList",
"version": "1.0.0",
"type": "partial"
},
{
"name": "navbar",
"version": "1.0.11",
"type": "partial"
},
{
"name": "popup",
"version": "1.1.5",
"type": "partial"
},
{
"name": "preloader",
"version": "1.1.14",
"type": "partial"
},
{
"name": "premium",
"version": "1.0.0",
"type": "partial"
},
{
"name": "secret",
"version": "1.0.0",
"type": "partial"
},
{
"name": "theme",
"version": "1.1.0",
"type": "partial"
},
{
"name": "preload",
"version": "0.0.0",
"type": "partial"
}
]

File diff suppressed because one or more lines are too long

View file

@ -1,167 +1,155 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now: 'commands'}) %>
<script>
// docuemnt on read
document.addEventListener('DOMContentLoaded', function() {
$('.glow').removeClass('active');
$('.active_all').addClass('active');
});
$(function () {
$('#all').click(function () {
$('.item').slideDown("slow");
$('.glow').removeClass('active');
$('.active_all').addClass('active');
return false;
});
<% themeConfig.commands?.forEach(category => { %>
$('#<%= category.categoryId %>').click(function () {
$('.item').not('.<%= category.categoryId %>').slideUp(300);
$('.<%= category.categoryId %>').slideDown("slow");
$('.glow').removeClass('active');
$('.active_<%= category.categoryId %>').addClass('active');
return false;
});
<% }) %>
});
</script>
<%- themeConfig?.customHtml %>
<%- include("partials/preloader.ejs", {now: "commands"}) %>
<script>
// document on read
document.addEventListener("DOMContentLoaded", function() {
$(".glow").removeClass("active");
$(".active_all").addClass("active");
});
$(function () {
$("#all").click(function () {
$(".item").slideDown("slow");
$(".glow").removeClass("active");
$(".active_all").addClass("active");
return false;
});
<% themeConfig.commands?.forEach(category => { %>
$("#<%= category.categoryId %>").click(function () {
$(".item").not(".<%= category.categoryId %>").slideUp(300);
$(".<%= category.categoryId %>").slideDown("slow");
$(".glow").removeClass("active");
$(".active_<%= category.categoryId %>").addClass("active");
return false;
});
<% }) %>
});
</script>
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'commands'}) %>
<%- include("partials/preload.ejs") %>
<%- include("partials/sidebar.ejs", {config: config, now:"commands"}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'commands'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="row">
<div class="container-fluid">
<% themeConfig.commands?.forEach(category => { %>
<section id="<%= category.categoryId %>">
<div class="col-12 item <%= category.categoryId %>" id="divtable">
<div class="card mb-4 command-card">
<div class="card-header pb-0">
<h4><%= category.category %></h4>
<a><%= category.subTitle %></a>
</div>
<div class="card-body px-0 pt-0 pb-2">
<div class="table-responsive p-0">
<table class="table align-items-center mb-0" name="commandsTable" id="table">
<thead>
<tr>
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">
Name
</th>
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7 ps-2">
Command Usage
</th>
<% if(!category.hideDescription) { %>
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">
Description
</th>
<% } %>
<% if(!category.hideAlias) { %>
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">
Aliases
</th>
<% } %>
<th class="text-secondary opacity-7"></th>
</tr>
</thead>
<tbody>
<% category.list.forEach((item)=>{ %>
<tr>
<td>
<div class="d-flex px-2 py-1">
<div>
<% if(category.image){ %>
<%- category.image %>
<% } %>
</div>
<div class="d-flex flex-column justify-content-center">
<h6 class="mb-0 text-sm"><%= item.commandName %></h6>
</div>
</div>
</td>
<td>
<p class="text-xs font-weight-bold mb-0"><%= item.commandUsage %></p>
</td>
<% if(!category.hideDescription) { %>
<td class="align-middle text-center text-sm">
<p class="text-xs font-weight-bold mb-0"><%= item.commandDescription %></p>
</td>
<% } %>
<% if(!category.hideAlias) { %>
<td class="align-middle text-center">
<span class="text-secondary text-xs font-weight-bold"><%= item.commandAlias %></span>
</td>
<% } %>
<td class="align-middle">
<a class="text-secondary font-weight-bold text-xs"
data-toggle="tooltip"
data-original-title="Edit user">
<!-- Navbar -->
<%- include("partials/navbar.ejs", {now:"commands"}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="row">
<div class="container-fluid">
<% themeConfig.commands?.forEach(category => { %>
<% if (!category.hideSidebarItem) { %>
<section id="<%= category.categoryId %>">
<div class="col-12 item <%= category.categoryId %>" id="divtable">
<div class="card mb-4 command-card">
<div class="card-header pb-0">
<h4><%= category.category %></h4>
<a><%= category.subTitle %></a>
</div>
<div class="card-body px-0 pt-0 pb-2">
<div class="table-responsive p-0">
<table class="table align-items-center mb-0" name="commandsTable" id="table">
<thead>
<tr>
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">
Name
</th>
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7 ps-2">
Command Usage
</th>
<% if(!category.hideDescription) { %>
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">
Description
</th>
<% } %>
<% if(!category.hideAlias) { %>
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">
Aliases
</th>
<% } %>
<th class="text-secondary opacity-7"></th>
</tr>
</thead>
<tbody>
<% category.list.forEach((item)=>{ %>
<tr>
<td>
<div class="d-flex px-2 py-1">
<div>
<% if(category.image){ %>
<%- category.image %>
<% } %>
</div>
<div class="d-flex flex-column justify-content-center">
<h6 class="mb-0 text-sm"><%= item.commandName %></h6>
</div>
</div>
</td>
<td>
<p class="text-xs font-weight-bold mb-0"><%= item.commandUsage %></p>
</td>
<% if(!category.hideDescription) { %>
<td class="align-middle text-center text-sm">
<p class="text-xs font-weight-bold mb-0"><%= item.commandDescription %></p>
</td>
<% } %>
<% if(!category.hideAlias) { %>
<td class="align-middle text-center">
<span class="text-secondary text-xs font-weight-bold"><%= item.commandAlias %></span>
</td>
<% } %>
<td class="align-middle">
<a class="text-secondary font-weight-bold text-xs"
data-toggle="tooltip"
data-original-title="Edit user">
</a>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
<% }) %>
</div>
</div>
</main>
<%- include('partials/footer.ejs') %>
<script>
$('#searchBar').on('change keyup paste enter', function () {
var input = $(this).val().toLowerCase();
const divs = $(".command-card").toArray()
</a>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
<% } %>
<% }) %>
</div>
</div>
</main>
<%- include("partials/footer.ejs") %>
<script>
$("#searchBar").on("change keyup paste enter", function () {
const input = $(this).val().toLowerCase();
const divs = $(".command-card").toArray()
if (!input || input.length <= 0) {
$('.item').show();
$(divs).show();
}
if (!input || input.length <= 0) {
$(".item").show();
$(divs).show();
}
$('tr').show()
$('tr:not(:contains(' + input + '))').hide()
$("tr").show()
$("tr:not(:contains(" + input + "))").hide()
for (const item of divs) {
try {
const tbody = item.firstChild.nextElementSibling.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.nextElementSibling
for (const item of divs) {
try {
const tbody = item.firstChild.nextElementSibling.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.nextElementSibling
if ($(tbody).children(':visible').length == 0) $(item).hide()
if ($(tbody).children(":visible").length == 0) $(item).hide()
} catch (error) {
console.log(error)
}
}
});
</script>
<%- include('partials/scripts.ejs', {now: "commands"}) %>
} catch (error) {
console.log(error)
}
}
});
</script>
<%- include("partials/scripts.ejs", {now: "commands"}) %>
</body>
</html>

View file

@ -1,32 +1,32 @@
<style>
.select2-results__option.select2-results__option--selectable:before {
content: "# ";
}
.select2-results__option.select2-results__option--selectable:before {
content: "# ";
}
</style>
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select placeholder="Select" class="multiSelect form-control"
formType="channelMultiSelect"
id="<%= option.optionId %>"
defaultValue=""
<% if(option.optionType.disabled){ %>disabled
<% } %>
<% if(option.optionType.required){ %>required
<% } %>
style="width:100%;background: #f9f9ff;border-color: #f9f9ff;<% if(!Allowed.allowed){ %>border-color: red;<% } %>"
multiple="multiple"
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
formType="channelMultiSelect"
id="<%= option.optionId %>"
defaultValue=""
<% if(option.optionType.disabled){ %>disabled
<% } %>
<% if(option.optionType.required){ %>required
<% } %>
style="width:100%;background: #f9f9ff;border-color: #f9f9ff;<% if(!Allowed.allowed){ %>border-color: red;<% } %>"
multiple="multiple"
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
>
<% if (actual[s.categoryId][option.optionId]) {
let ioooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId].includes(value)){ %>selected
<% } %>
><%= functiona.keys[ioooooo] %></option>
<% ioooooo++; })} %>
<% if (actual[s.categoryId][option.optionId]) {
let ioooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId].includes(value)){ %>selected
<% } %>
><%= functiona.keys[ioooooo] %></option>
<% ioooooo++; })} %>
</select>
<br>

View file

@ -1,19 +1,19 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
formType="channelSelect"
defaultValue=""
class="form-select"
id="<%= option.optionId %>" class="col-md-12"
style="<% if(!Allowed.allowed){ %>border-color: red;<% } %> ">
<%
let ioooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId] == value){ %>selected
<% } %>
><%= functiona.keys[ioooooo] %></option>
<% ioooooo++; }); %>
<select
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
formType="channelSelect"
defaultValue=""
class="form-select"
id="<%= option.optionId %>" class="col-md-12"
style="<% if(!Allowed.allowed){ %>border-color: red;<% } %> ">
<%
let ioooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId] == value){ %>selected
<% } %>
><%= functiona.keys[ioooooo] %></option>
<% ioooooo++; }); %>
</select>

View file

@ -1,14 +1,14 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<label class="container">
<input type="checkbox" id="<%= option.optionId %>"
formType="checkbox"
id="<%= option.optionId %>"
formType="checkbox"
defaultValue=""
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
<% if(!Allowed.allowed){ %>style="border-color: red;"<% } %>
>
<span class="checkmark round"></span>
<input type="checkbox" id="<%= option.optionId %>"
formType="checkbox"
id="<%= option.optionId %>"
formType="checkbox"
defaultValue=""
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
<% if(!Allowed.allowed){ %>style="border-color: red;"<% } %>
>
<span class="checkmark round"></span>
</label>
<br>

View file

@ -1,9 +1,9 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<input type="color" id="<%= option.optionId %>"
id="<%= option.optionId %>"
formType="colorSelect"
class="form-control form-control-color"
value="<%= actual[s.categoryId][option.optionId] || option.optionType.data || "#ffffff" %>"
<% if(option.optionType.disabled){ %>disabled<% } %>
<% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %>
id="<%= option.optionId %>"
formType="colorSelect"
class="form-control form-control-color"
value="<%= actual[s.categoryId][option.optionId] || option.optionType.data || "#ffffff" %>"
<% if(option.optionType.disabled){ %>disabled<% } %>
<% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %>
>

View file

@ -1,26 +1,26 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<input
defaultValue=""
class="form-control"
type="date"
id="<%= option.optionId %>"
formType="date"
<% if(actual[s.categoryId][option.optionId]){ %>
value="<%= actual[s.categoryId][option.optionId] %>"
<% } else { %>
value="<%- new Date().toISOString().slice(0, 10) %>"
<% } %>
<% if(option?.themeOptions?.min) { %>
min="<%= option.themeOptions.min%>"
<% } %>
<% if(option?.themeOptions?.max) { %>
max="<%= option.themeOptions.max%>"
<% } %>
<% if(!Allowed.allowed){ %>
style="border-color: red;"
<% } %>
<% if (!Allowed.allowed || option.optionType.disabled) { %>
disabled
<% } %>
<input
defaultValue=""
class="form-control"
type="date"
id="<%= option.optionId %>"
formType="date"
<% if(actual[s.categoryId][option.optionId]){ %>
value="<%= actual[s.categoryId][option.optionId] %>"
<% } else { %>
value="<%- new Date().toISOString().slice(0, 10) %>"
<% } %>
<% if(option?.themeOptions?.min) { %>
min="<%= option.themeOptions.min%>"
<% } %>
<% if(option?.themeOptions?.max) { %>
max="<%= option.themeOptions.max%>"
<% } %>
<% if(!Allowed.allowed){ %>
style="border-color: red;"
<% } %>
<% if (!Allowed.allowed || option.optionType.disabled) { %>
disabled
<% } %>
>

View file

@ -1,106 +1,106 @@
<style>
.iframe-container {
position: relative;
overflow: hidden;
width: 100%;
padding-top: 56.25%; /* 16:9 Aspect Ratio (divide 9 by 16 = 0.5625) */
}
.iframe-container {
position: relative;
overflow: hidden;
width: 100%;
padding-top: 56.25%; /* 16:9 Aspect Ratio (divide 9 by 16 = 0.5625) */
}
@media (max-width: 570px) {
.iframe-container {
padding-top: 150%;
}
}
@media (max-width: 570px) {
.iframe-container {
padding-top: 150%;
}
}
@media (min-width: 570px) and (max-width: 760px) {
.iframe-container {
padding-top: 130%;
}
}
@media (min-width: 570px) and (max-width: 760px) {
.iframe-container {
padding-top: 130%;
}
}
@media (min-width: 760px) and (max-width: 980px) {
.iframe-container {
padding-top: 110%;
}
}
@media (min-width: 760px) and (max-width: 980px) {
.iframe-container {
padding-top: 110%;
}
}
@media (min-width: 980px) and (max-width: 1247px) {
.iframe-container {
padding-top: 95%;
}
}
@media (min-width: 980px) and (max-width: 1247px) {
.iframe-container {
padding-top: 95%;
}
}
.responsive-iframe {
border: none;
border-radius: 10px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
}
.responsive-iframe {
border: none;
border-radius: 10px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
}
</style>
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<textarea id="<%= option.optionId %>" name="<%= option.optionId %>" formType="embedBuilder"
style="visibility: hidden;width: .1px;height: .1px"><%- JSON.stringify(actual[s.categoryId][option.optionId]) || "" %></textarea>
style="visibility: hidden;width: .1px;height: .1px"><%- JSON.stringify(actual[s.categoryId][option.optionId]) || "" %></textarea>
<div class="iframe-container">
<%
let embedContent;
if (actual[s.categoryId][option.optionId] == null) {
if (option.optionType.data.defaultJson) {
embedContent = JSON.stringify(option.optionType.data.defaultJson, null, 3);
} else {
embedContent = `{
content: "Did you know that if you don't know something, you don't know it? This riddle was solved by me. Don't thank me.",
embed: {
timestamp: new Date().toISOString(),
url: "https://discord.com",
description: "There was a boar, everyone liked a boar. One day the boar ate my dinner and escaped through the chimney. I haven't seen a boar since then.",
author: {
name: "Assistants Center",
url: "https://assistants.ga",
icon_url: "https://media.discordapp.net/attachments/911644960590270484/934513385402413076/ac_fixed.png"
},
image: {
url: "https://unsplash.it/380/200"
},
footer: {
text: "Crated with Discord-Dashboard",
icon_url: "https://cdn.discordapp.com/emojis/870635912437047336.png"
},
fields: [
{
name: "Hello",
value: "Hi, Assistants Center loves you <:ac_love:806492057996230676>"
},
{
name: "Do you know that",
value: "You can use custom emojis there, even from server where bot isn't <:Kekwlaugh:722088222766923847>",
inline: false
},
]
}
}`;
}
} else {
if (typeof actual[s.categoryId][option.optionId] === "string") embedContent = actual[s.categoryId][option.optionId];
else embedContent = JSON.stringify(actual[s.categoryId][option.optionId], null, 3);
}
<%
let embedContent;
if (actual[s.categoryId][option.optionId] == null) {
if (option.optionType.data.defaultJson) {
embedContent = JSON.stringify(option.optionType.data.defaultJson, null, 3);
} else {
embedContent = `{
content: "Did you know that if you don't know something, you don't know it? This riddle was solved by me. Don't thank me.",
embed: {
timestamp: new Date().toISOString(),
url: "https://discord.com",
description: "There was a boar, everyone liked a boar. One day the boar ate my dinner and escaped through the chimney. I haven't seen a boar since then.",
author: {
name: "Assistants Center",
url: "https://assistants.ga",
icon_url: "https://media.discordapp.net/attachments/911644960590270484/934513385402413076/ac_fixed.png"
},
image: {
url: "https://unsplash.it/380/200"
},
footer: {
text: "Crated with Discord-Dashboard",
icon_url: "https://cdn.discordapp.com/emojis/870635912437047336.png"
},
fields: [
{
name: "Hello",
value: "Hi, Assistants Center loves you <:ac_love:806492057996230676>"
},
{
name: "Do you know that",
value: "You can use custom emojis there, even from server where bot isn't <:Kekwlaugh:722088222766923847>",
inline: false
},
]
}
}`;
}
} else {
if (typeof actual[s.categoryId][option.optionId] === "string") embedContent = actual[s.categoryId][option.optionId];
else embedContent = JSON.stringify(actual[s.categoryId][option.optionId], null, 3);
}
%>
<iframe class="responsive-iframe"
src="data:text/html;charset=utf-8,<%= encodeURIComponent(config.theme.embedBuilderComponent.replace('{{ContentJsonReplacer}}', embedContent).replace('{{msgSource}}', option.optionId).replace('{{botusername}}', option.optionType.data.username).replace('{{botavatar}}', option.optionType.data.avatarURL)) %>"></iframe>
%>
<iframe class="responsive-iframe"
src="data:text/html;charset=utf-8,<%= encodeURIComponent(config.theme.embedBuilderComponent.replace('{{ContentJsonReplacer}}', embedContent).replace('{{msgSource}}', option.optionId).replace('{{botusername}}', option.optionType.data.username).replace('{{botavatar}}', option.optionType.data.avatarURL)) %>"></iframe>
</div>
<script>
setTimeout(() => {
window.addEventListener('message', function (e) {
if (e.data[0] === '<%= option.optionId %>') {
document.getElementById('<%= option.optionId %>').innerHTML = JSON.stringify(e.data[1]);
optionEdited(document.getElementById('<%= option.optionId %>'))
}
}, false);
}, 1200);
setTimeout(() => {
window.addEventListener('message', function (e) {
if (e.data[0] === '<%= option.optionId %>') {
document.getElementById('<%= option.optionId %>').innerHTML = JSON.stringify(e.data[1]);
optionEdited(document.getElementById('<%= option.optionId %>'))
}
}, false);
}, 1200);
</script>

View file

@ -1,176 +1,176 @@
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
img {
display: block;
}
img {
display: block;
}
.emoji-picker {
background-color: #303841;
width: 400px;
border-radius: 5px;
height: 400px;
display: flex;
}
.emoji-picker {
background-color: #303841;
width: 400px;
border-radius: 5px;
height: 400px;
display: flex;
}
.emoji-selectables {
background-color: #212427;
width: 45px;
height: 100%;
padding: 10px 15px;
display: flex;
flex-direction: column;
align-items: center;
}
.emoji-selectables {
background-color: #212427;
width: 45px;
height: 100%;
padding: 10px 15px;
display: flex;
flex-direction: column;
align-items: center;
}
.emoji-selectables span {
margin-bottom: 7px;
cursor: pointer;
}
.emoji-selectables span {
margin-bottom: 7px;
cursor: pointer;
}
.emoji-selectables span.active img {
filter: none;
}
.emoji-selectables span.active img {
filter: none;
}
.emoji-selectables span img {
width: 25px;
display: block;
display: flex;
align-items: center;
filter: grayscale(100%)
}
.emoji-selectables span img {
width: 25px;
display: block;
display: flex;
align-items: center;
filter: grayscale(100%)
}
.emoji-content div {
width: 100%;
.emoji-content div {
width: 100%;
flex-wrap: wrap;
justify-content: center;
padding: 5px;
}
flex-wrap: wrap;
justify-content: center;
padding: 5px;
}
.emoji-content span {
display: block;
padding: 5px;
cursor: pointer;
}
.emoji-content span {
display: block;
padding: 5px;
cursor: pointer;
}
.emoji-content span:hover {
transform: scale(1.1);
background-color: #3f4953;
border-radius: 5px;
}
.emoji-content span:hover {
transform: scale(1.1);
background-color: #3f4953;
border-radius: 5px;
}
.picker-emoji-content {
display: none;
.picker-emoji-content {
display: none;
}
}
.picker-emoji-sel.face {
color: aliceblue;
font-size: 10px;
}
.picker-emoji-sel.face {
color: aliceblue;
font-size: 10px;
}
.picker-emoji-content.active {
display: flex;
display: flex;
height: 100%;
overflow-y: scroll;
}
.picker-emoji-content.active {
display: flex;
display: flex;
height: 100%;
overflow-y: scroll;
}
.emoji-content span img {
width: 32px;
height: 32px;
}
.emoji-content span img {
width: 32px;
height: 32px;
}
.picker-emoji-content::-webkit-scrollbar-thumb {
height: 10px;
background-color: #65B88D;
border-radius: 100px;
}
.picker-emoji-content::-webkit-scrollbar-thumb {
height: 10px;
background-color: #65B88D;
border-radius: 100px;
}
.picker-emoji-content::-webkit-scrollbar-track {
background-color: #303841;
}
.picker-emoji-content::-webkit-scrollbar-track {
background-color: #303841;
}
.picker-emoji-content::-webkit-scrollbar {
width: 6px;
}
.picker-emoji-content::-webkit-scrollbar {
width: 6px;
}
img {
display: block;
}
img {
display: block;
}
</style>
<link href="https://www.jqueryscript.net/css/jquerysctipttop.css" rel="stylesheet" type="text/css">
<% if(!Allowed.allowed){ %>
<span style="color: red;">
<%- Allowed.errorMessage %>
</span>
<br>
<span style="color: red;">
<%- Allowed.errorMessage %>
</span>
<br>
<% } %>
<input defaultValue="<%= actual[s.categoryId][option.optionId] || "" %>" class="d-none" type="text" id="<%= option.optionId %>" formType="emojiPicker" type="text" onchange="optionEdited(this)">
<div class="dropdown">
<a href="javascript:;" class="btn bg-transparent" data-bs-toggle="dropdown" id="navbarDropdownMenuLink2" style="width: fit-content; height: fit-content; aspect-ratio: 1/1; justify-content: center; display: flex; align-items: center; max-width: 100px; <% if (option.optionType.disabled && !Allowed.allowed) { %>border-color: red;<% } %>">
<% if(actual[s.categoryId][option.optionId]){ %>
<% if (/\d/.test(actual[s.categoryId][option.optionId])) { %>
<img src="https://cdn.discordapp.com/emojis/<%= actual[s.categoryId][option.optionId] %>.png" style="width: 72px; height: 72px;">
<% } else { %>
<span style="font-size: 20px;"><%= actual[s.categoryId][option.optionId] %></span>
<% } %>
<% } %>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink2">
<div id="emojis">
</div>
</div>
<a href="javascript:;" class="btn bg-transparent" data-bs-toggle="dropdown" id="navbarDropdownMenuLink2" style="width: fit-content; height: fit-content; aspect-ratio: 1/1; justify-content: center; display: flex; align-items: center; max-width: 100px; <% if (option.optionType.disabled && !Allowed.allowed) { %>border-color: red;<% } %>">
<% if(actual[s.categoryId][option.optionId]){ %>
<% if (/\d/.test(actual[s.categoryId][option.optionId])) { %>
<img src="https://cdn.discordapp.com/emojis/<%= actual[s.categoryId][option.optionId] %>.png" style="width: 72px; height: 72px;">
<% } else { %>
<span style="font-size: 20px;"><%= actual[s.categoryId][option.optionId] %></span>
<% } %>
<% } %>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink2">
<div id="emojis">
</div>
</div>
</div>
<script src="/js/core/DisMojiPicker.js"></script>
<script src="https://twemoji.maxcdn.com/v/latest/twemoji.min.js" crossorigin="anonymous"></script>
<% if(!option.optionType.disabled && Allowed.allowed){ %>
<script>
const emojis = <%- JSON.stringify(bot.guilds.cache.get(req.params.id).emojis.cache.map(e => {
return {
animated: e.animated,
name: e.name,
id: e.id
}
})) %>
$(".dropdown").click(function(e){
e.stopPropagation();
})
$("#emojis").disMojiPicker(emojis)
$("#emojis").picker(emoji => {
let custom = {}
if (emoji)
$("#navbarDropdownMenuLink2").dropdown("toggle")
<script>
const emojis = <%- JSON.stringify(bot.guilds.cache.get(req.params.id).emojis.cache.map(e => {
return {
animated: e.animated,
name: e.name,
id: e.id
}
})) %>
$(".dropdown").click(function(e){
e.stopPropagation();
})
$("#emojis").disMojiPicker(emojis)
$("#emojis").picker(emoji => {
let custom = {}
if (emojis.find(x => x.name === emoji)) {
custom = emojis.find(x => x.name === emoji)
}
if (emoji)
$("#navbarDropdownMenuLink2").dropdown("toggle")
$("#<%= option.optionId %>").val(custom ? custom.id : emoji)
$("#<%= option.optionId %>").trigger("change")
if (custom?.id)
return $("#navbarDropdownMenuLink2").html(
`<img src="https://cdn.discordapp.com/emojis/${custom.id}.${custom.animated ? "gif" : "png"}" alt="${custom.name}" style="width: 72px; height: 72px;"/>`
)
else $("#navbarDropdownMenuLink2").html(`
<span style="width: 72px; height: 72px;">
${twemoji.parse(emoji)}
</span>
`)
});
twemoji.parse(document.body, "<%= bot.guilds.cache.get(req.params.id).emojis.cache.map(e => e.id) %>");
</script>
if (emojis.find(x => x.name === emoji)) {
custom = emojis.find(x => x.name === emoji)
}
$("#<%= option.optionId %>").val(custom ? custom.id : emoji)
$("#<%= option.optionId %>").trigger("change")
if (custom?.id)
return $("#navbarDropdownMenuLink2").html(
`<img src="https://cdn.discordapp.com/emojis/${custom.id}.${custom.animated ? "gif" : "png"}" alt="${custom.name}" style="width: 72px; height: 72px;"/>`
)
else $("#navbarDropdownMenuLink2").html(`
<span style="width: 72px; height: 72px;">
${twemoji.parse(emoji)}
</span>
`)
});
twemoji.parse(document.body, "<%= bot.guilds.cache.get(req.params.id).emojis.cache.map(e => e.id) %>");
</script>
<% } %>

View file

@ -1,33 +1,33 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<input <% if(!Allowed.allowed){ %>style="border-color: red;" disabled
<% } %>
type="text" id="<%= option.optionId %>" class="col-md-12 form-control"
id="<%= option.optionId %>"
formType="input"
defaultValue="<% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% } %>"
<% if(option.optionType.required){ %>required
<% } %>
<% if(option.optionType.disabled){ %>disabled
<% } %>
placeholder="<%= option.optionType.data %>"
<% if(actual[s.categoryId][option.optionId]){ %>value="<%= actual[s.categoryId][option.optionId] %>"
<% } %>
<% if(option.optionType.min){ %>minlength="<%= option.optionType.min %>"
<% } %>
<% if(option.optionType.max){ %>maxlength="<%= option.optionType.max %>"
<% } %>
<% } %>
type="text" id="<%= option.optionId %>" class="col-md-12 form-control"
id="<%= option.optionId %>"
formType="input"
defaultValue="<% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% } %>"
<% if(option.optionType.required){ %>required
<% } %>
<% if(option.optionType.disabled){ %>disabled
<% } %>
placeholder="<%= option.optionType.data %>"
<% if(actual[s.categoryId][option.optionId]){ %>value="<%= actual[s.categoryId][option.optionId] %>"
<% } %>
<% if(option.optionType.min){ %>minlength="<%= option.optionType.min %>"
<% } %>
<% if(option.optionType.max){ %>maxlength="<%= option.optionType.max %>"
<% } %>
/>
<% if (option?.themeOptions?.optionPlaceholder) { %>
<div style="margin: 0px -5px;">
<% option?.themeOptions?.optionPlaceholder?.values.forEach(array => { %>
<span style="<% if(option.themeOptions.optionPlaceholder.clickable && Allowed.allowed){ %>cursor: pointer;<% } %> color: #9db4cc;"
class="_87eb"
<% if(option.themeOptions.optionPlaceholder.clickable && Allowed.allowed){ %>
onclick="$('#<%= option.optionId %>').val(this.innerHTML);"
<% } %>
><%- array %></span>
<% }) %>
</div>
<div style="margin: 0px -5px;">
<% option?.themeOptions?.optionPlaceholder?.values.forEach(array => { %>
<span style="<% if(option.themeOptions.optionPlaceholder.clickable && Allowed.allowed){ %>cursor: pointer;<% } %> color: #9db4cc;"
class="_87eb"
<% if(option.themeOptions.optionPlaceholder.clickable && Allowed.allowed){ %>
onclick="$('#<%= option.optionId %>').val(this.innerHTML);"
<% } %>
><%- array %></span>
<% }) %>
</div>
<% } %>

View file

@ -1,10 +1,9 @@
<div class="formTypes">
<% option.optionType.options.forEach(opt => { %>
<div class="formtype-item mt-3">
<h4 class="m-0"><%- opt?.optionName || ""%></h4>
<p><%- opt?.optionDescription || ""%></p>
<%- include(`./${opt.optionType.type}.ejs`, {option: opt, s, Allowed}) %>
</div>
<% }) %>
<% option.optionType.options.forEach(opt => { %>
<div class="formtype-item mt-3">
<h4 class="m-0"><%- opt?.optionName || ""%></h4>
<p><%- opt?.optionDescription || ""%></p>
<%- include(`./${opt.optionType.type}.ejs`, {option: opt, s, Allowed}) %>
</div>
<% }) %>
</div>

View file

@ -1,29 +1,29 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select placeholder="Select" class="multiSelect js-example-basic-multiple"
<% if(option.optionType.disabled){ %>disabled
<% } %>
<% if(option.optionType.required){ %>required
<% } %>
id="<%= option.optionId %>"
defaultValue=""
formType="multiSelect"
style="width:100%;background: #f9f9ff;border-color: #f9f9ff;"
class="col-md-12" multiple="multiple"
<% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %>
<% if(option.optionType.disabled){ %>disabled
<% } %>
<% if(option.optionType.required){ %>required
<% } %>
id="<%= option.optionId %>"
defaultValue=""
formType="multiSelect"
style="width:100%;background: #f9f9ff;border-color: #f9f9ff;"
class="col-md-12" multiple="multiple"
<% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %>
>
<%
let ioo = 0;
option.optionType.data.values.forEach(value => {
%>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId].includes(value)) { %>
selected
<% }
%>
> <%= option.optionType.data.keys[ioo] %> </option>
<%
ioo++;
})
%>
<%
let ioo = 0;
option.optionType.data.values.forEach(value => {
%>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId].includes(value)) { %>
selected
<% }
%>
> <%= option.optionType.data.keys[ioo] %> </option>
<%
ioo++;
})
%>
</select>

View file

@ -1,27 +1,27 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<input
<% if(actual[s.categoryId][option.optionId]){ %>
defaultValue="<%= actual[s.categoryId][option.optionId] %>"
value="<%= actual[s.categoryId][option.optionId] %>"
<% } %>
class="form-control"
type="number"
id="<%= option.optionId %>"
formType="numberPicker"
<% if (option.optionType.min) { %>
min="<%= option.optionType.min %>"
onkeyup="if(this.value < <%= option.optionType.min %>) this.value = <%= option.optionType.min %>"
<% } %>
<% if (option.optionType.max) { %>
max="<%= option.optionType.max %>"
onkeyup="if(this.value > <%= option.optionType.max %>) this.value = <%= option.optionType.max %>"
<% } %>
<% if(!Allowed.allowed ){ %>
style="border-color: red !important"
disabled
<% } %>
<% if (Allowed.allowed && option.optionType.disabled) { %>
disabled
<% } %>
<input
<% if(actual[s.categoryId][option.optionId]){ %>
defaultValue="<%= actual[s.categoryId][option.optionId] %>"
value="<%= actual[s.categoryId][option.optionId] %>"
<% } %>
class="form-control"
type="number"
id="<%= option.optionId %>"
formType="numberPicker"
<% if (option.optionType.min) { %>
min="<%= option.optionType.min %>"
onkeyup="if(this.value < <%= option.optionType.min %>) this.value = <%= option.optionType.min %>"
<% } %>
<% if (option.optionType.max) { %>
max="<%= option.optionType.max %>"
onkeyup="if(this.value > <%= option.optionType.max %>) this.value = <%= option.optionType.max %>"
<% } %>
<% if(!Allowed.allowed ){ %>
style="border-color: red !important"
disabled
<% } %>
<% if (Allowed.allowed && option.optionType.disabled) { %>
disabled
<% } %>
>

View file

@ -1,26 +1,26 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select placeholder="Select" class="multiSelect form-control"
formType="rolesMultiSelect"
id="<%= option.optionId %>"
defaultValue=""
<% if(option.optionType.disabled){ %>disabled
<% } %>
<% if(option.optionType.required){ %>required
<% } %>
style="width:100%;background: #f9f9ff;border-color: #f9f9ff;<% if(!Allowed.allowed){ %>border-color: red;<% } %>"
multiple="multiple"
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
formType="rolesMultiSelect"
id="<%= option.optionId %>"
defaultValue=""
<% if(option.optionType.disabled){ %>disabled
<% } %>
<% if(option.optionType.required){ %>required
<% } %>
style="width:100%;background: #f9f9ff;border-color: #f9f9ff;<% if(!Allowed.allowed){ %>border-color: red;<% } %>"
multiple="multiple"
<% if(!Allowed.allowed || option.optionType.disabled){ %>disabled<% } %>
>
<% if (actual[s.categoryId][option.optionId]) {
let ioooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId].includes(value)){ %>selected
<% } %>
><%= functiona.keys[ioooooo] %></option>
<% ioooooo++; })} %>
<% if (actual[s.categoryId][option.optionId]) {
let ioooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId].includes(value)){ %>selected
<% } %>
><%= functiona.keys[ioooooo] %></option>
<% ioooooo++; })} %>
</select>
<br>

View file

@ -1,21 +1,21 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select class="form-control"
<% if(option.optionType.disabled){ %>disabled
<% } %>
id="<%= option.optionId %>" class="col-md-12"
formType="rolesSelect"
defaultValue=""
<% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %>
<% if(option.optionType.disabled){ %>disabled
<% } %>
id="<%= option.optionId %>" class="col-md-12"
formType="rolesSelect"
defaultValue=""
<% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %>
>
<%
let iooooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId] == value){ %>selected
<% } %>
><%= functiona.keys[iooooooo] %></option>
<%
iooooooo++;
}) %>
<%
let iooooooo = 0;
let functiona = option.optionType.function(bot, guildid, userid);
functiona.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId] == value){ %>selected
<% } %>
><%= functiona.keys[iooooooo] %></option>
<%
iooooooo++;
}) %>
</select>

View file

@ -1,22 +1,22 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select class="form-control"
<% if(!Allowed.allowed){ %>style="border-color: red;"
<% } %>
formType="select"
id="<%= option.optionId %>"
<% if(!Allowed.allowed){ %>style="border-color: red;"
<% } %>
formType="select"
id="<%= option.optionId %>"
<% if(!Allowed.allowed || option.optionType.disabled){ %>
disabled
<% } %>
name="<%= option.optionId %>">
<%
let ioo = 0;
option.optionType.data.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId] == value){ %>selected
<% } %>
><%= option.optionType.data.keys[ioo] %>
</option>
<%
ioo++;
}) %>
disabled
<% } %>
name="<%= option.optionId %>">
<%
let ioo = 0;
option.optionType.data.values.forEach(value=>{ %>
<option value="<%= value %>"
<% if(actual[s.categoryId][option.optionId] == value){ %>selected
<% } %>
><%= option.optionType.data.keys[ioo] %>
</option>
<%
ioo++;
}) %>
</select>

View file

@ -1,99 +1,99 @@
<style>
.form-control.slider {
padding: 0 .75rem;
padding: 0 .75rem;
}
datalist.slider {
margin: 0 !important;
margin: 0 !important;
}
option.slider.text-sm {
font-weight: bold;
font-weight: bold;
}
option.slider:nth-last-child(1) {
margin-right: 5px;
margin-right: 5px;
}
.form-control.slider::after {
background: none !important;
background: none !important;
}
.form-control.slider::before {
background: none !important;
background: none !important;
}
.form-control:focus {
box-shadow: none !important;
border: none !important;
box-shadow: none !important;
border: none !important;
}
.form-control.slider.slider {
-webkit-appearance: none;
padding: 0 !important;
margin-top: 10px;
width: 97.8%;
height: 15px;
border-radius: 5px;
background-image: linear-gradient(var(--gradient));
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
-webkit-appearance: none;
padding: 0 !important;
margin-top: 10px;
width: 97.8%;
height: 15px;
border-radius: 5px;
background-image: linear-gradient(var(--gradient));
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.form-control.slider.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
margin-bottom: 8px;
width: 25px;
height: 25px;
border-radius: 50%;
background-image: linear-gradient(310deg, rgb(16, 18, 31) 0%, rgb(46, 52, 89) 100%);
-webkit-appearance: none;
appearance: none;
margin-bottom: 8px;
width: 25px;
height: 25px;
border-radius: 50%;
background-image: linear-gradient(310deg, rgb(16, 18, 31) 0%, rgb(46, 52, 89) 100%);
cursor: pointer;
cursor: pointer;
}
.form-control.slider.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background-image: linear-gradient(310deg, rgb(16, 18, 31) 0%, rgb(46, 52, 89) 100%);
cursor: pointer;
width: 25px;
height: 25px;
border-radius: 50%;
background-image: linear-gradient(310deg, rgb(16, 18, 31) 0%, rgb(46, 52, 89) 100%);
cursor: pointer;
}
</style>
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<% if(option?.themeOptions?.dataList) { %>
<datalist class="slider" id="steplist">
<% option.themeOptions.dataList.forEach(data => { %>
<option class="slider text-sm" style="user-select: none;"><strong><%- data %></strong></option>
<% }) %>
</datalist>
<datalist class="slider" id="steplist">
<% option.themeOptions.dataList.forEach(data => { %>
<option class="slider text-sm" style="user-select: none;"><strong><%- data %></strong></option>
<% }) %>
</datalist>
<% } %>
<input
<input
<% if(actual[s.categoryId][option.optionId]){ %>
defaultValue="<%= actual[s.categoryId][option.optionId] %>"
value="<%= actual[s.categoryId][option.optionId] %>"
defaultValue="<%= actual[s.categoryId][option.optionId] %>"
value="<%= actual[s.categoryId][option.optionId] %>"
<% } %>
class="form-control slider"
formType="slider"
id="<%= option.optionId %>"
type="range"
list="steplist"
step="<%= option.optionType.step %>"
min="<%= option.optionType.min %>"
max="<%= option.optionType.max %>"
class="form-control slider"
formType="slider"
id="<%= option.optionId %>"
type="range"
list="steplist"
step="<%= option.optionType.step %>"
min="<%= option.optionType.min %>"
max="<%= option.optionType.max %>"
<% if (option.themeOptions?.showValue) { %>
oninput="updateSlider(this.value, this.id)"
<% } %>
style="border: none !important; <% if(!Allowed.allowed){ %> border-color: red; <% } %>"
<% if(!Allowed.allowed){ %>
disabled
oninput="updateSlider(this.value, this.id)"
<% } %>
style="border: none !important; <% if(!Allowed.allowed){ %> border-color: red; <% } %>"
<% if(!Allowed.allowed){ %>
disabled
<% } %>
<% if (Allowed.allowed && option.optionType.disabled) { %>
disabled
disabled
<% } %>
>
<% if (option.themeOptions?.showValue) { %>
<p class="mt-2" style="margin-bottom: 0 !important;">Slider is set to <b><span id="value_<%= option.optionId %>"><% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% } %></span></b></p>
<p class="mt-2" style="margin-bottom: 0 !important;">Slider is set to <b><span id="value_<%= option.optionId %>"><% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% } %></span></b></p>
<% } %>

View file

@ -2,77 +2,77 @@
if (actual[s.categoryId][option.optionId]) val = "checked";
%>
<style>
/* The switch - the box around the slider */
.toggleSwitch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* The switch - the box around the slider */
.toggleSwitch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.toggleSwitch input {
opacity: 0;
width: 0;
height: 0;
}
/* Hide default HTML checkbox */
.toggleSwitch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.tslider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
/* The slider */
.tslider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.tslider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
.tslider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .tslider {
background-color: #2196F3;
}
input:checked + .tslider {
background-color: #2196F3;
}
input:focus + .tslider {
box-shadow: 0 0 1px #2196F3;
}
input:focus + .tslider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .tslider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
input:checked + .tslider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.tslider.round {
border-radius: 34px;
}
/* Rounded sliders */
.tslider.round {
border-radius: 34px;
}
.tslider.round:before {
border-radius: 50%;
}
.tslider.round:before {
border-radius: 50%;
}
</style>
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<label class="toggleSwitch">
<input type="checkbox" id="<%= option.optionId %>"
formtype="switch"
defaultValue=""
id="<%= option.optionId %>" <%- val %>
<% if(option.optionType.disabled || !Allowed.allowed ){ %>disabled<% } %>
>
<span class="tslider round"></span>
<input type="checkbox" id="<%= option.optionId %>"
formtype="switch"
defaultValue=""
id="<%= option.optionId %>" <%- val %>
<% if(option.optionType.disabled || !Allowed.allowed ){ %>disabled<% } %>
>
<span class="tslider round"></span>

View file

@ -1,25 +1,25 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<select
<select
<% if (actual[s.categoryId][option.optionId]) {%>
defaultValue="<%= JSON.stringify(actual[s.categoryId][option.optionId])%>"
defaultValue="<%= JSON.stringify(actual[s.categoryId][option.optionId])%>"
<% } %>
id="<%= option.optionId %>"
getValue="<%= option.optionId %>"
class="tags form-control"
multiple="multiple"
formType="tagInput"
id="<%= option.optionId %>"
getValue="<%= option.optionId %>"
class="tags form-control"
multiple="multiple"
formType="tagInput"
<% if(!Allowed.allowed){ %>
style="border-color: red;"
disabled
style="border-color: red;"
disabled
<% } %>
<% if (Allowed.allowed && option.optionType.disabled) { %>
disabled
disabled
<% } %>
>
<% if (actual[s.categoryId][option.optionId]) {%>
<% actual[s.categoryId][option.optionId].forEach(value=>{ %>
<option value="<%= value %>" selected><%= value %></option>
<% }) %>
<% } %>
<% actual[s.categoryId][option.optionId].forEach(value=>{ %>
<option value="<%= value %>" selected><%= value %></option>
<% }) %>
<% } %>
</select>

View file

@ -1,2 +1,2 @@
<% if(!Allowed.allowed){ %><span style="color: red;"><%- Allowed.errorMessage %></span><br><% } %>
<textarea id="<%= option.optionId %>"<%if(option.optionType.required){%>required<% } %><% if(option.optionType.disabled || !Allowed.allowed ){ %>disabled <% } %><% if(option.optionType.min){ %>minlength="<%= option.optionType.min %>"<% } %><% if(option.optionType.max){ %>maxlength="<%= option.optionType.max %>"<% } %>rows="4" class="col-md-12 form-control" defaultValue="<% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% }else{ %><%= option.optionType.data %><% } %>" formType="textarea"><% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% }else{ %><%= option.optionType.data %><% } %></textarea>
<textarea id="<%= option.optionId %>"<%if(option.optionType.required){%>required<% } %><% if(option.optionType.disabled || !Allowed.allowed ){ %>disabled <% } %><% if(option.optionType.min){ %>minlength="<%= option.optionType.min %>"<% } %><% if(option.optionType.max){ %>maxlength="<%= option.optionType.max %>"<% } %>rows="4" class="col-md-12 form-control" defaultValue="<% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% }else{ %><%= option.optionType.data %><% } %>" formType="textarea"><% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% }else{ %><%= option.optionType.data %><% } %></textarea>

View file

@ -1,221 +1,206 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now: 'credits'}) %>
<%- themeConfig?.customHtml %>
<%- include('partials/preloader.ejs', {now: 'credits'}) %>
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'credits'}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'credits'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4" style="padding-bottom: 0px !important;">
<div id="discordRocket" style="display: none;">
<div id="rocketDiscord"
style="position: absolute; margin: 0; top: 50%; left: 50%; -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); z-index: 420;">
<i class="fab fa-discord fa-10x" aria-hidden="true"></i>
</div>
<p style="font-size: 150%; position: absolute; margin: 0; top: 50%; left: 50%; transform: translate(-50%, -50%);">
Taking you to <b>discord.gg</b></p>
<!-- i cant figure out how to center this -->
</div>
<section class="py-sm-7 py-5 position-relative" id="mainSection" style="padding-top: 0px !important;">
<div>
<div class="row mb-4">
<div class="col-lg-12 mb-lg-0 mb-4" style="padding: 0px">
<div class="card">
<div class="card-body p-3">
<div class="row">
<div class="col-lg-6">
<div class="d-flex flex-column h-100">
<p class="mb-1 pt-2 text-bold">Soft-UI Theme</p>
<h5 class="font-weight-bolder">Soft UI Theme</h5>
<p>The Discord-Dashboard Soft UI theme was created as a feature-packed theme for DBD users!</p>
<p class="mb-1 mt-5"> Made with <i class="fa fa-heart"></i> by <a
href="https://github.com/PlainDevelopment"
class="font-weight-bold text-gradient text-primary"
style="font-weight: 700 !important;">PlainDevelopment</a> and <a
href="https://github.com/iMidnights"
class="font-weight-bold text-gradient text-primary"
style="font-weight: 700 !important;">iMidnight</a></p>
<a class="text-body text-sm font-weight-bold mb-0 icon-move-right"
href="https://github.com/Assistants-Center">
Visit our Github page
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
<div class="col-lg-5 ms-auto text-center mt-5 mt-lg-0">
<div class="bg-gradient-primary border-radius-lg h-100"
style="background-image: url('/img/soft-ui.webp') !important; background-repeat: no-repeat; background-size: contain; background-position: center;">
<div class="position-relative d-flex align-items-center justify-content-center h-100"
style="min-height: 210px !important;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-4 d-flex" style="justify-content: space-between;">
<div class="card" style="width: 300px; height: 465px; text-align: center;">
<div class="p-3">
<img class="img border-radius-lg max-width-200 w-100 position-relative z-index-2"
src="https://cdn.discordapp.com/avatars/715195498495082627/1eae1059ab1d33da0f99cd370c2014cf.webp"
style="width: 200px; height: 200px;"
alt="Plain">
</div>
<hr>
<div>
<div class="p-3 text-center" style="text-align: left !important; padding-top: 0 !important;">
<h2 class="text-gradient text-primary">Plain</h2>
<h5 class="mt-1" style="margin-bottom: 0;">Soft UI Developer</h5>
<p>Spent over 6 hours typing out all the feed icons.</p>
<div style="position: absolute; bottom: 15px;">
<a class="text-body text-bg font-weight-bold mb-0 icon-move-right"
href="https://github.com/PlainDevelopment">
Plain's Github
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</div>
<div class="card" style="width: 300px; height: 465px; text-align: center;">
<div class="p-3">
<img class="img border-radius-lg max-width-200 w-100 position-relative z-index-2"
src="https://cdn.discordapp.com/avatars/427534456169955352/5cff8985bb22c7b2bad7e0823412a45e.webp"
style="width: 200px; height: 200px;"
alt="iMidnight">
</div>
<hr>
<div>
<div class="p-3 text-center" style="text-align: left !important; padding-top: 0 !important;">
<h2 class="text-gradient text-primary">iMidnight</h2>
<h5 class="mt-1" style="margin-bottom: 0;">Soft UI Developer</h5>
<p>Potato Brain.</p>
<div style="position: absolute; bottom: 15px;">
<a class="text-body text-bg font-weight-bold mb-0 icon-move-right"
href="https://github.com/iMidnights">
iMidnight's Github
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</div>
<div class="card" style="width: 300px; height: 465px; text-align: center;">
<div class="p-3">
<img class="img border-radius-lg max-width-200 w-100 position-relative z-index-2"
src="https://avatars.githubusercontent.com/u/62174194"
style="width: 200px; height: 200px;"
alt="Breathtake">
</div>
<hr>
<div>
<div class="p-3 text-center" style="text-align: left !important; padding-top: 0 !important;">
<h2 class="text-gradient text-primary">Breathtake</h2>
<h5 class="mt-1" style="margin-bottom: 0;">Discord Dashboard Developer</h5>
<p>Project Ants.</p>
<div style="position: absolute; bottom: 15px;">
<a class="text-body text-bg font-weight-bold mb-0 icon-move-right"
href="https://github.com/breftejk">
Breathtake's Github
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
<%
const images = ["curved-1", "curved-2", "curved-3", "curved-4", "curved-5", "curved-6", "curved-7", "curved-8", "curved-9", "curved-10", "curved-11", "curved-12", "curved-13", "curved-14", "curved-15", "curved-16", "curved-17", "curved-18"];
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'credits'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4" style="padding-bottom: 0px !important;">
<div id="discordRocket" style="display: none;">
<div id="rocketDiscord"
style="position: absolute; margin: 0; top: 50%; left: 50%; -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); z-index: 420;">
<i class="fab fa-discord fa-10x" aria-hidden="true"></i>
</div>
<p style="font-size: 150%; position: absolute; margin: 0; top: 50%; left: 50%; transform: translate(-50%, -50%);">
Taking you to <b>discord.gg</b></p>
<!-- i cant figure out how to center this -->
</div>
<section class="py-sm-7 py-5 position-relative" id="mainSection" style="padding-top: 0px !important;">
<div>
<div class="row mb-4">
<div class="col-lg-12 mb-lg-0 mb-4" style="padding: 0px">
<div class="card">
<div class="card-body p-3">
<div class="row">
<div class="col-lg-6">
<div class="d-flex flex-column h-100">
<p class="mb-1 pt-2 text-bold">Soft-UI Theme</p>
<h5 class="font-weight-bolder">Soft UI Theme</h5>
<p>The Discord-Dashboard Soft UI theme was created as a feature-packed theme for DBD users!</p>
<p class="mb-1 mt-5"> Made with <i class="fa fa-heart"></i> by <a
href="https://github.com/PlainDevelopment"
class="font-weight-bold text-gradient text-primary"
style="font-weight: 700 !important;">PlainDevelopment</a> and <a
href="https://github.com/iMidnights"
class="font-weight-bold text-gradient text-primary"
style="font-weight: 700 !important;">iMidnight</a></p>
<a class="text-body text-sm font-weight-bold mb-0 icon-move-right"
href="https://github.com/Assistants-Center">
Visit our Github page
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
<div class="col-lg-5 ms-auto text-center mt-5 mt-lg-0">
<div class="bg-gradient-primary border-radius-lg h-100"
style="background-image: url('/img/soft-ui.webp') !important; background-repeat: no-repeat; background-size: contain; background-position: center;">
<div class="position-relative d-flex align-items-center justify-content-center h-100"
style="min-height: 210px !important;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-4 d-flex" style="justify-content: space-between;">
<div class="card" style="width: 300px; height: 465px; text-align: center;">
<div class="p-3">
<img class="img border-radius-lg max-width-200 w-100 position-relative z-index-2"
src="https://cdn.discordapp.com/avatars/715195498495082627/1eae1059ab1d33da0f99cd370c2014cf.webp"
style="width: 200px; height: 200px;"
alt="Plain">
</div>
<hr>
<div>
<div class="p-3 text-center" style="text-align: left !important; padding-top: 0 !important;">
<h2 class="text-gradient text-primary">Plain</h2>
<h5 class="mt-1" style="margin-bottom: 0;">Soft UI Developer</h5>
<p>Spent over 6 hours typing out all the feed icons.</p>
<div style="position: absolute; bottom: 15px;">
<a class="text-body text-bg font-weight-bold mb-0 icon-move-right"
href="https://github.com/PlainDevelopment">
Plain's Github
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</div>
<div class="card" style="width: 300px; height: 465px; text-align: center;">
<div class="p-3">
<img class="img border-radius-lg max-width-200 w-100 position-relative z-index-2"
src="https://cdn.discordapp.com/avatars/427534456169955352/5cff8985bb22c7b2bad7e0823412a45e.webp"
style="width: 200px; height: 200px;"
alt="iMidnight">
</div>
<hr>
<div>
<div class="p-3 text-center" style="text-align: left !important; padding-top: 0 !important;">
<h2 class="text-gradient text-primary">iMidnight</h2>
<h5 class="mt-1" style="margin-bottom: 0;">Soft UI Developer</h5>
<p>Potato Brain.</p>
<div style="position: absolute; bottom: 15px;">
<a class="text-body text-bg font-weight-bold mb-0 icon-move-right"
href="https://github.com/iMidnights">
iMidnight's Github
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</div>
<div class="card" style="width: 300px; height: 465px; text-align: center;">
<div class="p-3">
<img class="img border-radius-lg max-width-200 w-100 position-relative z-index-2"
src="https://avatars.githubusercontent.com/u/62174194"
style="width: 200px; height: 200px;"
alt="Breathtake">
</div>
<hr>
<div>
<div class="p-3 text-center" style="text-align: left !important; padding-top: 0 !important;">
<h2 class="text-gradient text-primary">Breathtake</h2>
<h5 class="mt-1" style="margin-bottom: 0;">Discord Dashboard Developer</h5>
<p>Project Ants.</p>
<div style="position: absolute; bottom: 15px;">
<a class="text-body text-bg font-weight-bold mb-0 icon-move-right"
href="https://github.com/breftejk">
Breathtake's Github
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
<%
const images = ["curved-1", "curved-2", "curved-3", "curved-4", "curved-5", "curved-6", "curved-7", "curved-8", "curved-9", "curved-10", "curved-11", "curved-12", "curved-13", "curved-14", "curved-15", "curved-16", "curved-17", "curved-18"];
const image = images[Math.floor(Math.random() * images.length)];
%>
<section class="pb-7 position-relative" id="getHelp">
<div class="page-header min-vh-50 m-3 border-radius-xl"
style="background-image: url('/img/curved-images/<%- image %>.webp');">
<span class="mask bg-gradient-dark opacity-8"></span>
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-6 text-center mx-auto">
<h1 class="text-white mt-4 mb-1">Got a question?</h1>
<p class="lead text-white mb-6">Join our discord server!</p>
</div>
<button type="button" style="border: none; background: none; cursor: pointer;" id="discordButton"
onclick="supportServer()">
<i class="fab fa-discord fa-7x" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
const image = images[Math.floor(Math.random() * images.length)];
%>
<section class="pb-7 position-relative" id="getHelp">
<div class="page-header min-vh-50 m-3 border-radius-xl"
style="background-image: url('/img/curved-images/<%- image %>.webp');">
<span class="mask bg-gradient-dark opacity-8"></span>
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-6 text-center mx-auto">
<h1 class="text-white mt-4 mb-1">Got a question?</h1>
<p class="lead text-white mb-6">Join our discord server!</p>
</div>
<button type="button" style="border: none; background: none; cursor: pointer;" id="discordButton"
onclick="supportServer()">
<i class="fab fa-discord fa-7x" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<%- include('partials/footer.ejs') %>
</section>
<%- include('partials/footer.ejs') %>
</section>
</div>
</main>
<script>
let disableFunc = false;
var win;
let disableFunc = false;
var win;
function supportServer() {
if (disableFunc) return;
disableFunc = true;
$('#discordButton').parent().css('overflow', 'hidden');
$('#discordButton').animate({'margin-top': '-=50px'});
$('#discordButton').animate({'margin-top': '+=500px', opacity: 0}, function () {
$(this).hide();
});
$("#discordRocket").fadeIn();
setTimeout(function () {
$('#rocketDiscord').animate({'margin-top': '+=600px'}, 1);
$("#mainSection").fadeOut();
$("#main2").fadeOut();
$("#getHelp").fadeOut();
}, 1000)
setTimeout(function () {
setTimeout(function () {
$('#rocketDiscord').animate({'margin-top': '+=75px'});
$('#rocketDiscord').animate({'margin-top': '-=1000px'}, 1500);
setTimeout(function () {
window.open('https://discord.gg/EdJFwNvNS9', '_blank', 'location=yes,height=1200,width=800');
function supportServer() {
if (disableFunc) return;
disableFunc = true;
$('#discordButton').parent().css('overflow', 'hidden');
$('#discordButton').animate({'margin-top': '-=50px'});
$('#discordButton').animate({'margin-top': '+=500px', opacity: 0}, function () {
$(this).hide();
});
$("#discordRocket").fadeIn();
setTimeout(function () {
$('#rocketDiscord').animate({'margin-top': '+=600px'}, 1);
$("#mainSection").fadeOut();
$("#main2").fadeOut();
$("#getHelp").fadeOut();
}, 1000)
setTimeout(function () {
setTimeout(function () {
$('#rocketDiscord').animate({'margin-top': '+=75px'});
$('#rocketDiscord').animate({'margin-top': '-=1000px'}, 1500);
setTimeout(function () {
window.open('https://discord.gg/EdJFwNvNS9', '_blank', 'location=yes,height=1200,width=800');
$("#rocketDiscord").fadeOut();
$("#discordRocket").fadeOut();
$("#rocketDiscord").fadeOut();
$("#discordRocket").fadeOut();
setTimeout(function () {
disableFunc = false;
location.reload();
}, 3500)
}, 1200)
}, 1500)
}, 2000);
}
setTimeout(function () {
disableFunc = false;
location.reload();
}, 3500)
}, 1200)
}, 1500)
}, 2000);
}
</script>

View file

@ -1,386 +1,285 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../testcdn/a05ee437b7ade39c78f8.css" data-n-p="">
<%- include('partials/preloader.ejs', {now: 'debug'}) %>
<%
<link rel="stylesheet" href="../testcdn/a05ee437b7ade39c78f8.css" data-n-p="">
<%- include("partials/preloader.ejs", {now: "debug"}) %>
<%
let seconds = Math.round(rawUptime % 60);
let seconds = Math.round(rawUptime % 60);
if (seconds > 59) seconds = Math.round(seconds % 60);
if (seconds > 59) seconds = Math.round(seconds % 60);
let minutes = Math.floor(rawUptime / 60);
let hours = Math.floor(minutes / 60);
let days = Math.floor(hours / 24);
let minutes = Math.floor(rawUptime / 60);
let hours = Math.floor(minutes / 60);
let days = Math.floor(hours / 24);
minutes = minutes % 60;
hours = hours % 24;
minutes = minutes % 60;
hours = hours % 24;
let filterUptime = `${days}d, ${hours}h, ${minutes}m, ${seconds}s`;
if (!days) filterUptime = `${hours}h, ${minutes}m, ${seconds}s`;
if (!hours) filterUptime = `${minutes}m, ${seconds}s`;
if (!minutes) filterUptime = `${seconds}s`;
let filterUptime = `${days}d, ${hours}h, ${minutes}m, ${seconds}s`;
if (!days) filterUptime = `${hours}h, ${minutes}m, ${seconds}s`;
if (!hours) filterUptime = `${minutes}m, ${seconds}s`;
if (!minutes) filterUptime = `${seconds}s`;
let modified = 0;
let modified = 0;
if (onlineFiles.index.replace(/\s+/g, '') !== localFiles.index.replace(/\s+/g, '')) modified++;
if (onlineFiles.guild.replace(/\s+/g, '') !== localFiles.guild.replace(/\s+/g, '')) modified++;
if (onlineFiles.guilds.replace(/\s+/g, '') !== localFiles.guilds.replace(/\s+/g, '')) modified++;
const info = []
const versions = []
if (modified !== 0) modded = "true"
else modded = "false"
const info = []
const versions = []
if (modified !== 0) modded = "true"
else modded = "false"
let information = [
{name: "Theme", value: "Soft UI Theme"},
{name: "Modified", value: `${modded}`},
{name: "Uptime", value: `${filterUptime}`},
// {name: "Permissions", value: req.requiredPermissions},
{name: "Redirect URI", value: `${config.redirectUri?.includes("/discord/callback")}`}
]
let information = [
{name: "Theme", value: "Soft UI Theme"},
{name: "Modified", value: `${modded}`},
{name: "License Type", value: `${license}`},
{name: "Uptime", value: `${filterUptime}`},
{name: "Permissions", value: req.requiredPermissions},
{name: "Redirect URI", value: `${config.redirectUri?.includes("/discord/callback")}`}
]
let modules = [
{name: "Node JS", version: `${nodeVersion.split("v")[1]}`},
{name: "Discord JS", version: `${discordVersion}`, npm: "discord.js"},
{name: "Discord Dashboard", version: `${dbdVersion}`, npm: "discord-dashboard"},
{name: "Theme", version: `${themeVersion}`, npm: "soft-ui"},
]
let modules = [
{name: "Node JS", version: `${nodeVersion.split("v")[1]}`},
{name: "Discord JS", version: `${discordVersion}`, npm: "discord.js"},
{name: "Discord Dashboard", version: `${dbdVersion}`, npm: "discord-dashboard"},
{name: "Theme", version: `${themeVersion}`, npm: "soft-ui"},
]
const settings = config.settings
onlineV.forEach(online => {
const current = localV[online.name];
const latest = online.version;
const name = online.name;
let debug = {information, modules, versions, settings, themeConfig}
versions.push({name: name, current: current, latest: latest})
});
const settings = config.settings
let debug = {information, modules, versions, settings, themeConfig}
var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(debug));
%>
<%- themeConfig?.customHtml %>
var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(debug));
%>
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'debug'}) %>
<%- include("partials/preload.ejs") %>
<%- include("partials/sidebar.ejs", {config: config, now:"debug"}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'debug'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="modal fade" id="exampleModalSignUp" tabindex="-1" role="dialog"
aria-labelledby="exampleModalSignTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-body p-0">
<div class="card card-plain">
<div class="card-header pb-0 text-left">
<h4 class="font-weight-bolder text-primary text-gradient">Download Log file.</h4>
<p class="mb-0"
style="text-align: center;">This log contains the dashboard's Theme Config and all options with any personal information redacted.</p>
</div>
<div class="card-body pb-3" id="form1">
<form role="form text-left">
<div class="text-center">
<%
//new date
const date = new Date();
//convert unix to string
const dateString = date.toString();
//split date string
const dateSplit = dateString.split(" ");
//get date
const dateFinal = dateSplit[2] + "-" + dateSplit[1] + "-" + dateSplit[3];
//get time
const timeFinal = dateSplit[4];
//split by space and join by -
const timeFinal2 = timeFinal.replace(/[&\/\\#, +()$~%.'":*?<>{}]/g, '-');
%>
<a href="data:<%- data %>"
download="Log_SoftUI_<%- timeFinal2 %>_<%- dateFinal %>.json"
class="btn bg-gradient-primary">download JSON</a>
</div>
</form>
</div>
<div class="card-footer text-center pt-0 px-sm-4 px-1">
Paste this in the <a
href="https://discord.com/channels/803034737261936670/803036935785414717"
target="_blank" class="text-dark font-weight-bolder">#😖»get-help</a> channel.
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-xl-6">
<div class="row pb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fab fa-node-js opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Node JS</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- nodeVersion.split("v")[1] %></h5>
</div>
</div>
</div>
<div class="col-md-6 mt-md-0 mt-4">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fab fa-discord opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Discord.JS</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- discordVersion %></h5>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-6">
<style>
.fab {
color: rgb(232, 230, 227) !important;
}
<!-- Navbar -->
<%- include("partials/navbar.ejs", {now:"debug"}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="modal fade" id="exampleModalSignUp" tabindex="-1" role="dialog"
aria-labelledby="exampleModalSignTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-body p-0">
<div class="card card-plain">
<div class="card-header pb-0 text-left">
<h4 class="font-weight-bolder text-primary text-gradient">Download Log file.</h4>
<p class="mb-0"
style="text-align: center;">This log contains the dashboard"s Theme Config and all options with any personal information redacted.</p>
</div>
<div class="card-body pb-3" id="form1">
<form role="form text-left">
<div class="text-center">
<%
//new date
const date = new Date();
//convert unix to string
const dateString = date.toString();
//split date string
const dateSplit = dateString.split(" ");
//get date
const dateFinal = dateSplit[2] + "-" + dateSplit[1] + "-" + dateSplit[3];
//get time
const timeFinal = dateSplit[4];
//split by space and join by -
const timeFinal2 = timeFinal.replace(/[&\/\\#, +()$~%."":*?<>{}]/g, "-");
%>
<a href="data:<%- data %>"
download="Log_SoftUI_<%- timeFinal2 %>_<%- dateFinal %>.json"
class="btn bg-gradient-primary">download JSON</a>
</div>
</form>
</div>
<div class="card-footer text-center pt-0 px-sm-4 px-1">
Paste this in the <a
href="https://discord.com/channels/803034737261936670/803036935785414717"
target="_blank" class="text-dark font-weight-bolder">#😖»get-help</a> channel.
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-xl-6">
<div class="row pb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fab fa-node-js opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Node JS</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- nodeVersion.split("v")[1] %></h5>
</div>
</div>
</div>
<div class="col-md-6 mt-md-0 mt-4">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fab fa-discord opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Discord.JS</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- discordVersion %></h5>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-6">
<style>
.fab {
color: rgb(232, 230, 227) !important;
}
.fas {
color: rgb(232, 230, 227) !important;
}
</style>
<div class="row">
<div class="col-md-6 mb-4">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fas fa-landmark opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Discord Dashboard</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- dbdVersion %></h5>
</div>
</div>
</div>
<div class="col-md-6 mt-md-0 mt-4 mb-4">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fas fa-cloud opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Theme</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- themeVersion %></h5>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-lg-0 mb-4">
<div class="card">
<div class="card-header pb-0 p-3">
<div class="row">
<div class="col-6 d-flex align-items-center">
<h6 class="mb-0">Dashboard Logs</h6>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<div data-bs-toggle="modal" style="cursor: pointer;"
data-bs-target="#exampleModalSignUp"
class="alert alert-primary text-white font-weight-bold text-center"
role="alert">
Download Logs
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-lg-0 mb-4">
<div class="card">
<div class="card-header pb-0 p-3">
<div class="row">
<div class="col-6 d-flex align-items-center">
<h6 class="mb-0">Theme Modification</h6>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<% if(modified !== 0){ %>
<div class="alert alert-danger text-white font-weight-bold"
role="alert">
This theme has been modified!
</div>
<% } else{ %>
<div class="alert alert-success text-white font-weight-bold"
role="alert">
This theme has not been modified!
</div>
<% } %>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-lg-0 mb-4">
<div class="card">
<div class="card-header pb-0 p-3">
<div class="row">
<div class="col-6 d-flex align-items-center">
<h6 class="mb-0">Dashboard Information</h6>
</div>
<div style="text-align: right;" class="col-6 align-items-right">
<a style="text-align: right;">Uptime: <%- filterUptime %></a>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<% if (license == "opensource") { %>
<div class="alert alert-primary text-white font-weight-bold"
role="alert">
License type: <span
style="text-transform: capitalize;"><%- license %></span>
</div>
<% } else if (license == "personal") { %>
<div class="alert alert-success text-white font-weight-bold"
role="alert">
License type: <span
style="text-transform: capitalize;"><%- license %></span>
</div>
<% } else if (license == "production") { %>
<div class="alert alert-info text-white font-weight-bold" role="alert">
License type: <span
style="text-transform: capitalize;"><%- license %></span>
</div>
<% } else { %>
<div class="alert alert-warning text-white font-weight-bold"
role="alert">
License type: <span
style="text-transform: capitalize;">Unknown</span>
</div>
<% } %>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12 mt-4">
<div class="col-12 col-lg-12 mb-4">
<div class="card ">
<div class="card-header pb-0 p-3">
<div class="d-flex justify-content-between">
<h6 class="mb-2">Partial Information</h6>
</div>
</div>
<div class="table-responsive">
<table class="table align-items-center ">
<tbody>
<% onlineV.forEach(online => { %>
<%
const latest = onlineV[online.version];
const current = localV[online.name];
const newest = online.version;
%>
<tr>
<td class="w-30">
<div class="d-flex px-2 py-1 align-items-center">
<div class="ms-2">
<p class="text-xs font-weight-bold mb-0">Name:</p>
<h6 class="text-sm mb-0"
style="text-transform: capitalize;"><%- online.name %></h6>
</div>
</div>
</td>
<td>
<div class="text-center">
<p class="text-xs font-weight-bold mb-0">Version:</p>
<h6 class="text-sm mb-0"><%- current %></h6>
</div>
</td>
<td>
<div class="text-center">
<p class="text-xs font-weight-bold mb-0">Type:</p>
<h6 class="text-sm mb-0"
style="text-transform: capitalize;"><%- online.type %></h6>
</div>
</td>
<td class="align-middle text-sm">
<div class="col text-center">
<p class="text-xs font-weight-bold mb-0">Latest:</p>
<%
let update = true;
if (newest > current) update = true;
if (newest == current) update = false;
%>
<% if (update) { %>
<span class="badge bg-gradient-danger"><%- online.version %></span>
<% } else { %>
<span class="badge bg-gradient-success"><%- online.version %></span>
<% } %>
</div>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
</div>
<%- include('partials/footer.ejs') %>
</div>
</main>
</div>
<%- include('partials/scripts.ejs', {now: "debug"}) %>
.fas {
color: rgb(232, 230, 227) !important;
}
</style>
<div class="row">
<div class="col-md-6 mb-4">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fas fa-landmark opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Discord Dashboard</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- dbdVersion %></h5>
</div>
</div>
</div>
<div class="col-md-6 mt-md-0 mt-4 mb-4">
<div class="card">
<div class="card-header mx-4 p-3 text-center">
<div class="icon icon-shape icon-lg bg-gradient-primary shadow text-center border-radius-lg">
<i class="fas fa-cloud opacity-10" aria-hidden="true"></i>
</div>
</div>
<div class="card-body pt-0 p-3 text-center">
<h6 class="text-center mb-0">Theme</h6>
<span class="text-xs">Version</span>
<hr class="horizontal dark my-3">
<h5 class="mb-0"><%- themeVersion %></h5>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-lg-0 mb-4">
<div class="card">
<div class="card-header pb-0 p-3">
<div class="row">
<div class="col-6 d-flex align-items-center">
<h6 class="mb-0">Dashboard Logs</h6>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<div data-bs-toggle="modal" style="cursor: pointer;"
data-bs-target="#exampleModalSignUp"
class="alert alert-primary text-white font-weight-bold text-center"
role="alert">
Download Logs
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-lg-0 mb-4">
<div class="card">
<div class="card-header pb-0 p-3">
<div class="row">
<div class="col-6 d-flex align-items-center">
<h6 class="mb-0">Theme Modification</h6>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<% if(modified !== 0){ %>
<div class="alert alert-danger text-white font-weight-bold"
role="alert">
This theme has been modified!
</div>
<% } else{ %>
<div class="alert alert-success text-white font-weight-bold"
role="alert">
This theme has not been modified!
</div>
<% } %>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-lg-0 mb-4">
<div class="card">
<div class="card-header pb-0 p-3">
<div class="row">
<div class="col-6 d-flex align-items-center">
<h6 class="mb-0">Dashboard Information</h6>
</div>
<div style="text-align: right;" class="col-6 align-items-right">
<a style="text-align: right;">Uptime: <%- filterUptime %></a>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="row">
<div class="col-md-12 mb-md-0 mb-4">
<div class="alert alert-warning text-white font-weight-bold" role="alert">
License type: <span style="text-transform: capitalize;">No License</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12 mt-4">
<div class="col-12 col-lg-12 mb-4">
<div class="card ">
<div class="card-header pb-0 p-3">
<div class="d-flex justify-content-between">
<h6 class="mb-2">Partial Information</h6>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
</div>
<%- include("partials/footer.ejs") %>
</div>
</main>
</div>
<%- include("partials/scripts.ejs", {now: "debug"}) %>
</body>
</html>

View file

@ -1,151 +1,136 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now: 'error'}) %>
<%
let data
<%- include('partials/preloader.ejs', {now: 'error'}) %>
<%
let data
if (error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) {
data = "text/json;charset=utf-8," + encodeURIComponent(error) + "\n"
data += `${error.path}`
}
%>
<% if (error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) { %>
<script>
function copyToClipboard(text) {
if (window.clipboardData && window.clipboardData.setData) {
return window.clipboardData.setData("Text", text);
}
else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
var textarea = document.createElement("textarea");
textarea.textContent = text;
textarea.style.position = "fixed";
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand("copy");
}
catch (ex) {
console.warn("Copy to clipboard failed.", ex);
prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
finally {
document.body.removeChild(textarea);
sweetalert("success", "Copied to clipboard", 3000)
}
}
}
</script>
<% } %>
<%- themeConfig?.customHtml %>
if (error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) {
data = "text/json;charset=utf-8," + encodeURIComponent(error) + "\n"
data += `${error.path}`
}
%>
<% if (error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) { %>
<script>
function copyToClipboard(text) {
if (window.clipboardData && window.clipboardData.setData) {
return window.clipboardData.setData("Text", text);
}
else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
var textarea = document.createElement("textarea");
textarea.textContent = text;
textarea.style.position = "fixed";
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand("copy");
}
catch (ex) {
console.warn("Copy to clipboard failed.", ex);
prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
finally {
document.body.removeChild(textarea);
sweetalert("success", "Copied to clipboard", 3000)
}
}
}
</script>
<% } %>
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<header>
<div class="page-header min-vh-85">
<%
const images = ["curved-1", "curved-2", "curved-3", "curved-4", "curved-5", "curved-6", "curved-7", "curved-8", "curved-9", "curved-10", "curved-11", "curved-12", "curved-13", "curved-14", "curved-15", "curved-16", "curved-17", "curved-18"];
const image = images[Math.floor(Math.random() * images.length)];
%>
<div style="background-image: url('/img/curved-images/<%- image %>.webp') !important; background: no-repeat; background-size: cover;"
class="position-absolute fixed-top ms-auto w-50 h-100 z-index-0 d-none d-sm-none d-md-block border-radius-section border-top-end-radius-0 border-top-start-radius-0 border-bottom-end-radius-0">
<span class="mask bg-gradient-primary ms-auto h-100 z-index-0 d-none d-sm-none d-md-block border-radius-section border-top-end-radius-0 border-top-start-radius-0 border-bottom-end-radius-0">
</span>
</div>
<div class="container">
<div class="row">
<div class="col-lg-7 d-flex">
<div class="card card-body blur text-md-start text-center px-sm-5 shadow-lg mt-sm-5 py-sm-5">
<h2 class="text-gradient text-primary mb-0"> <%- title %></h2>
<h2 class="text-dark mb-4"><%- subtitle %></h2>
<p class="lead text-dark pe-md-5 me-md-5">
<%- description %>
</p>
<% if (req.originalUrl !== "/") { %>
<div class="buttons">
<a href="/" class="btn btn-rounded bg-gradient-primary mt-4">Return to home</a>
<!-- <a target="_blank" href="https://discord.gg/CHbfcSbEgd" class="btn btn-rounded btn-outline-secondary mt-4 ms-2">Get help</a> -->
</div>
<% } %>
</div>
</div>
</div>
</div>
</div>
<div class="page-header min-vh-85">
<%
const images = ["curved-1", "curved-2", "curved-3", "curved-4", "curved-5", "curved-6", "curved-7", "curved-8", "curved-9", "curved-10", "curved-11", "curved-12", "curved-13", "curved-14", "curved-15", "curved-16", "curved-17", "curved-18"];
const image = images[Math.floor(Math.random() * images.length)];
%>
<div style="background-image: url('/img/curved-images/<%- image %>.webp') !important; background: no-repeat; background-size: cover;"
class="position-absolute fixed-top ms-auto w-50 h-100 z-index-0 d-none d-sm-none d-md-block border-radius-section border-top-end-radius-0 border-top-start-radius-0 border-bottom-end-radius-0">
<span class="mask bg-gradient-primary ms-auto h-100 z-index-0 d-none d-sm-none d-md-block border-radius-section border-top-end-radius-0 border-top-start-radius-0 border-bottom-end-radius-0">
</span>
</div>
<div class="container">
<div class="row">
<div class="col-lg-7 d-flex">
<div class="card card-body blur text-md-start text-center px-sm-5 shadow-lg mt-sm-5 py-sm-5">
<h2 class="text-gradient text-primary mb-0"> <%- title %></h2>
<h2 class="text-dark mb-4"><%- subtitle %></h2>
<p class="lead text-dark pe-md-5 me-md-5">
<%- description %>
</p>
<% if (req.originalUrl !== "/") { %>
<div class="buttons">
<a href="/" class="btn btn-rounded bg-gradient-primary mt-4">Return to home</a>
<!-- <a target="_blank" href="https://discord.gg/CHbfcSbEgd" class="btn btn-rounded btn-outline-secondary mt-4 ms-2">Get help</a> -->
</div>
<% } %>
</div>
</div>
</div>
</div>
</div>
</header>
</main>
<%- include('partials/scripts.ejs', {now: "index"}) %>
<% if(error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) { %>
<div class="modal fade" id="exampleModalSignUp" tabindex="-1" role="dialog" aria-labelledby="exampleModalSignTitle"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document" style="max-width: 700px;">
<div class="modal-content">
<div class="modal-body p-0">
<div class="card card-plain">
<div class="card-body pb-3" id="form1">
<h4 class="font-weight-bolder text-primary text-gradient">Viewing Error</h4>
<pre><%= error %><br><br>Error occured at: <%- error.path %><br>Check console logs for more information</pre>
</div>
<div class="d-flex" style="justify-content: flex-end; margin-right: 20px">
<!--
<button onclick="copyToClipboard(`<%= strError %>`)" class="btn btn-primary" style="margin-left: 10px;">Copy
error
</button>
-->
</div>
</div>
</div>
</div>
</div>
</div>
<% if (error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) { %>
<script>
if (window.addEventListener) {
const konami = <%- JSON.stringify(themeConfig?.error?.dbdError?.secretMenuCombination || ["69", "82", "82", "79", "82"]) %> //this spells error
let
<div class="modal fade" id="exampleModalSignUp" tabindex="-1" role="dialog" aria-labelledby="exampleModalSignTitle"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document" style="max-width: 700px;">
<div class="modal-content">
<div class="modal-body p-0">
<div class="card card-plain">
<div class="card-body pb-3" id="form1">
<h4 class="font-weight-bolder text-primary text-gradient">Viewing Error</h4>
<pre><%= error %><br><br>Error occured at: <%- error.path %><br>Check console logs for more information</pre>
</div>
<div class="d-flex" style="justify-content: flex-end; margin-right: 20px">
<!--
<button onclick="copyToClipboard(`<%= strError %>`)" class="btn btn-primary" style="margin-left: 10px;">Copy
error
</button>
-->
</div>
</div>
</div>
</div>
</div>
</div>
<% if (error !== undefined && error && config.ownerIDs?.includes(req.session?.user?.id) && !themeConfig?.error?.dbdError?.disableSecretMenu) { %>
<script>
if (window.addEventListener) {
const konami = <%- JSON.stringify(themeConfig?.error?.dbdError?.secretMenuCombination || ["69", "82", "82", "79", "82"]) %> //this spells error
let
currentCount = 0;
let entered = [];
window.addEventListener("keydown", function (e) {
if (e.keyCode.toString() === konami[currentCount]) {
if (currentCount !== 0 && entered[currentCount - 1] !== konami[currentCount - 1]) {
// User has messed with variables in console to try show it smh
entered = [];
return currentCount = 0;
}
if (!konami[currentCount + 1]) {
// Correct code
$('#exampleModalSignUp').modal('show');
currentCount = 0;
return entered = [];
}
entered.push(e.keyCode.toString());
currentCount++;
} else {
currentCount = 0;
return entered = [];
}
}, true);
}
</script>
<% } %>
let entered = [];
window.addEventListener("keydown", function (e) {
if (e.keyCode.toString() === konami[currentCount]) {
if (currentCount !== 0 && entered[currentCount - 1] !== konami[currentCount - 1]) {
// User has messed with variables in console to try show it smh
entered = [];
return currentCount = 0;
}
if (!konami[currentCount + 1]) {
// Correct code
$('#exampleModalSignUp').modal('show');
currentCount = 0;
return entered = [];
}
entered.push(e.keyCode.toString());
currentCount++;
} else {
currentCount = 0;
return entered = [];
}
}, true);
}
</script>
<% } %>
<% } %>
</body>

View file

@ -1,32 +1,16 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.onload = function () {
if(window.location.search.startsWith("?redirect=")) window.opener.location = window.location.replace("?redirect=", "");
else window.location.href = `settings/<%= req.params.id %>`;
}
</script>
<script>
window.onload = function () {
if(window.location.search.startsWith("?redirect=")) window.opener.location = window.location.replace("?redirect=", "");
else window.location.href = `settings/<%= req.params.id %>`;
}
</script>
</head>
<body class="g-sidenav-show bg-gray-100">
</body>
</html>
</html>

View file

@ -1,115 +1,100 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now:'manage'}) %>
<%- include('partials/preloader.ejs', {now:'manage'}) %>
<link rel="stylesheet" href="/css/dashboard/guilds.css">
<%- themeConfig?.customHtml %>
<link rel="stylesheet" href="/css/dashboard/guilds.css">
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'manage'}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<%- include('partials/navbar.ejs', {now:'manage'}) %>
<div class="container-fluid py-4" style="padding-bottom: 0px !important;">
<div class="row">
<div class="col-12" id="divtable">
<div class="card mb-4">
<div class="card-header pb-0" style="text-align: center;">
<h2 class="mb-1">
Your servers
</h2>
<p class="mb-0 font-weight-bold text-sm">
Select the server you want to configure
</p>
</div>
<div class="card-body px-0 pt-0 pb-2">
<div style="margin-bottom: 35px; margin-top: 0px; text-align: center;">
<%
for(var i in req.session.guilds){ %>
<% if((req.session.guilds[i].permissions & 0x00000020) == 0x00000020){ %>
<% if(bot.guilds.cache.get(req.session.guilds[i].id)){
const guild = bot.guilds.cache.get(req.session.guilds[i].id);
let icon;
<%- include('partials/navbar.ejs', {now:'manage'}) %>
<div class="container-fluid py-4" style="padding-bottom: 0px !important;">
<div class="row">
<div class="col-12" id="divtable">
<div class="card mb-4">
<div class="card-header pb-0" style="text-align: center;">
<h2 class="mb-1">
Your servers
</h2>
<p class="mb-0 font-weight-bold text-sm">
Select the server you want to configure
</p>
</div>
<div class="card-body px-0 pt-0 pb-2">
<div style="margin-bottom: 35px; margin-top: 0px; text-align: center;">
<%
for(var i in req.session.guilds){ %>
<% if((req.session.guilds[i].permissions & 0x00000020) == 0x00000020){ %>
<% if(bot.guilds.cache.get(req.session.guilds[i].id)){
const guild = bot.guilds.cache.get(req.session.guilds[i].id);
let icon;
if (!guild.iconURL()) icon = themeConfig?.icons?.noGuildIcon;
else icon = guild.iconURL() + "?size=256";
%>
<a oncontextmenu="window.location='/guild/<%- guild.id %>'; return false;"
onclick="window.location='/settings/<%- guild.id %>'">
<div max="20" scale="110" perspective="400" class="_82d1"
data-guildname="<%- guild.name %>"
style="background-image: url(&quot;<%- icon %>&quot;);"></div>
</a>
<% } } } %>
</div>
<div class="_4204" style="margin-bottom: 35px; text-align: center;">
<% for (var i in req.session.guilds){ %>
<% if((req.session.guilds[i].permissions & 0x00000020) == 0x00000020){ %>
<%
if(!bot.guilds.cache.get(req.session.guilds[i].id)){
let icon = `https://cdn.discordapp.com/icons/${req.session.guilds[i].id}/${req.session.guilds[i].icon}.png`;
const friendlyName = req.session.guilds[i].name.replace('`', '');
if (!req.session.guilds[i].icon) icon = themeConfig.icons.noGuildIcon;
else icon = icon + "?size=256"
%>
<!--href="../invite?g=<%- req.session.guilds[i].id %>"-->
<a onclick="const newWindow = window.open(`/invite?g=<%- req.session.guilds[i].id %><%- config.invite?.redirectUri ? `&redirect=${config.invite.redirectUri.replace('{SERVER}', req.session.guilds[i].id)}` : '' %>`, 'Add bot to guild', 'scrollbars=no, resizable=no, status=no, location=no, toolbar=no, menubar=no, width=500, height=800'); checkRefresh()">
<div max="20" scale="110" perspective="700" class="_82d1"
data-guildname="<%- req.session.guilds[i].name %>"
style="background-image: url(&quot;<%- icon %>&quot;); filter: grayscale(1);"></div>
</a>
if (!guild.iconURL()) icon = themeConfig?.icons?.noGuildIcon;
else icon = guild.iconURL() + "?size=256";
%>
<a oncontextmenu="window.location='/guild/<%- guild.id %>'; return false;"
onclick="window.location='/settings/<%- guild.id %>'">
<div max="20" scale="110" perspective="400" class="_82d1"
data-guildname="<%- guild.name %>"
style="background-image: url(&quot;<%- icon %>&quot;);"></div>
</a>
<% } } } %>
</div>
<div class="_4204" style="margin-bottom: 35px; text-align: center;">
<% for (var i in req.session.guilds){ %>
<% if((req.session.guilds[i].permissions & 0x00000020) == 0x00000020){ %>
<%
if(!bot.guilds.cache.get(req.session.guilds[i].id)){
let icon = `https://cdn.discordapp.com/icons/${req.session.guilds[i].id}/${req.session.guilds[i].icon}.png`;
const friendlyName = req.session.guilds[i].name.replace('`', '');
if (!req.session.guilds[i].icon) icon = themeConfig.icons.noGuildIcon;
else icon = icon + "?size=256"
%>
<!--href="../invite?g=<%- req.session.guilds[i].id %>"-->
<a onclick="const newWindow = window.open(`/invite?g=<%- req.session.guilds[i].id %><%- config.invite?.redirectUri ? `&redirect=${config.invite.redirectUri.replace('{SERVER}', req.session.guilds[i].id)}` : '' %>`, 'Add bot to guild', 'scrollbars=no, resizable=no, status=no, location=no, toolbar=no, menubar=no, width=500, height=800'); checkRefresh()">
<div max="20" scale="110" perspective="700" class="_82d1"
data-guildname="<%- req.session.guilds[i].name %>"
style="background-image: url(&quot;<%- icon %>&quot;); filter: grayscale(1);"></div>
</a>
<% } } } %>
<script>
function checkRefresh() {
setInterval(() => {
if (newWindow.closed) location.reload();
}, 500);
}
</script>
</div>
</div>
</div>
</div>
<%- include('partials/footer.ejs') %>
</div>
</div>
<!-- Core JS Files -->
<script src="../assets/js/core/popper.min.js"></script>
<script src="../assets/js/core/bootstrap.min.js"></script>
<script src="../assets/js/plugins/perfect-scrollbar.min.js"></script>
<script src="../assets/js/plugins/smooth-scrollbar.min.js"></script>
<script>
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
</script>
<!-- Github buttons -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<!-- Control Center for Soft Dashboard: parallax effects, scripts for the example pages etc -->
<%- include('partials/scripts.ejs', {now: "guilds"}) %>
<% } } } %>
<script>
function checkRefresh() {
setInterval(() => {
if (newWindow.closed) location.reload();
}, 500);
}
</script>
</div>
</div>
</div>
</div>
<%- include('partials/footer.ejs') %>
</div>
</div>
<!-- Core JS Files -->
<script src="../assets/js/core/popper.min.js"></script>
<script src="../assets/js/core/bootstrap.min.js"></script>
<script src="../assets/js/plugins/perfect-scrollbar.min.js"></script>
<script src="../assets/js/plugins/smooth-scrollbar.min.js"></script>
<script>
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
</script>
<!-- Github buttons -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<!-- Control Center for Soft Dashboard: parallax effects, scripts for the example pages etc -->
<%- include('partials/scripts.ejs', {now: "guilds"}) %>
</body>
</html>

View file

@ -1,36 +1,21 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<%- include('partials/preloader.ejs', {now:'index', req: req}) %>
<% if (req.query?.guild_id) { %>
<script>
window.onload = function () {
window.onunload = refreshParent;
<script>
window.onload = function () {
window.onunload = refreshParent;
function refreshParent() {
window.opener.location = `/settings/<%= req.query?.guild_id %>`;
window.close();
return
};
window.opener.location = `/settings/<%= req.query?.guild_id %>`;
window.close();
}
</script>
<%- themeConfig?.customHtml %>
function refreshParent() {
window.opener.location = `/settings/<%= req.query?.guild_id %>`;
window.close();
return
};
window.opener.location = `/settings/<%= req.query?.guild_id %>`;
window.close();
}
</script>
<%- themeConfig?.customHtml %>
<% } %>
<head>
</head>
@ -38,115 +23,115 @@
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'index'}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'index'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4" style="padding-bottom: 0px !important;">
<div class="row mb-3">
<%
let i = 0;
customThemeOptions.cards.forEach((stats) => {
%>
<div class="col-xl-3 col-sm-6 mb-xl-0 mb-4">
<div class="card">
<div class="card-body p-3">
<div class="row">
<div class="col-8">
<div class="numbers">
<p class="text-sm mb-0 text-capitalize font-weight-bold">
<%- req?.locales?.index?.feeds[i] || stats.title %></p>
<h5 class="font-weight-bolder mb-0">
<%- stats.getValue %>
</h5>
</div>
<% if(stats.progressBar && stats.progressBar.enabled){ %>
<div class="progress w-150" style="margin-top: 6px;">
<div style="width: <%= stats.progressBar.getProgress %>% !important"
aria-label="Progress Bar"
class="progress-bar bg-gradient-primary"
role="progressbar" aria-valuenow="80" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
<% } %>
</div>
<div class="col-4 text-end">
<div class="icon icon-shape bg-gradient-primary shadow text-center border-radius-md">
<i class="ni ni-<%= stats.icon %> text-lg opacity-10" aria-hidden="true"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<% i++ }); %>
</div>
<div class="row">
<div class="col-lg-12 mb-lg-0 mb-4">
<div class="card">
<div class="card-body p-3">
<div class="row">
<div class="col-lg-6">
<div class="d-flex flex-column h-100">
<p class="mb-1 pt-2 text-bold"><%- req?.locales?.index?.card?.category %></p>
<h5 class="font-weight-bolder"><%- req?.locales?.index?.card?.title %></h5>
<p><%- req?.locales?.index?.card?.description %></p>
<p class="mb-5"><%= req?.locales?.index?.card?.footer %></p>
<% if(themeConfig.index?.card?.link?.enabled) { %>
<a class="text-body text-sm font-weight-bold mb-0 icon-move-right mt-auto"
href="<%- themeConfig.index.card.link.url %>">
<%- req?.locales?.index?.card?.link?.text %>
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
<% } %>
</div>
</div>
<div class="col-lg-5 ms-auto text-center mt-5 mt-lg-0">
<div class="bg-gradient-primary border-radius-lg h-100"
style="background-image: url('<%= req?.locales?.index?.card?.image %>') !important; background-repeat: no-repeat; background-size: contain; background-position: center;">
<div class="position-relative d-flex align-items-center justify-content-center h-100"
style="min-height: 210px !important;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-7 mb-lg-0 mb-4">
<div class="card z-index-2">
<div class="card-body p-3">
<h5 class="font-weight-bolder"><%- req?.locales?.index?.feeds.title || "Feeds" %></h5>
<%- include('partials/feeds.ejs', {require, admin:false}) %>
</div>
</div>
</div>
<div class="col-lg-5 mb-4">
<% if(themeConfig.index?.graph?.enabled) { %>
<div class="card z-index-2">
<div class="card-body p-3">
<h5 class="font-weight-bolder"><%- req?.locales?.index?.graph?.title %></h5>
<% if(themeConfig.index.graph.lineGraph) { %>
<div class="bg-gradient-dark border-radius-lg py-3 pe-1 mb-3">
<% } %>
<div class="chart">
<% if(!themeConfig.index.graph.lineGraph) { %>
<canvas id="chart-line" class="chart-canvas" height="300"></canvas>
<% } else { %>
<canvas id="chart-bars" class="chart-canvas" height="170"></canvas>
<% } %>
</div>
<% if(themeConfig.index.graph.lineGraph) { %>
</div>
<% } %>
</div>
</div>
</div>
</div>
<% } %>
</div>
<%- include('partials/footer.ejs') %>
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'index'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4" style="padding-bottom: 0px !important;">
<div class="row mb-3">
<%
let i = 0;
customThemeOptions.cards.forEach((stats) => {
%>
<div class="col-xl-3 col-sm-6 mb-xl-0 mb-4">
<div class="card">
<div class="card-body p-3">
<div class="row">
<div class="col-8">
<div class="numbers">
<p class="text-sm mb-0 text-capitalize font-weight-bold">
<%- req?.locales?.index?.feeds[i] || stats.title %></p>
<h5 class="font-weight-bolder mb-0">
<%- stats.getValue %>
</h5>
</div>
<% if(stats.progressBar && stats.progressBar.enabled){ %>
<div class="progress w-150" style="margin-top: 6px;">
<div style="width: <%= stats.progressBar.getProgress %>% !important"
aria-label="Progress Bar"
class="progress-bar bg-gradient-primary"
role="progressbar" aria-valuenow="80" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
<% } %>
</div>
<div class="col-4 text-end">
<div class="icon icon-shape bg-gradient-primary shadow text-center border-radius-md">
<i class="ni ni-<%= stats.icon %> text-lg opacity-10" aria-hidden="true"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<% i++ }); %>
</div>
<div class="row">
<div class="col-lg-12 mb-lg-0 mb-4">
<div class="card">
<div class="card-body p-3">
<div class="row">
<div class="col-lg-6">
<div class="d-flex flex-column h-100">
<p class="mb-1 pt-2 text-bold"><%- req?.locales?.index?.card?.category %></p>
<h5 class="font-weight-bolder"><%- req?.locales?.index?.card?.title %></h5>
<p><%- req?.locales?.index?.card?.description %></p>
<p class="mb-5"><%= req?.locales?.index?.card?.footer %></p>
<% if(themeConfig.index?.card?.link?.enabled) { %>
<a class="text-body text-sm font-weight-bold mb-0 icon-move-right mt-auto"
href="<%- themeConfig.index.card.link.url %>">
<%- req?.locales?.index?.card?.link?.text %>
<i class="fas fa-arrow-right text-sm ms-1" aria-hidden="true"></i>
</a>
<% } %>
</div>
</div>
<div class="col-lg-5 ms-auto text-center mt-5 mt-lg-0">
<div class="bg-gradient-primary border-radius-lg h-100"
style="background-image: url('<%= req?.locales?.index?.card?.image %>') !important; background-repeat: no-repeat; background-size: contain; background-position: center;">
<div class="position-relative d-flex align-items-center justify-content-center h-100"
style="min-height: 210px !important;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-7 mb-lg-0 mb-4">
<div class="card z-index-2">
<div class="card-body p-3">
<h5 class="font-weight-bolder"><%- req?.locales?.index?.feeds.title || "Feeds" %></h5>
<%- include('partials/feeds.ejs', {require, admin:false}) %>
</div>
</div>
</div>
<div class="col-lg-5 mb-4">
<% if(themeConfig.index?.graph?.enabled) { %>
<div class="card z-index-2">
<div class="card-body p-3">
<h5 class="font-weight-bolder"><%- req?.locales?.index?.graph?.title %></h5>
<% if(themeConfig.index.graph.lineGraph) { %>
<div class="bg-gradient-dark border-radius-lg py-3 pe-1 mb-3">
<% } %>
<div class="chart">
<% if(!themeConfig.index.graph.lineGraph) { %>
<canvas id="chart-line" class="chart-canvas" height="300"></canvas>
<% } else { %>
<canvas id="chart-bars" class="chart-canvas" height="170"></canvas>
<% } %>
</div>
<% if(themeConfig.index.graph.lineGraph) { %>
</div>
<% } %>
</div>
</div>
</div>
</div>
<% } %>
</div>
<%- include('partials/footer.ejs') %>
</div>
</div>
</main>

View file

@ -1,140 +1,140 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/soft-ui-dashboard.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Alatsi">
<link rel="stylesheet" href="/css/nucleo-icons.css">
<link rel="stylesheet" href="/css/nucleo-svg.css">
<link rel="stylesheet" href="/css/soft-ui-dashboard.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@4/dark.css">
<link rel="stylesheet" href="/css/jquery-ui.css">
<%- include('partials/colorscheme.ejs') %>
<title><%= themeConfig.websiteName %> - Loading</title>
<% if(req.cookies?.selectedTheme == "dark" || req.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %>
<link href="/css/darkMode.css" rel='stylesheet'
<% if(req?.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %>
media="(prefers-color-scheme: dark)"
<% } %>
>
<% } %>
<%- themeConfig?.customHtml %>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/soft-ui-dashboard.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Alatsi">
<link rel="stylesheet" href="/css/nucleo-icons.css">
<link rel="stylesheet" href="/css/nucleo-svg.css">
<link rel="stylesheet" href="/css/soft-ui-dashboard.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@4/dark.css">
<link rel="stylesheet" href="/css/jquery-ui.css">
<%- include('partials/colorscheme.ejs') %>
<title><%= themeConfig.websiteName %> - Loading</title>
<% if(req.cookies?.selectedTheme == "dark" || req.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %>
<link href="/css/darkMode.css" rel='stylesheet'
<% if(req?.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %>
media="(prefers-color-scheme: dark)"
<% } %>
>
<% } %>
<%- themeConfig?.customHtml %>
</head>
<body>
<style>
@media all and (min-width: 0px) and (max-width: 600px) {
.responsive {
width: calc(100vw - 30px)
}
}
@media all and (min-width: 0px) and (max-width: 600px) {
.responsive {
width: calc(100vw - 30px)
}
}
@media all and (min-width: 0px) and (max-width: 590px) {
.responsive {
margin-top: calc(100vh / 4) !important;
}
}
@media all and (min-width: 0px) and (max-width: 590px) {
.responsive {
margin-top: calc(100vh / 4) !important;
}
}
.preloader {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100vh;
z-index: 99999999;
background-repeat: no-repeat;
background-image: none;
background-color: #FFF;
background-position: center;
}
.preloader {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100vh;
z-index: 99999999;
background-repeat: no-repeat;
background-image: none;
background-color: #FFF;
background-position: center;
}
#scroll {
height: 100% !important;
/* overflow: hidden; */
}
#scroll {
height: 100% !important;
/* overflow: hidden; */
}
.progress-bar {
transition: width 1s ease !important;
}
.progress-bar {
transition: width 1s ease !important;
}
</style>
<div class="preloader">
<div class="progress-wrapper">
<div id="progress-bar" class="progress">
<div id="progress" class="progress-bar bg-gradient-primary" role="progressbar" aria-valuenow="60"
aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
</div>
</div>
<% if(themeConfig.preloader){ %>
<% if(themeConfig.preloader.image) { %>
<% if(!themeConfig.preloader.spinner) { %>
<div class="loader">
<img class="responsive preloader-image" src="<%- themeConfig.preloader.image %>" alt=""
style="border-radius: 5%; display: block; margin-left: auto; margin-right: auto; margin-top: calc(100vh / 5.8);">
</div>
<% } %>
<% } %>
<% if(themeConfig.preloader.text){ %>
<br>
<div style="text-align: center;<% if(themeConfig.preloader.spinner) { %>margin-top: calc(100vh / 2.7);<% } %>">
<h1 class="font-weight-bolder text-primary text-gradient"><span id="stateText">Loading...</span></h1>
<% if(themeConfig.preloader.spinner) { %>
<div class="progress-wrapper">
<div id="progress-bar" class="progress">
<div id="progress" class="progress-bar bg-gradient-primary" role="progressbar" aria-valuenow="60"
aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
</div>
</div>
<% if(themeConfig.preloader){ %>
<% if(themeConfig.preloader.image) { %>
<% if(!themeConfig.preloader.spinner) { %>
<div class="loader">
<img class="responsive preloader-image" src="<%- themeConfig.preloader.image %>" alt=""
style="border-radius: 5%; display: block; margin-left: auto; margin-right: auto; margin-top: calc(100vh / 5.8);">
</div>
<% } %>
<% } %>
<% if(themeConfig.preloader.text){ %>
<br>
<div style="text-align: center;<% if(themeConfig.preloader.spinner) { %>margin-top: calc(100vh / 2.7);<% } %>">
<h1 class="font-weight-bolder text-primary text-gradient"><span id="stateText">Loading...</span></h1>
<% if(themeConfig.preloader.spinner) { %>
<div style="transform: scale(3); padding-top: 30px;">
<div style="text-align: center; " class="spinner-border text-primary text-gradient"
role="status">
<span class="visually-hidden">Loading...</span>
</div>
<span id="stateText"></span>
</div>
<% } %>
</div>
<% } %>
<% } %>
<div style="transform: scale(3); padding-top: 30px;">
<div style="text-align: center; " class="spinner-border text-primary text-gradient"
role="status">
<span class="visually-hidden">Loading...</span>
</div>
<span id="stateText"></span>
</div>
<% } %>
</div>
<% } %>
<% } %>
</div>
<script>
<% if (req.session.user) { %>
window.onload = function () {
window.close()
}
<% } %>
let i = 0;
const reFetch = async () => {
const res = await fetch('/discord/status/');
const json = await res.json();
if (json.loading == false && json.success == true) {
location.href = '<%= `${req.session.r}?swal=logged` || `/?swal=logged` %>';
} else if (json.loading == false && json.success == false) {
location.href = '/?error=' + json.state.error;
}
if (json.loading == false && json.success == true) {
<% if (req.session.r == "/manage") { %>
location.href = '<%= `${req.session.r}?swal=logged` || `/?swal=logged` %>';
<% } else { %>
window.close();
<% } %>
document.getElementById('progress').style.width = 100 + '%';
return;
}
;
if (json.loading == true) {
document.getElementById('stateText').innerHTML = json.state.data;
document.getElementById('progress').style.width = i + '%';
if (i > 100) {
document.getElementById('stateText').innerHTML = "Finishing up...";
}
i = i + 10;
} else if (json.loading == false && json.success == false) {
location.href = '/?error=' + json.state.error;
}
;
}
setInterval(() => {
reFetch()
}, 300);
<% if (req.session.user) { %>
window.onload = function () {
window.close()
}
<% } %>
let i = 0;
const reFetch = async () => {
const res = await fetch('/discord/status/');
const json = await res.json();
if (json.loading == false && json.success == true) {
location.href = '<%= `${req.session.r}?swal=logged` || `/?swal=logged` %>';
} else if (json.loading == false && json.success == false) {
location.href = '/?error=' + json.state.error;
}
if (json.loading == false && json.success == true) {
<% if (req.session.r == "/manage") { %>
location.href = '<%= `${req.session.r}?swal=logged` || `/?swal=logged` %>';
<% } else { %>
window.close();
<% } %>
document.getElementById('progress').style.width = 100 + '%';
return;
}
;
if (json.loading == true) {
document.getElementById('stateText').innerHTML = json.state.data;
document.getElementById('progress').style.width = i + '%';
if (i > 100) {
document.getElementById('stateText').innerHTML = "Finishing up...";
}
i = i + 10;
} else if (json.loading == false && json.success == false) {
location.href = '/?error=' + json.state.error;
}
;
}
setInterval(() => {
reFetch()
}, 300);
</script>
</body>
</html>

View file

@ -1,167 +1,154 @@
<!--
=========================================================
* Soft UI Design System - v1.0.5
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-design-system
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -->
<%
let logged = `<a id="login" onclick="auth()" class="btn btn-sm bg-gradient-primary btn-round mb-0 me-1 mt-2 mt-md-0">Login</a>`;
if (loggedIn) logged = '<a href="/discord/logout" class="btn btn-sm bg-gradient-primary btn-round mb-0 me-1 mt-2 mt-md-0">Logout</a>';
let title,
contentTitle,
texts;
contentTitle,
texts;
if (defaultMaintenanceConfig !== {}) {
title = defaultMaintenanceConfig.title;
contentTitle = defaultMaintenanceConfig.contentTitle;
texts = defaultMaintenanceConfig.texts;
if (!texts) texts = [];
title = defaultMaintenanceConfig.title;
contentTitle = defaultMaintenanceConfig.contentTitle;
texts = defaultMaintenanceConfig.texts;
if (!texts) texts = [];
}
%>
<!DOCTYPE html>
<html lang="en" itemscope itemtype="http://schema.org/WebPage">
<head>
<%- include('partials/preloader.ejs', {now: 'maintenance'}) %>
<%- include('partials/colorscheme.ejs') %>
<style>
.blur.blur-rounded {
border-radius: 17px;
}
<%- include('partials/preloader.ejs', {now: 'maintenance'}) %>
<%- include('partials/colorscheme.ejs') %>
<style>
.blur.blur-rounded {
border-radius: 17px;
}
a.btn.btn-sm.bg-gradient-primary.btn-round.mb-0.me-1.mt-2.mt-md-0 {
margin-top: auto !important;
margin-bottom: auto !important;
}
</style>
<script>
function auth() {
<% if (!req.session.user) { %>
const newWindow = window.open('/discord?r=/close%3Flogin=true', 'Log in with discord', `directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width=500, height=800`);
newWindow.focus();
a.btn.btn-sm.bg-gradient-primary.btn-round.mb-0.me-1.mt-2.mt-md-0 {
margin-top: auto !important;
margin-bottom: auto !important;
}
</style>
<script>
function auth() {
<% if (!req.session.user) { %>
const newWindow = window.open('/discord?r=/close%3Flogin=true', 'Log in with discord', `directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width=500, height=800`);
newWindow.focus();
setInterval(() => {
if (newWindow.closed) window.location.href = `<%= req.originalUrl%>?swal=logged`
}, 500);
<% } else { %>
window.location.href = `<%= req.originalUrl%>?swal=logged`
<% } %>
}
</script>
<%- themeConfig?.customHtml %>
setInterval(() => {
if (newWindow.closed) window.location.href = `<%= req.originalUrl%>?swal=logged`
}, 500);
<% } else { %>
window.location.href = `<%= req.originalUrl%>?swal=logged`
<% } %>
}
</script>
<%- themeConfig?.customHtml %>
</head>
<body class="presentation-page">
<%- include('partials/preload.ejs') %>
<!-- Navbar -->
<div class="container position-sticky z-index-sticky top-0">
<div class="row">
<div class="col-12">
<nav class="maintenance navbar navbar-expand-lg blur blur-rounded top-0 z-index-fixed shadow position-absolute my-3 py-2 start-0 end-0 mx-4">
<div class="container-fluid px-0" style="flex-wrap: unset;">
<a class="navbar-brand font-weight-bolder ms-sm-3" href="/">
<img src="<%- themeConfig.icons.favicon %>" class="h-100"
style="border-radius: 50%; width:40px;" alt="main_logo">
<a style="margin-top: auto !important; margin-bottom: auto !important; font-weight: 800;"><%- themeConfig.websiteName %></a>
</a>
<ul class="navbar-nav navbar-nav-hover ms-lg-12 ps-lg-5 w-100" style="flex-direction: row-reverse;">
<li class="nav navbar-nav navbar-right">
<%- logged %>
</li>
</ul>
</div>
</nav>
<!-- End Navbar -->
</div>
</div>
<div class="row">
<div class="col-12">
<nav class="maintenance navbar navbar-expand-lg blur blur-rounded top-0 z-index-fixed shadow position-absolute my-3 py-2 start-0 end-0 mx-4">
<div class="container-fluid px-0" style="flex-wrap: unset;">
<a class="navbar-brand font-weight-bolder ms-sm-3" href="/">
<img src="<%- themeConfig.icons.favicon %>" class="h-100"
style="border-radius: 50%; width:40px;" alt="main_logo">
<a style="margin-top: auto !important; margin-bottom: auto !important; font-weight: 800;"><%- themeConfig.websiteName %></a>
</a>
<ul class="navbar-nav navbar-nav-hover ms-lg-12 ps-lg-5 w-100" style="flex-direction: row-reverse;">
<li class="nav navbar-nav navbar-right">
<%- logged %>
</li>
</ul>
</div>
</nav>
<!-- End Navbar -->
</div>
</div>
</div>
<header class="header-2">
<%
const images = ["curved-1", "curved-2", "curved-3", "curved-4", "curved-5", "curved-6", "curved-7", "curved-8", "curved-9", "curved-10", "curved-11", "curved-12", "curved-13", "curved-14", "curved-15", "curved-16", "curved-17", "curved-18"];
<%
const images = ["curved-1", "curved-2", "curved-3", "curved-4", "curved-5", "curved-6", "curved-7", "curved-8", "curved-9", "curved-10", "curved-11", "curved-12", "curved-13", "curved-14", "curved-15", "curved-16", "curved-17", "curved-18"];
const image = images[Math.floor(Math.random() * images.length)];
%>
<div id="background" class="page-header min-vh-75 relative"
style="background-image: url('/img/curved-images/<%- image %>.webp');">
<span class="mask bg-gradient-primary opacity-6"></span>
<div class="container" style="margin-top: 10vh">
<div class="row">
<div class="col-lg-7 text-center mx-auto">
<h1 class="text-white pt-3 mt-n5"><%- contentTitle %></h1>
<p class="lead text-white mt-3">
<%- texts.map(text => '<p class="text-white">' + text + '</p>').join('') %>
</p>
</div>
</div>
</div>
<div class="position-absolute w-100 z-index-1 bottom-0">
<svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 24 150 40" preserveAspectRatio="none" shape-rendering="auto">
<defs>
<path id="gentle-wave"
d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"/>
</defs>
<g class="moving-waves">
<use class="dark-wave-1" xlink:href="#gentle-wave" x="48" y="-1" fill="rgba(255,255,255,0.40"/>
<use class="dark-wave-2" xlink:href="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.35)"/>
<use class="dark-wave-3" xlink:href="#gentle-wave" x="48" y="5" fill="rgba(255,255,255,0.25)"/>
<use class="dark-wave-4" xlink:href="#gentle-wave" x="48" y="8" fill="rgba(255,255,255,0.20)"/>
<use class="dark-wave-5" xlink:href="#gentle-wave" x="48" y="13" fill="rgba(255,255,255,0.15)"/>
<use class="dark-wave-6" xlink:href="#gentle-wave" x="48" y="16" fill="rgba(255,255,255,0.95"/>
</g>
</svg>
</div>
</div>
const image = images[Math.floor(Math.random() * images.length)];
%>
<div id="background" class="page-header min-vh-75 relative"
style="background-image: url('/img/curved-images/<%- image %>.webp');">
<span class="mask bg-gradient-primary opacity-6"></span>
<div class="container" style="margin-top: 10vh">
<div class="row">
<div class="col-lg-7 text-center mx-auto">
<h1 class="text-white pt-3 mt-n5"><%- contentTitle %></h1>
<p class="lead text-white mt-3">
<%- texts.map(text => '<p class="text-white">' + text + '</p>').join('') %>
</p>
</div>
</div>
</div>
<div class="position-absolute w-100 z-index-1 bottom-0">
<svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 24 150 40" preserveAspectRatio="none" shape-rendering="auto">
<defs>
<path id="gentle-wave"
d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"/>
</defs>
<g class="moving-waves">
<use class="dark-wave-1" xlink:href="#gentle-wave" x="48" y="-1" fill="rgba(255,255,255,0.40"/>
<use class="dark-wave-2" xlink:href="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.35)"/>
<use class="dark-wave-3" xlink:href="#gentle-wave" x="48" y="5" fill="rgba(255,255,255,0.25)"/>
<use class="dark-wave-4" xlink:href="#gentle-wave" x="48" y="8" fill="rgba(255,255,255,0.20)"/>
<use class="dark-wave-5" xlink:href="#gentle-wave" x="48" y="13" fill="rgba(255,255,255,0.15)"/>
<use class="dark-wave-6" xlink:href="#gentle-wave" x="48" y="16" fill="rgba(255,255,255,0.95"/>
</g>
</svg>
</div>
</div>
</header>
<% if(defaultMaintenanceConfig.infoCards){ %>
<section class="pt-4 pb-5 info-maintenance" id="count-stats" style="padding-top: 7rem !important;">
<div class="container">
<div class="row">
<div style="box-shadow: none !important;"
class="maintenance info col-lg-9 z-index-2 border-radius-xl mt-n10 mx-auto py-4 blur shadow-blur">
<div class="row">
<% let c = 1; defaultMaintenanceConfig.infoCards.forEach(card => { %>
<div class="col-md-4 position-relative">
<div class="p-3 text-center">
<% if(card.title){ %><h1 class="text-gradient text-primary">
<span><%- card.title %></span></h1>
<% } %>
<% if(card.subtitle){ %><h5 class="mt-3"><%- card.subtitle %></h5>
<% } %>
<% if(card.description){ %><p class="text-sm"><%- card.description %></p>
<% } %>
</div>
<% c++; if(c != 4) { %>
<hr class="vertical dark">
<% } %>
</div>
<% }) %>
<section class="pt-4 pb-5 info-maintenance" id="count-stats" style="padding-top: 7rem !important;">
<div class="container">
<div class="row">
<div style="box-shadow: none !important;"
class="maintenance info col-lg-9 z-index-2 border-radius-xl mt-n10 mx-auto py-4 blur shadow-blur">
<div class="row">
<% let c = 1; defaultMaintenanceConfig.infoCards.forEach(card => { %>
<div class="col-md-4 position-relative">
<div class="p-3 text-center">
<% if(card.title){ %><h1 class="text-gradient text-primary">
<span><%- card.title %></span></h1>
<% } %>
<% if(card.subtitle){ %><h5 class="mt-3"><%- card.subtitle %></h5>
<% } %>
<% if(card.description){ %><p class="text-sm"><%- card.description %></p>
<% } %>
</div>
<% c++; if(c != 4) { %>
<hr class="vertical dark">
<% } %>
</div>
<% }) %>
<!-- <div class="col-md-4 position-relative">
<div class="p-3 text-center">
<h1 class="text-gradient text-primary"> <span id="state2" countTo="15">0</span>+</h1>
<h5 class="mt-3">Design Blocks</h5>
<p class="text-sm">Mix the sections, change the colors and unleash your creativity</p>
</div>
<hr class="vertical dark">
</div>
<div class="col-md-4">
<div class="p-3 text-center">
<h1 class="text-gradient text-primary" id="state3" countTo="4">0</h1>
<h5 class="mt-3">Pages</h5>
<p class="text-sm">Save 3-4 weeks of work when you use our pre-made pages for your website</p>
</div>
</div> -->
</div>
</div>
</div>
</div>
</section>
<!-- <div class="col-md-4 position-relative">
<div class="p-3 text-center">
<h1 class="text-gradient text-primary"> <span id="state2" countTo="15">0</span>+</h1>
<h5 class="mt-3">Design Blocks</h5>
<p class="text-sm">Mix the sections, change the colors and unleash your creativity</p>
</div>
<hr class="vertical dark">
</div>
<div class="col-md-4">
<div class="p-3 text-center">
<h1 class="text-gradient text-primary" id="state3" countTo="4">0</h1>
<h5 class="mt-3">Pages</h5>
<p class="text-sm">Save 3-4 weeks of work when you use our pre-made pages for your website</p>
</div>
</div> -->
</div>
</div>
</div>
</div>
</section>
<% } %>
<!-- Core JS Files -->

View file

@ -1,202 +1,202 @@
<html>
<head>
<link href="/types/styles.css" rel="stylesheet"/>
<script src="/types/code.js"></script>
<link rel="stylesheet" href="/testcdn/f47b986ff7b093031dc7.css">
<link rel="stylesheet" href="/testcdn/guild.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<link href="/types/styles.css" rel="stylesheet"/>
<script src="/types/code.js"></script>
<link rel="stylesheet" href="/testcdn/f47b986ff7b093031dc7.css">
<link rel="stylesheet" href="/testcdn/guild.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
</head>
<body class="gui emptyContent emptyEmbed">
<button class="emojipicker">Emoji picker</button>
<hr>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
</div>
<p>Slider is set to <b><span id="val"></span></b></p>
<hr>
<select id="channelSelect">
<optgroup label="Category Name">
<option value="54321">general</option>
<option value="12345">commands</option>
</optgroup>
<optgroup label="Category Name">
<option value="54321">general</option>
<option value="12345">commands</option>
</optgroup>
</select>
<hr>
<div style="max-width: 640px;"><input type="number" value="0"></div>
<hr>
<label class="f76c">
<input type="checkbox" checked="">
<span class="_3319"></span>Checkbox
<input type="checkbox" checked="">
<span class="_3319"></span>Checkbox
</label>
<hr>
<div class="c945" style="width: 90%; margin: 5rem;">
<h2>Message content</h2>
<hr>
<div class="a437">
<div class="e91f">
<input type="text" placeholder="Message Content">
</div>
<div class="f039" style="border-left-color: rgb(134, 194, 50);">
<div class="_221e"></div>
<div class="_8d09">
<div class="e91f">
<input type="text" placeholder="Embed Author">
</div>
</div>
<div class="_4956">
<div class="e91f">
<input type="text" placeholder="Title" value="New User! :D">
</div>
</div>
<div class="_9c2a">
<div class="e91f">
<input type="text" placeholder="Description" value="Embed Description">
</div>
</div>
<div class="_3594">
<div class="e91f">
<input type="text" placeholder="Footer Text" value="Look ma, this is a footer!">
</div>
</div>
</div>
</div>
<br>
<div><label class="f76c"><input type="checkbox" checked=""><span class="_3319"></span>Show embed</label></div>
<div style="width: 1px; height: 5px;"></div>
<div><label class="f76c"><input type="checkbox"><span class="_3319"></span>Show welcoming image</label></div>
<h2>Message content</h2>
<hr>
<div class="a437">
<div class="e91f">
<input type="text" placeholder="Message Content">
</div>
<div class="f039" style="border-left-color: rgb(134, 194, 50);">
<div class="_221e"></div>
<div class="_8d09">
<div class="e91f">
<input type="text" placeholder="Embed Author">
</div>
</div>
<div class="_4956">
<div class="e91f">
<input type="text" placeholder="Title" value="New User! :D">
</div>
</div>
<div class="_9c2a">
<div class="e91f">
<input type="text" placeholder="Description" value="Embed Description">
</div>
</div>
<div class="_3594">
<div class="e91f">
<input type="text" placeholder="Footer Text" value="Look ma, this is a footer!">
</div>
</div>
</div>
</div>
<br>
<div><label class="f76c"><input type="checkbox" checked=""><span class="_3319"></span>Show embed</label></div>
<div style="width: 1px; height: 5px;"></div>
<div><label class="f76c"><input type="checkbox"><span class="_3319"></span>Show welcoming image</label></div>
</div>
<script>
/* -- ON SLIDER CHANGE, UPDATE PREVIEW COUNTER -- */
var slider = document.getElementById("myRange");
var output = document.getElementById("val");
output.innerHTML = slider.value;
/* -- ON SLIDER CHANGE, UPDATE PREVIEW COUNTER -- */
var slider = document.getElementById("myRange");
var output = document.getElementById("val");
output.innerHTML = slider.value;
slider.oninput = function () {
output.innerHTML = this.value;
}
slider.oninput = function () {
output.innerHTML = this.value;
}
/* -- -- */
function formatState(state) {
if (!state.id) {
return state.text;
}
var $state = $(
`<span>#${state.text}</span>`
);
return $state;
}
/* -- -- */
function formatState(state) {
if (!state.id) {
return state.text;
}
var $state = $(
`<span>#${state.text}</span>`
);
return $state;
}
$("#channelSelect").select2({
templateResult: formatState
});
$("#channelSelect").select2({
templateResult: formatState
});
new EmojiPicker({
trigger: [
{
selector: '.emojipicker'
}
],
closeButton: true
});
new EmojiPicker({
trigger: [
{
selector: '.emojipicker'
}
],
closeButton: true
});
</script>
<hr>
<div class="c945" style="width: 90%; margin: 5rem;">
<h2>Items</h2>
<h3>Manage your shop. Add, edit or remove items.</h3>
<hr>
<div class="_2242">
<span>
<div class="_46a4">Item</div>
</span>
<div class="_46a4 _34a1"><i class="fa fa-plus">+</i></div>
</div>
<h2>Items</h2>
<h3>Manage your shop. Add, edit or remove items.</h3>
<hr>
<div class="_2242">
<span>
<div class="_46a4">Item</div>
</span>
<div class="_46a4 _34a1"><i class="fa fa-plus">+</i></div>
</div>
</div>
<div class="c945" style="width: 90%; margin: 5rem;">
<script>
function myFunction(type) {
var x = document.getElementById(`${type}input`).value;
document.getElementById(type).innerHTML = x;
}
<script>
function myFunction(type) {
var x = document.getElementById(`${type}input`).value;
document.getElementById(type).innerHTML = x;
}
function setHref(item) {
var a = document.getElementById(item); //or grab it by tagname etc
var x = document.getElementById("authorurlinput").value;
a.href = x
}
</script>
<div class="row">
<div class="col-12 col-sm-6">
<h2>Currency</h2>
<h3>Set a custom currency symbol.</h3>
<hr>
<div>
<div class="row" style="display: flex;">
<div class="col-sm" style="width: 30%;">
<p>Basic Settings</p>
<div style="max-width: 270px;">
<input id="titleinput" style="margin-top: 10px;" type="text" placeholder="Title"
onkeyup="myFunction('title')">
<input id="descriptioninput" style="margin-top: 10px;" type="text" placeholder="Description"
onkeyup="myFunction('description')">
<input id="" style="margin-top: 10px;" type="text" placeholder="Url">
</div>
<br>
<label class="f76c">
<input type="checkbox">
<span class="_3319">
</span>Wallet enabled
</label>
</div>
<div class="col-sm" style="width: 30%;">
<p>Author settings</p>
<div style="max-width: 270px;">
<input id="authorinput" style="margin-top: 10px;" type="text" placeholder="Author Name"
onkeyup="myFunction('author')">
<input id="authorurlinput" style="margin-top: 10px;" type="text" placeholder="Author Link"
onkeyup="setHref('author')">
<input id="" style="margin-top: 10px;" type="text" placeholder="Author Icon">
</div>
<br>
<label class="f76c">
<input type="checkbox">
<span class="_3319">
</span>Wallet enabled
</label>
</div>
<div class="co-sm" style="width: 40%;">
<div class="">
<div class="bce7">
<div class="fcd5">
<div class="_25cb" style="font-size: 1.3rem;"><a id="author"></a></div>
<div id="title" class="_25cb">Server's store</div>
<div id="description" class="_03aa">You have <b>10$</b> in your bank.</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="row" style="display: flex;">
<div class="col-sm" style="width: 30%;">
<p>Fields</p>
<div style="max-width: 270px;">
<input style="margin-top: 10px;" type="text" placeholder="Title">
<input style="margin-top: 10px;" type="text" placeholder="Description">
<input style="margin-top: 10px;" type="text" placeholder="Url">
</div>
<br>
<label class="f76c">
<input type="checkbox">
<span class="_3319">
</span>Wallet enabled
</label>
</div>
</div>
</div>
</div>
</div>
function setHref(item) {
var a = document.getElementById(item); //or grab it by tagname etc
var x = document.getElementById("authorurlinput").value;
a.href = x
}
</script>
<div class="row">
<div class="col-12 col-sm-6">
<h2>Currency</h2>
<h3>Set a custom currency symbol.</h3>
<hr>
<div>
<div class="row" style="display: flex;">
<div class="col-sm" style="width: 30%;">
<p>Basic Settings</p>
<div style="max-width: 270px;">
<input id="titleinput" style="margin-top: 10px;" type="text" placeholder="Title"
onkeyup="myFunction('title')">
<input id="descriptioninput" style="margin-top: 10px;" type="text" placeholder="Description"
onkeyup="myFunction('description')">
<input id="" style="margin-top: 10px;" type="text" placeholder="Url">
</div>
<br>
<label class="f76c">
<input type="checkbox">
<span class="_3319">
</span>Wallet enabled
</label>
</div>
<div class="col-sm" style="width: 30%;">
<p>Author settings</p>
<div style="max-width: 270px;">
<input id="authorinput" style="margin-top: 10px;" type="text" placeholder="Author Name"
onkeyup="myFunction('author')">
<input id="authorurlinput" style="margin-top: 10px;" type="text" placeholder="Author Link"
onkeyup="setHref('author')">
<input id="" style="margin-top: 10px;" type="text" placeholder="Author Icon">
</div>
<br>
<label class="f76c">
<input type="checkbox">
<span class="_3319">
</span>Wallet enabled
</label>
</div>
<div class="co-sm" style="width: 40%;">
<div class="">
<div class="bce7">
<div class="fcd5">
<div class="_25cb" style="font-size: 1.3rem;"><a id="author"></a></div>
<div id="title" class="_25cb">Server's store</div>
<div id="description" class="_03aa">You have <b>10$</b> in your bank.</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="row" style="display: flex;">
<div class="col-sm" style="width: 30%;">
<p>Fields</p>
<div style="max-width: 270px;">
<input style="margin-top: 10px;" type="text" placeholder="Title">
<input style="margin-top: 10px;" type="text" placeholder="Description">
<input style="margin-top: 10px;" type="text" placeholder="Url">
</div>
<br>
<label class="f76c">
<input type="checkbox">
<span class="_3319">
</span>Wallet enabled
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<%- include('partials/scripts.ejs') %>
</body>

View file

@ -1,187 +1,194 @@
<%
let currentScheme = themeConfig.colorScheme,
currentCode = "310deg, #7928CA 0%, #FF0080 100%",
colone,
coltwo;
currentCode = "310deg, #7928CA 0%, #FF0080 100%",
colone,
coltwo;
if (currentScheme == "pink") {
currentCode = "310deg, #7928CA 0%, #FF0080 100%";
colone = "#FF0080";
coltwo = "#7928CA";
currentCode = "310deg, #7928CA 0%, #FF0080 100%";
colone = "#FF0080";
coltwo = "#7928CA";
}
if (currentScheme == "red") {
currentCode = "310deg, #ea0606 0%, #ff667c 100%";
colone = "#ea0606";
coltwo = "#ff667c";
currentCode = "310deg, #ea0606 0%, #ff667c 100%";
colone = "#ea0606";
coltwo = "#ff667c";
}
if (currentScheme == "green") {
currentCode = "310deg, #17ad37 0%, #98ec2d 100%";
colone = "#17ad37";
coltwo = "#98ec2d";
currentCode = "310deg, #17ad37 0%, #98ec2d 100%";
colone = "#17ad37";
coltwo = "#98ec2d";
}
if (currentScheme == "yellow") {
currentCode = "310deg, #f53939 0%, #fbcf33 100%";
colone = "#f53939";
coltwo = "#fbcf33";
currentCode = "310deg, #f53939 0%, #fbcf33 100%";
colone = "#f53939";
coltwo = "#fbcf33";
}
if (currentScheme == "dark") {
currentCode = "310deg, #141727 0%, #3A416F 100%";
colone = "#141727";
coltwo = "#3A416F";
currentCode = "310deg, #141727 0%, #3A416F 100%";
colone = "#141727";
coltwo = "#3A416F";
}
if (currentScheme == "blue") {
currentCode = "310deg, #2152ff 0%, #21d4fd 100%";
colone = "#2152ff";
coltwo = "#21d4fd";
currentCode = "310deg, #2152ff 0%, #21d4fd 100%";
colone = "#2152ff";
coltwo = "#21d4fd";
}
if (currentScheme == "custom") {
if (!themeConfig.themeColors || !themeConfig.themeColors.primaryColor || !themeConfig.themeColors.secondaryColor) {
currentCode = "310deg, #7928CA 0%, #FF0080 100%";
colone = "#FF0080";
coltwo = "#7928CA";
} else {
currentCode = "310deg, " + themeConfig.themeColors.primaryColor + " 0%, " + themeConfig.themeColors.secondaryColor + " 100%";
colone = themeConfig.themeColors.primaryColor;
coltwo = themeConfig.themeColors.secondaryColor;
}
if (!themeConfig.themeColors || !themeConfig.themeColors.primaryColor || !themeConfig.themeColors.secondaryColor) {
currentCode = "310deg, #7928CA 0%, #FF0080 100%";
colone = "#FF0080";
coltwo = "#7928CA";
} else {
currentCode = "310deg, " + themeConfig.themeColors.primaryColor + " 0%, " + themeConfig.themeColors.secondaryColor + " 100%";
colone = themeConfig.themeColors.primaryColor;
coltwo = themeConfig.themeColors.secondaryColor;
}
}
%>
<meta name="theme-color" content="<%- colone %>">
<style>
:root {
--gradient: <%= currentCode%> !important;
--colone: <%= colone%> !important;
--coltwo: <%= coltwo%> !important;
}
:root {
--gradient: <%=currentCode%> !important;
--colone: <%=colone%> !important;
--coltwo: <%=coltwo%> !important;
}
input:checked + .tslider {
background: linear-gradient(var(--gradient)) !important;
}
input:checked+.tslider {
background: linear-gradient(var(--gradient)) !important;
}
option {
color: var(--colone);
}
option {
color: var(--colone);
}
option:hover {
background-color: none !important;
}
option:hover {
background-color: none !important;
}
.fixed-plugin .btn.bg-gradient-primary:not(:disabled):not(.disabled):not(.active) {
border: 1px solid var(--colone) !important;
color: var(--colone) !important;
}
.fixed-plugin .btn.bg-gradient-primary:not(:disabled):not(.disabled):not(.active) {
border: 1px solid var(--colone) !important;
color: var(--colone) !important;
}
.card.card-background.card-background-mask-primary::after, .swal2-popup.swal2-toast {
background-image: linear-gradient(var(--gradient)) !important;
}
.card.card-background.card-background-mask-primary::after,
.swal2-popup.swal2-toast {
background-image: linear-gradient(var(--gradient)) !important;
}
.form-switch .form-check-input:checked {
border-color: var(--colone) !important;
background-image: linear-gradient(var(--gradient)) !important;
}
.form-switch .form-check-input:checked {
border-color: var(--colone) !important;
background-image: linear-gradient(var(--gradient)) !important;
}
.swal2-title {
color: #ebdddd !important;
-webkit-font-smoothing: antialiased;
}
.swal2-title {
color: #ebdddd !important;
-webkit-font-smoothing: antialiased;
}
.swal2-success-fix, .swal2-success-circular-line-left, .swal2-success-circular-line-right {
background: none !important;
}
.swal2-success-fix,
.swal2-success-circular-line-left,
.swal2-success-circular-line-right {
background: none !important;
}
.swal2-success-ring {
color: rgba(0, 0, 0, 0) !important;
border: rgba(0, 0, 0, 0) !important;
}
.swal2-success-ring {
color: rgba(0, 0, 0, 0) !important;
border: rgba(0, 0, 0, 0) !important;
}
.swal2-icon.swal2-error, .swal2-icon.swal2-success {
border-color: #f9f9f9 !important;
color: #f9f9f9 !important;
}
.swal2-icon.swal2-error,
.swal2-icon.swal2-success {
border-color: #f9f9f9 !important;
color: #f9f9f9 !important;
}
.swal2-x-mark-line-right, .swal2-x-mark-line-left, .swal2-success-line-long, .swal2-success-line-tip {
background-color: #f9f9f9 !important;
}
.swal2-x-mark-line-right,
.swal2-x-mark-line-left,
.swal2-success-line-long,
.swal2-success-line-tip {
background-color: #f9f9f9 !important;
}
.swal2-success-fix {
color: white !important;
}
.swal2-success-fix {
color: white !important;
}
.swal2-icon.swal2-success [class^=swal2-success-line] {
display: block;
position: absolute;
z-index: 2;
height: 0.3125em;
border-radius: 0.125em;
background-color: var(#f9f9f9) !important;
}
.swal2-icon.swal2-success [class^=swal2-success-line] {
display: block;
position: absolute;
z-index: 2;
height: 0.3125em;
border-radius: 0.125em;
background-color: var(#f9f9f9) !important;
}
.bg-gradient-primary {
background-image: linear-gradient(var(--gradient));
}
.bg-gradient-primary {
background-image: linear-gradient(var(--gradient));
}
.card.card-background.card-background-mask-primary:after {
background-image: linear-gradient(var(--gradient));
opacity: .85;
}
.card.card-background.card-background-mask-primary:after {
background-image: linear-gradient(var(--gradient));
opacity: .85;
}
.navbar-vertical .navbar-nav > .nav-item .nav-link.active .icon {
background-image: linear-gradient(var(--gradient)) !important;
}
.navbar-vertical .navbar-nav>.nav-item .nav-link.active .icon {
background-image: linear-gradient(var(--gradient)) !important;
}
.text-gradient.text-primary {
background-image: linear-gradient(var(--gradient));
}
.text-gradient.text-primary {
background-image: linear-gradient(var(--gradient));
}
.btn-outline-primary {
color: var(--colone);
border-color: var(--colone);
}
.btn-outline-primary {
color: var(--colone);
border-color: var(--colone);
}
.nav-tabs .nav-link.active {
background-size: 100% 4px;
border-bottom: 4px solid var(--colone) !important;
color: var(--colone) !important;
}
.nav-tabs .nav-link.active {
background-size: 100% 4px;
border-bottom: 4px solid var(--colone) !important;
color: var(--colone) !important;
}
.nav-tabs .nav-link:hover {
border: 0;
border-bottom: 0px solid;
}
.nav-tabs .nav-link:hover {
border: 0;
border-bottom: 0px solid;
}
.pagination.pagination-primary .page-item.active > .page-link,
.pagination.pagination-primary .page-item.active > .page-link:focus,
.pagination.pagination-primary .page-item.active > .page-link:hover {
background-image: linear-gradient(var(--gradient));
border: none;
}
.pagination.pagination-primary .page-item.active>.page-link,
.pagination.pagination-primary .page-item.active>.page-link:focus,
.pagination.pagination-primary .page-item.active>.page-link:hover {
background-image: linear-gradient(var(--gradient));
border: none;
}
.sidenav[data-color="primary"] .navbar-nav > .nav-item > .nav-link.active .icon {
background-image: linear-gradient(var(--gradient));
}
.sidenav[data-color="primary"] .navbar-nav>.nav-item>.nav-link.active .icon {
background-image: linear-gradient(var(--gradient));
}
.blur-section.blur-gradient-primary {
background-image: linear-gradient(var(--gradient));
}
.blur-section.blur-gradient-primary {
background-image: linear-gradient(var(--gradient));
}
.blur-section.blur-gradient-primary {
background-image: linear-gradient(var(--gradient));
}
.blur-section.blur-gradient-primary {
background-image: linear-gradient(var(--gradient));
}
.form-control:focus {
box-shadow: var(--colone) 0px 0px 0px 2px !important;
}
.form-control:focus {
box-shadow: var(--colone) 0px 0px 0px 2px !important;
}
.input-group .form-control:focus {
border-color: var(--colone) !important;
}
.input-group .form-control:focus {
border-color: var(--colone) !important;
}
.themecol {
color: var(--colone) !important;
}
.themecol {
color: var(--colone) !important;
}
.input-group .form-control:focus {
border-left-color: var(--colone) !important;
border-right-color: var(--colone) !important;
}
.input-group .form-control:focus {
border-left-color: var(--colone) !important;
border-right-color: var(--colone) !important;
}
</style>

View file

@ -1,118 +1,118 @@
<div class="card-body px-0 pt-0 pb-2">
<div class="table-responsive p-0">
<%
let feeds = [];
<div class="table-responsive p-0">
<%
let feeds = [];
const db = require('quick.db');
const db = require('quick.db');
if (db.get('feeds.three')) {
const fd = db.get('feeds.three');
const fdata = {
color: fd.color,
description: fd.description,
icon: fd.icon,
published: fd.published,
diff: fd.diff,
feedNum: 3
}
feeds.push(fdata);
}
if (db.get('feeds.two')) {
const fd = db.get('feeds.two');
const fdata = {
color: fd.color,
description: fd.description,
icon: fd.icon,
published: fd.published,
diff: fd.diff,
feedNum: 2
}
feeds.push(fdata);
}
if (db.get('feeds.one')) {
const fd = db.get('feeds.one');
const fdata = {
color: fd.color,
description: fd.description,
published: fd.published,
icon: fd.icon,
diff: fd.diff,
feedNum: 1
}
feeds.push(fdata);
}
feeds.forEach(feed => {
if (db.get('feeds.three')) {
const fd = db.get('feeds.three');
const fdata = {
color: fd.color,
description: fd.description,
icon: fd.icon,
published: fd.published,
diff: fd.diff,
feedNum: 3
}
feeds.push(fdata);
}
if (db.get('feeds.two')) {
const fd = db.get('feeds.two');
const fdata = {
color: fd.color,
description: fd.description,
icon: fd.icon,
published: fd.published,
diff: fd.diff,
feedNum: 2
}
feeds.push(fdata);
}
if (db.get('feeds.one')) {
const fd = db.get('feeds.one');
const fdata = {
color: fd.color,
description: fd.description,
published: fd.published,
icon: fd.icon,
diff: fd.diff,
feedNum: 1
}
feeds.push(fdata);
}
feeds.forEach(feed => {
var delta = Math.abs(Date.now() - feed.published) / 1000;
var delta = Math.abs(Date.now() - feed.published) / 1000;
// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
delta -= days * 86400;
// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
delta -= days * 86400;
// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
delta -= hours * 3600;
// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
delta -= hours * 3600;
// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;
// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;
// what's left is seconds
var seconds = delta % 60; // in theory the modulus is not required
// what's left is seconds
var seconds = delta % 60; // in theory the modulus is not required
let dateString = `loading`;
let dateString = `loading`;
//stupid variable names but yeah :sweat_smile:
if (seconds < 2) secsingle = "second";
else secsingle = "seconds";
//stupid variable names but yeah :sweat_smile:
if (seconds < 2) secsingle = "second";
else secsingle = "seconds";
if (minutes < 2) minsingle = "minute";
else minsingle = "minutes";
if (minutes < 2) minsingle = "minute";
else minsingle = "minutes";
if (hours < 2) hrsingle = "hour";
else hrsingle = "hours";
if (hours < 2) hrsingle = "hour";
else hrsingle = "hours";
if (days < 2) daysingle = "day";
else daysingle = "days";
if (days < 2) daysingle = "day";
else daysingle = "days";
if (minutes < 1) dateString = `${Math.round(seconds)} ${secsingle} ago`;
else if (hours < 1) dateString = `${minutes} ${minsingle} ago`;
else if (days < 1) dateString = `${hours} ${hrsingle} ago`;
else dateString = `${days} ${daysingle} ago`;
let faString = "fas fa-";
if (feed.diff) faString = "fab fa-";
%>
<div>
<div class="alert alert-<%- feed.color %> text-white font-weight-bold" role="alert"
style="display: flex; margin-top: 20px;">
<div class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center gray-icon-bg"
style="margin: auto 0px; width: 30px !important; height: 30px !important;">
<i class="<%- faString %><%- feed.icon %> invert-img" style="font-size: 80%; color: black;"></i>
</div>
<span style="margin: auto 0px"><%- feed.description %></span>
<span class="tagnamecolor-date"
style="color:rgb(155, 148, 148); margin: auto 0px; font-size: 75%; flex: 1; text-align: right; white-space: nowrap;">
<%- dateString %>
</span>
<% if(admin) { %>
<div class="ms-auto text-end">
<a id="deleteFeed<%- feed.feedNum %>" class="btn btn-link text-text-gradient px-3 mb-0"
style="color:white;" href="javascript:"><i class="far fa-trash-alt me-2"></i>Delete</a>
</div>
<% } %>
</div>
</div>
<%
})
if(!feeds[0]) {
%>
<div>
<span class="tagnamecolor-date" style="color:rgb(155, 148, 148); white-space: nowrap;">
There are no feeds.
</span>
</div>
<%
}
%>
</div>
if (minutes < 1) dateString = `${Math.round(seconds)} ${secsingle} ago`;
else if (hours < 1) dateString = `${minutes} ${minsingle} ago`;
else if (days < 1) dateString = `${hours} ${hrsingle} ago`;
else dateString = `${days} ${daysingle} ago`;
let faString = "fas fa-";
if (feed.diff) faString = "fab fa-";
%>
<div>
<div class="alert alert-<%- feed.color %> text-white font-weight-bold" role="alert"
style="display: flex; margin-top: 20px;">
<div class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center gray-icon-bg"
style="margin: auto 0px; width: 30px !important; height: 30px !important;">
<i class="<%- faString %><%- feed.icon %> invert-img" style="font-size: 80%; color: black;"></i>
</div>
<span style="margin: auto 0px"><%- feed.description %></span>
<span class="tagnamecolor-date"
style="color:rgb(155, 148, 148); margin: auto 0px; font-size: 75%; flex: 1; text-align: right; white-space: nowrap;">
<%- dateString %>
</span>
<% if(admin) { %>
<div class="ms-auto text-end">
<a id="deleteFeed<%- feed.feedNum %>" class="btn btn-link text-text-gradient px-3 mb-0"
style="color:white;" href="javascript:"><i class="far fa-trash-alt me-2"></i>Delete</a>
</div>
<% } %>
</div>
</div>
<%
})
if(!feeds[0]) {
%>
<div>
<span class="tagnamecolor-date" style="color:rgb(155, 148, 148); white-space: nowrap;">
There are no feeds.
</span>
</div>
<%
}
%>
</div>
</div>

View file

@ -1,16 +1,20 @@
<footer class="footer">
<div class="container-fluid">
<div class="row align-items-center justify-content-lg-between">
<div class="col-lg-6 mb-lg-0 mb-4">
<div class="copyright text-center text-sm text-muted text-lg-start">
© <%= new Date().getFullYear() %>
<% if(themeConfig?.footer?.replaceDefault === true) { %>
<a href="/credits" class="font-weight-bold" target="_blank">Assistants</a><% if(themeConfig?.footer?.text?.length) { %> | <%= themeConfig?.footer?.text %> <% } %>
<% } else { %>
Made with <i class="fa fa-heart"></i> by <a href="/credits" class="font-weight-bold" target="_blank">PlainDevelopment</a> and <a href="/credits" class="font-weight-bold" target="_blank">iMidnight</a>
<% } %>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row align-items-center justify-content-lg-between">
<div class="col-lg-6 mb-lg-0 mb-4">
<div class="copyright text-center text-sm text-muted text-lg-start">
© <%= new Date().getFullYear() %>
<% if(themeConfig?.footer?.replaceDefault === true) { %>
<a href="/credits" class="font-weight-bold"
target="_blank">Assistants</a><% if(themeConfig?.footer?.text?.length) { %> |
<%= themeConfig?.footer?.text %> <% } %>
<% } else { %>
Made with <i class="fa fa-heart"></i> by <a href="/credits" class="font-weight-bold"
target="_blank">PlainDevelopment</a> and <a href="/credits" class="font-weight-bold"
target="_blank">Jonny_Bro</a>
<% } %>
</div>
</div>
</div>
</div>
</footer>

View file

@ -7,220 +7,220 @@ let gradone;
let gradtwo;
function hexToRgba(hex, alpha) {
var r = parseInt(hex.substring(1,3), 16);
var g = parseInt(hex.substring(3,5), 16);
var b = parseInt(hex.substring(5,7), 16);
var r = parseInt(hex.substring(1,3), 16);
var g = parseInt(hex.substring(3,5), 16);
var b = parseInt(hex.substring(5,7), 16);
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
}
if (currentScheme == "blue") {
colone = "#21d4fd";
coltwo = "#2152ff";
gradone = "rgba(33,212,253,0.1)";
gradtwo = "rgba(33,82,255,0.1)";
colone = "#21d4fd";
coltwo = "#2152ff";
gradone = "rgba(33,212,253,0.1)";
gradtwo = "rgba(33,82,255,0.1)";
}
if (currentScheme == "pink") {
colone = "#FF0080";
coltwo = "#7928CA";
gradone = "rgba(255,0,128,0.1)";
gradtwo = "rgba(121,40,202,0.1)";
colone = "#FF0080";
coltwo = "#7928CA";
gradone = "rgba(255,0,128,0.1)";
gradtwo = "rgba(121,40,202,0.1)";
}
if (currentScheme == "red") {
colone = "#ea0606";
coltwo = "#ff667c";
gradone = "rgba(255,102,124,0.1)";
gradtwo = "rgba(234,6,6,0.1)";
colone = "#ea0606";
coltwo = "#ff667c";
gradone = "rgba(255,102,124,0.1)";
gradtwo = "rgba(234,6,6,0.1)";
}
if (currentScheme == "green") {
colone = "#17ad37";
coltwo = "#98ec2d";
gradone = "rgba(23,173,55,0.1)";
gradtwo = "rgba(152,236,45,0.1)";
colone = "#17ad37";
coltwo = "#98ec2d";
gradone = "rgba(23,173,55,0.1)";
gradtwo = "rgba(152,236,45,0.1)";
}
if (currentScheme == "yellow") {
colone = "#f53939";
coltwo = "#fbcf33";
gradone = "rgba(245,57,57,0.1)";
gradtwo = "rgba(251,207,51,0.1)";
colone = "#f53939";
coltwo = "#fbcf33";
gradone = "rgba(245,57,57,0.1)";
gradtwo = "rgba(251,207,51,0.1)";
}
if (currentScheme == "dark") {
colone = "#141727";
coltwo = "#3A416F";
gradone = "rgba(20,23,39,0.1)";
gradtwo = "rgba(58,65,111,0.1)";
colone = "#141727";
coltwo = "#3A416F";
gradone = "rgba(20,23,39,0.1)";
gradtwo = "rgba(58,65,111,0.1)";
}
if (currentScheme == "custom") {
if (!themeConfig.themeColors || !themeConfig.themeColors.primaryColor || !themeConfig.themeColors.secondaryColor) {
currentCode = "310deg, #7928CA 0%, #FF0080 100%";
colone = "#FF0080";
coltwo = "#7928CA";
gradone = "rgba(255,0,128,0.1)";
gradtwo = "rgba(121,40,202,0.1)";
} else {
currentCode = "310deg, " + themeConfig.themeColors.primaryColor + " 0%, " + themeConfig.themeColors.secondaryColor + " 100%";
colone = themeConfig.themeColors.primaryColor;
coltwo = themeConfig.themeColors.secondaryColor;
gradone = hexToRgba(themeConfig.themeColors.primaryColor, 0.1);
gradtwo = hexToRgba(themeConfig.themeColors.secondaryColor, 0.1);
}
if (!themeConfig.themeColors || !themeConfig.themeColors.primaryColor || !themeConfig.themeColors.secondaryColor) {
currentCode = "310deg, #7928CA 0%, #FF0080 100%";
colone = "#FF0080";
coltwo = "#7928CA";
gradone = "rgba(255,0,128,0.1)";
gradtwo = "rgba(121,40,202,0.1)";
} else {
currentCode = "310deg, " + themeConfig.themeColors.primaryColor + " 0%, " + themeConfig.themeColors.secondaryColor + " 100%";
colone = themeConfig.themeColors.primaryColor;
coltwo = themeConfig.themeColors.secondaryColor;
gradone = hexToRgba(themeConfig.themeColors.primaryColor, 0.1);
gradtwo = hexToRgba(themeConfig.themeColors.secondaryColor, 0.1);
}
}
%>
<script>
<%
let graphType = "chart-bars"; // line-graph
if (!themeConfig.index.graph.lineGraph) graphType = "chart-line";
%>
let ctx = document.getElementById("<%- graphType %>").getContext("2d"); // line graph
<%
let graphType = "chart-bars"; // line-graph
if (!themeConfig.index.graph.lineGraph) graphType = "chart-line";
%>
let ctx = document.getElementById("<%- graphType %>").getContext("2d"); // line graph
<% if(graphType === "chart-bars") { %>
new Chart(ctx, {
type: "bar",
data: {
labels: <%- JSON.stringify(customThemeOptions.graph.labels) %>,
datasets: [{
label: "<%= themeConfig.index.graph.tag %>",
tension: 0.4,
borderWidth: 0,
borderRadius: 4,
borderSkipped: false,
backgroundColor: "#fff",
data: <%- JSON.stringify(data.values) %>,
maxBarThickness: 6
},],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
}
},
interaction: {
intersect: false,
mode: 'index',
},
scales: {
y: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false,
},
ticks: {
suggestedMin: 0,
suggestedMax: 500,
beginAtZero: true,
padding: 15,
font: {
size: 14,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
color: "#fff"
},
},
x: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false
},
ticks: {
display: false
},
},
},
},
});
<% } else { %>
<% if(graphType === "chart-bars") { %>
new Chart(ctx, {
type: "bar",
data: {
labels: <%- JSON.stringify(customThemeOptions.graph.labels) %>,
datasets: [{
label: "<%= themeConfig.index.graph.tag %>",
tension: 0.4,
borderWidth: 0,
borderRadius: 4,
borderSkipped: false,
backgroundColor: "#fff",
data: <%- JSON.stringify(data.values) %>,
maxBarThickness: 6
},],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
}
},
interaction: {
intersect: false,
mode: 'index',
},
scales: {
y: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false,
},
ticks: {
suggestedMin: 0,
suggestedMax: 500,
beginAtZero: true,
padding: 15,
font: {
size: 14,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
color: "#fff"
},
},
x: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false
},
ticks: {
display: false
},
},
},
},
});
<% } else { %>
var gradientStroke1 = ctx.createLinearGradient(0, 230, 0, 50);
var gradientStroke1 = ctx.createLinearGradient(0, 230, 0, 50);
gradientStroke1.addColorStop(1, '<%= colone %>');
gradientStroke1.addColorStop(0.1, '<%= gradone %>');
gradientStroke1.addColorStop(0, '<%= gradtwo %>'); //purple colors
gradientStroke1.addColorStop(1, '<%= colone %>');
gradientStroke1.addColorStop(0.1, '<%= gradone %>');
gradientStroke1.addColorStop(0, '<%= gradtwo %>'); //purple colors
new Chart(ctx, {
type: "line",
data: {
labels: <%- JSON.stringify(customThemeOptions.graph.labels) %>,
datasets: [{
label: "<%= themeConfig.index.graph.tag %>",
tension: 0.4,
borderWidth: 0,
pointRadius: 0,
borderColor: "<%- colone %>",
borderWidth: 3,
backgroundColor: gradientStroke1,
fill: true,
data: <%- JSON.stringify(data.values) %>,
maxBarThickness: 6
new Chart(ctx, {
type: "line",
data: {
labels: <%- JSON.stringify(customThemeOptions.graph.labels) %>,
datasets: [{
label: "<%= themeConfig.index.graph.tag %>",
tension: 0.4,
borderWidth: 0,
pointRadius: 0,
borderColor: "<%- colone %>",
borderWidth: 3,
backgroundColor: gradientStroke1,
fill: true,
data: <%- JSON.stringify(data.values) %>,
maxBarThickness: 6
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
}
},
interaction: {
intersect: false,
mode: 'index',
},
scales: {
y: {
suggestedMin: 0,
suggestedMax: <%- themeConfig.index.graph.max %>,
grid: {
drawBorder: false,
display: true,
drawOnChartArea: true,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
padding: 10,
color: '#b2b9bf',
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
x: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
color: '#b2b9bf',
padding: 20,
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
},
},
});
<% } %>
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
}
},
interaction: {
intersect: false,
mode: 'index',
},
scales: {
y: {
suggestedMin: 0,
suggestedMax: <%- themeConfig.index.graph.max %>,
grid: {
drawBorder: false,
display: true,
drawOnChartArea: true,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
padding: 10,
color: '#b2b9bf',
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
x: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
color: '#b2b9bf',
padding: 20,
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
},
},
});
<% } %>
</script>

View file

@ -1,22 +1,22 @@
<div id="bigIconsList" style="display: none;">
<% icons.forEach(async(icon) => { %>
<div style="text-align:center;width:15%;float: left;padding-right:10px;">
<div class="icon-shape icon-sm shadow border-radius-md bg-white gray-icon-bg" style="margin: 0 auto">
<i class="fas fa-<%- icon %> feeds-icon"></i>
</div>
<span class="tagnamecolor feeds-desc">
<%- icon %>
</span>
</div>
<% });
otherIcons.forEach(async(icon) => { %>
<div style="text-align:center;width:15%;float: left;padding-right:10px;">
<div class="icon-shape icon-sm shadow border-radius-md bg-white gray-icon-bg" style="margin: 0 auto">
<i class="fab fa-<%- icon %> feeds-icon"></i>
</div>
<span class="tagnamecolor feeds-desc">
<%- icon %>
</span>
</div>
<% }); %>
<% icons.forEach(async(icon) => { %>
<div style="text-align:center;width:15%;float: left;padding-right:10px;">
<div class="icon-shape icon-sm shadow border-radius-md bg-white gray-icon-bg" style="margin: 0 auto">
<i class="fas fa-<%- icon %> feeds-icon"></i>
</div>
<span class="tagnamecolor feeds-desc">
<%- icon %>
</span>
</div>
<% });
otherIcons.forEach(async(icon) => { %>
<div style="text-align:center;width:15%;float: left;padding-right:10px;">
<div class="icon-shape icon-sm shadow border-radius-md bg-white gray-icon-bg" style="margin: 0 auto">
<i class="fab fa-<%- icon %> feeds-icon"></i>
</div>
<span class="tagnamecolor feeds-desc">
<%- icon %>
</span>
</div>
<% }); %>
</div>

View file

@ -1,25 +1,45 @@
<meta charset="utf-8"/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Meta Information -->
<% if(themeConfig?.meta?.author){ %><meta name="author" content="<%- themeConfig.meta.author %>"><% } %>
<% if(themeConfig?.meta?.owner){ %><meta name="owner" content="<%- themeConfig.meta.owner %>"><% } %>
<% if(themeConfig?.meta?.ogLocale){ %><meta property="og:locale" content="<%- themeConfig.meta.ogLocale %>"><% } %>
<% if(themeConfig?.meta?.ogTitle){ %><meta property="og:title" content="<%- themeConfig.meta.ogTitle %>"><% } %>
<% if(themeConfig?.meta?.twitterTitle){ %><meta property="twitter:title" content="<%- themeConfig.meta.twitterTitle %>"><% } %>
<% if(themeConfig?.meta?.description){ %><meta name="description" content="<%- themeConfig.meta.description %>"><% } %>
<% if(themeConfig?.meta?.ogDescription){ %><meta property="og:description" content="<%- themeConfig.meta.ogDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDescription){ %><meta property="twitter:description" content="<%- themeConfig.meta.twitterDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDomain){ %><meta property="twitter:domain" content="<%- themeConfig.meta.twitterDomain %>"><% } %>
<% if(themeConfig?.meta?.twitterUrl){ %><meta property="twitter:url" content="<%- themeConfig.meta.twitterUrl %>"><% } %>
<% if(themeConfig?.meta?.twitterCard){ %><meta property="twitter:card" content="<%- themeConfig.meta.twitterCard %>"><% } %>
<% if(themeConfig?.meta?.twitterSite){ %><meta property="twitter:site" content="<%- themeConfig.meta.twitterSite %>"><% } %>
<% if(themeConfig?.meta?.twitterSiteId){ %><meta property="twitter:site:id" content="<%- themeConfig.meta.twitterSiteId %>"><% } %>
<% if(themeConfig?.meta?.twitterCreator){ %><meta property="twitter:creator" content="<%- themeConfig.meta.twitterCreator %>"><% } %>
<% if(themeConfig?.meta?.twitterCreatorId){ %><meta property="twitter:creator:id" content="<%- themeConfig.meta.twitterCreatorId %>"><% } %>
<% if(themeConfig?.meta?.twitterImage){ %><meta property="twitter:image" content="<%- themeConfig.meta.twitterImage %>"><% } %>
<% if(themeConfig?.meta?.ogImage){ %><meta property="og:image" itemprop="image" content="<%- themeConfig.meta.ogImage %>"><% } %>
<% if(themeConfig?.meta?.ogType){ %><meta property="og:type" content="<%- themeConfig.meta.ogType %>"><% } %>
<% if(themeConfig?.meta?.ogUrl){ %><meta property="og:url" content="<%- themeConfig.meta.ogUrl %>"><% } %>
<% if(themeConfig?.meta?.ogSiteName){ %><meta property="og:site_name" content="<%- themeConfig.meta.ogSiteName %>"><% } %>
<% if(themeConfig?.meta?.author){ %>
<meta name="author" content="<%- themeConfig.meta.author %>"><% } %>
<% if(themeConfig?.meta?.owner){ %>
<meta name="owner" content="<%- themeConfig.meta.owner %>"><% } %>
<% if(themeConfig?.meta?.ogLocale){ %>
<meta property="og:locale" content="<%- themeConfig.meta.ogLocale %>"><% } %>
<% if(themeConfig?.meta?.ogTitle){ %>
<meta property="og:title" content="<%- themeConfig.meta.ogTitle %>"><% } %>
<% if(themeConfig?.meta?.twitterTitle){ %>
<meta property="twitter:title" content="<%- themeConfig.meta.twitterTitle %>"><% } %>
<% if(themeConfig?.meta?.description){ %>
<meta name="description" content="<%- themeConfig.meta.description %>"><% } %>
<% if(themeConfig?.meta?.ogDescription){ %>
<meta property="og:description" content="<%- themeConfig.meta.ogDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDescription){ %>
<meta property="twitter:description" content="<%- themeConfig.meta.twitterDescription %>"><% } %>
<% if(themeConfig?.meta?.twitterDomain){ %>
<meta property="twitter:domain" content="<%- themeConfig.meta.twitterDomain %>"><% } %>
<% if(themeConfig?.meta?.twitterUrl){ %>
<meta property="twitter:url" content="<%- themeConfig.meta.twitterUrl %>"><% } %>
<% if(themeConfig?.meta?.twitterCard){ %>
<meta property="twitter:card" content="<%- themeConfig.meta.twitterCard %>"><% } %>
<% if(themeConfig?.meta?.twitterSite){ %>
<meta property="twitter:site" content="<%- themeConfig.meta.twitterSite %>"><% } %>
<% if(themeConfig?.meta?.twitterSiteId){ %>
<meta property="twitter:site:id" content="<%- themeConfig.meta.twitterSiteId %>"><% } %>
<% if(themeConfig?.meta?.twitterCreator){ %>
<meta property="twitter:creator" content="<%- themeConfig.meta.twitterCreator %>"><% } %>
<% if(themeConfig?.meta?.twitterCreatorId){ %>
<meta property="twitter:creator:id" content="<%- themeConfig.meta.twitterCreatorId %>"><% } %>
<% if(themeConfig?.meta?.twitterImage){ %>
<meta property="twitter:image" content="<%- themeConfig.meta.twitterImage %>"><% } %>
<% if(themeConfig?.meta?.ogImage){ %>
<meta property="og:image" itemprop="image" content="<%- themeConfig.meta.ogImage %>"><% } %>
<% if(themeConfig?.meta?.ogType){ %>
<meta property="og:type" content="<%- themeConfig.meta.ogType %>"><% } %>
<% if(themeConfig?.meta?.ogUrl){ %>
<meta property="og:url" content="<%- themeConfig.meta.ogUrl %>"><% } %>
<% if(themeConfig?.meta?.ogSiteName){ %>
<meta property="og:site_name" content="<%- themeConfig.meta.ogSiteName %>"><% } %>
<!-- End of Meta Information -->

View file

@ -1,64 +1,64 @@
<%
let currentPage = "Dashboard";
if (now) {
const pages = req?.locales?.partials?.navbar?.pages;
if (now === 'manage') currentPage = pages?.manage || "Manage Guilds";
if (now === 'settings') currentPage = pages?.settings || "Manage Guilds";
if (now === 'commands') currentPage = pages?.commands || "Commands";
if (now === 'pp') currentPage = pages?.pp || "Privacy Policy";
if (now === 'admin') currentPage = pages?.admin || "Admin Panel";
if (now === 'error') currentPage = pages?.error || "Error";
if (now === 'credits') currentPage = pages?.credits || "Credits";
if (now === 'debug') currentPage = pages?.debug || "Debug";
if (now === 'leaderboard') currentPage = pages?.leaderboard || "Leaderboard";
if (now === 'profile') currentPage = pages?.profile || "Profile";
if (now === 'maintenance') currentPage = pages?.maintenance || "Under Maintenance";
if (now === 'shards') currentPage = pages?.shards || "Shards";
const pages = req?.locales?.partials?.navbar?.pages;
if (now === 'manage') currentPage = pages?.manage || "Manage Guilds";
if (now === 'settings') currentPage = pages?.settings || "Manage Guilds";
if (now === 'commands') currentPage = pages?.commands || "Commands";
if (now === 'pp') currentPage = pages?.pp || "Privacy Policy";
if (now === 'admin') currentPage = pages?.admin || "Admin Panel";
if (now === 'error') currentPage = pages?.error || "Error";
if (now === 'credits') currentPage = pages?.credits || "Credits";
if (now === 'debug') currentPage = pages?.debug || "Debug";
if (now === 'leaderboard') currentPage = pages?.leaderboard || "Leaderboard";
if (now === 'profile') currentPage = pages?.profile || "Profile";
if (now === 'maintenance') currentPage = pages?.maintenance || "Under Maintenance";
if (now === 'shards') currentPage = pages?.shards || "Shards";
}
%>
<!-- Navbar -->
<nav style="padding-bottom: 0;" class="navbar navbar-main navbar-expand-lg px-0 mx-4 shadow-none border-radius-xl"
id="navbarBlur" navbar-scroll="false">
<div class="container-fluid py-1 px-3">
<nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent mb-0 pb-0 pt-1 px-0 me-sm-6 me-5">
<li class="breadcrumb-item text-sm"><a class="opacity-9 text-dark" href="/"><%- req?.locales?.partials?.navbar?.home || "Home" %></a></li>
<li class="breadcrumb-item text-sm text-dark active" aria-current="page"><%- currentPage %></li>
</ol>
<h6 class="font-weight-bolder mb-0"><%- currentPage %></h6>
</nav>
id="navbarBlur" navbar-scroll="false">
<div class="container-fluid py-1 px-3">
<nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent mb-0 pb-0 pt-1 px-0 me-sm-6 me-5">
<li class="breadcrumb-item text-sm"><a class="opacity-9 text-dark" href="/"><%- req?.locales?.partials?.navbar?.home || "Home" %></a></li>
<li class="breadcrumb-item text-sm text-dark active" aria-current="page"><%- currentPage %></li>
</ol>
<h6 class="font-weight-bolder mb-0"><%- currentPage %></h6>
</nav>
<div class="collapse navbar-collapse mt-sm-0 mt-2 me-md-0 me-sm-4" id="navbar">
<div class="ms-md-auto pe-md-3 d-flex align-items-center">
</div>
<ul class="navbar-nav justify-content-end">
<li class="nav-item d-xl-none ps-3 d-flex align-items-center">
<a onclick="toggleSidenav()" style="cursor: pointer;" class="nav-link text-body p-0"
id="iconNavbarSidenav">
<div class="sidenav-toggler-inner">
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
</div>
</a>
</li>
<!--<% if(req.session.user) { %>
<li class="nav-item dropdown pe-2 d-flex align-items-center">
<a href="javascript:;" class="avatar rounded-circle" style="margin-top: 5px;">
<img alt="Image placeholder"
src="<%= req.session.user.avatarURL || "https://w5fc.org/wp-content/uploads/2021/05/s9biyhs4lix61.jpg" %>">
</a>
</li>
<% } else { %>
<li class="nav-item dropdown pe-2 d-flex align-items-center">
<a onclick="const newWindow = window.open('/discord?r=/close%3Flogin=true', 'Log in with discord', `scrollbars=no, resizable=no, status=no, location=no, toolbar=no, menubar=no, width=500, height=800`);" class="nav-link text-body p-0">
<i class="fa fa-user me-sm-1" aria-hidden="true"></i>
<span class="d-sm-inline d-none">Sign In</span>
</a>
</li>
<% } %>-->
</ul>
</div>
</div>
<div class="collapse navbar-collapse mt-sm-0 mt-2 me-md-0 me-sm-4" id="navbar">
<div class="ms-md-auto pe-md-3 d-flex align-items-center">
</div>
<ul class="navbar-nav justify-content-end">
<li class="nav-item d-xl-none ps-3 d-flex align-items-center">
<a onclick="toggleSidenav()" style="cursor: pointer;" class="nav-link text-body p-0"
id="iconNavbarSidenav">
<div class="sidenav-toggler-inner">
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
</div>
</a>
</li>
<!--<% if(req.session.user) { %>
<li class="nav-item dropdown pe-2 d-flex align-items-center">
<a href="javascript:;" class="avatar rounded-circle" style="margin-top: 5px;">
<img alt="Image placeholder"
src="<%= req.session.user.avatarURL || "https://w5fc.org/wp-content/uploads/2021/05/s9biyhs4lix61.jpg" %>">
</a>
</li>
<% } else { %>
<li class="nav-item dropdown pe-2 d-flex align-items-center">
<a onclick="const newWindow = window.open('/discord?r=/close%3Flogin=true', 'Log in with discord', `scrollbars=no, resizable=no, status=no, location=no, toolbar=no, menubar=no, width=500, height=800`);" class="nav-link text-body p-0">
<i class="fa fa-user me-sm-1" aria-hidden="true"></i>
<span class="d-sm-inline d-none">Sign In</span>
</a>
</li>
<% } %>-->
</ul>
</div>
</div>
</nav>
<!-- End Navbar -->

View file

@ -1,29 +1,29 @@
<div class="row">
<div class="col-md-4">
<div class="modal fade" id="modal-default" tabindex="-1" role="dialog" aria-labelledby="modal-default"
aria-hidden="true">
<div class="modal-dialog modal- modal-dialog-centered modal-" role="document">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title" id="modal-title-default"><%- title %></h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
onclick="resetURL()">
<div class="col-md-4">
<div class="modal fade" id="modal-default" tabindex="-1" role="dialog" aria-labelledby="modal-default"
aria-hidden="true">
<div class="modal-dialog modal- modal-dialog-centered modal-" role="document">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title" id="modal-title-default"><%- title %></h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
onclick="resetURL()">
</button>
</div>
<div class="modal-body">
<h5><%- subtitle %></h5>
<% errors.forEach(e=>{ %>
<%= e.split('%is%')[0] %>: <%= e.split('%is%')[1] %> <!--(id: <%= e.split('%is%')[2] %>)-->
<br>
<% }) %>
</div>
<div class="modal-footer">
<button type="button" class="btn bg-gradient-primary" data-bs-dismiss="modal"
onclick="resetURL()">Close
</button>
</div>
</div>
</div>
</div>
</div>
</button>
</div>
<div class="modal-body">
<h5><%- subtitle %></h5>
<% errors.forEach(e=>{ %>
<%= e.split('%is%')[0] %>: <%= e.split('%is%')[1] %> <!--(id: <%= e.split('%is%')[2] %>)-->
<br>
<% }) %>
</div>
<div class="modal-footer">
<button type="button" class="btn bg-gradient-primary" data-bs-dismiss="modal"
onclick="resetURL()">Close
</button>
</div>
</div>
</div>
</div>
</div>

View file

@ -1,67 +1,67 @@
<style>
@media all and (min-width: 0px) and (max-width: 600px) {
.responsive {
width: calc(100vw - 30px)
}
}
@media all and (min-width: 0px) and (max-width: 600px) {
.responsive {
width: calc(100vw - 30px)
}
}
@media all and (min-width: 0px) and (max-width: 590px) {
.responsive {
margin-top: calc(100vh / 4) !important;
}
}
@media all and (min-width: 0px) and (max-width: 590px) {
.responsive {
margin-top: calc(100vh / 4) !important;
}
}
.preloader {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100vh;
z-index: 99999999;
background-repeat: no-repeat;
background-image: none;
background-color: #FFF;
background-position: center;
}
.preloader {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100vh;
z-index: 99999999;
background-repeat: no-repeat;
background-image: none;
background-color: #FFF;
background-position: center;
}
#scroll {
height: 100% !important;
/* overflow: hidden; */
}
#scroll {
height: 100% !important;
/* overflow: hidden; */
}
</style>
<div class="preloader">
<div class="progress-wrapper">
<div id="progress-bar" class="progress">
<div id="progress" class="progress-bar bg-gradient-primary" role="progressbar" aria-valuenow="60"
aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
</div>
</div>
<% if(themeConfig.preloader){ %>
<% if(themeConfig.preloader.image) { %>
<% if(!themeConfig.preloader.spinner) { %>
<div class="loader">
<img class="responsive preloader-image" src="<%- themeConfig.preloader.image %>" alt=""
style="border-radius: 5%; display: block; margin-left: auto; margin-right: auto; margin-top: calc(100vh / 5.8);">
</div>
<% } %>
<% } %>
<% if(themeConfig.preloader.text){ %>
<br>
<div style="text-align: center;<% if(themeConfig.preloader.spinner) { %>margin-top: calc(100vh / 2.7);<% } %>">
<h1 class="font-weight-bolder text-primary text-gradient"><%- req?.locales?.partials?.preloader?.text %></h1>
<% if(themeConfig.preloader.spinner) { %>
<div class="progress-wrapper">
<div id="progress-bar" class="progress">
<div id="progress" class="progress-bar bg-gradient-primary" role="progressbar" aria-valuenow="60"
aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
</div>
</div>
<% if(themeConfig.preloader){ %>
<% if(themeConfig.preloader.image) { %>
<% if(!themeConfig.preloader.spinner) { %>
<div class="loader">
<img class="responsive preloader-image" src="<%- themeConfig.preloader.image %>" alt=""
style="border-radius: 5%; display: block; margin-left: auto; margin-right: auto; margin-top: calc(100vh / 5.8);">
</div>
<% } %>
<% } %>
<% if(themeConfig.preloader.text){ %>
<br>
<div style="text-align: center;<% if(themeConfig.preloader.spinner) { %>margin-top: calc(100vh / 2.7);<% } %>">
<h1 class="font-weight-bolder text-primary text-gradient"><%- req?.locales?.partials?.preloader?.text %></h1>
<% if(themeConfig.preloader.spinner) { %>
<div style="transform: scale(3); padding-top: 30px;">
<div style="text-align: center; " class="spinner-border text-primary text-gradient"
role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<% } %>
</div>
<% } %>
<% } %>
<div style="transform: scale(3); padding-top: 30px;">
<div style="text-align: center; " class="spinner-border text-primary text-gradient"
role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<% } %>
</div>
<% } %>
<% } %>
</div>

View file

@ -1,18 +1,18 @@
<%
let currentPage = "Dashboard";
if (now) {
const pages = req?.locales?.partials?.navbar?.pages;
if (now === 'manage') currentPage = pages?.manage || "Manage Guilds";
if (now === 'settings') currentPage = pages?.settings || "Manage Guilds";
if (now === 'commands') currentPage = pages?.commands || "Commands";
if (now === 'pp') currentPage = pages?.pp || "Privacy Policy";
if (now === 'admin') currentPage = pages?.admin || "Admin Panel";
if (now === 'error') currentPage = pages?.error || "Error";
if (now === 'credits') currentPage = pages?.credits || "Credits";
if (now === 'debug') currentPage = pages?.debug || "Debug";
if (now === 'leaderboard') currentPage = pages?.leaderboard || "Leaderboard";
if (now === 'profile') currentPage = pages?.profile || "Profile";
if (now === 'maintenance') currentPage = pages?.maintenance || "Under Maintenance";
const pages = req?.locales?.partials?.navbar?.pages;
if (now === 'manage') currentPage = pages?.manage || "Manage Guilds";
if (now === 'settings') currentPage = pages?.settings || "Manage Guilds";
if (now === 'commands') currentPage = pages?.commands || "Commands";
if (now === 'pp') currentPage = pages?.pp || "Privacy Policy";
if (now === 'admin') currentPage = pages?.admin || "Admin Panel";
if (now === 'error') currentPage = pages?.error || "Error";
if (now === 'credits') currentPage = pages?.credits || "Credits";
if (now === 'debug') currentPage = pages?.debug || "Debug";
if (now === 'leaderboard') currentPage = pages?.leaderboard || "Leaderboard";
if (now === 'profile') currentPage = pages?.profile || "Profile";
if (now === 'maintenance') currentPage = pages?.maintenance || "Under Maintenance";
}
%>
@ -21,13 +21,13 @@ if (now) {
<!-- Page Information -->
<link rel="icon" type="image/png" href="<%= themeConfig.icons.favicon %>">
<title>
<%= themeConfig.websiteName %> - <%- currentPage %>
<%= themeConfig.websiteName %> - <%- currentPage %>
</title>
<!-- End of Page Information -->
<!-- Stylesheets -->
<% if(themeConfig.preloader.image) { %>
<link rel="prefetch" href="<%- themeConfig.preloader.image %>"/><% } %>
<link rel="prefetch" href="<%- themeConfig.preloader.image %>"/><% } %>
<link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" as="style" onload="this.onload=null;this.rel='stylesheet'">
@ -38,25 +38,25 @@ if (now) {
<link rel="preload" href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@4/dark.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<link rel="preload" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/jquery-ui.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Alatsi">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/nucleo-icons.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/nucleo-svg.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/soft-ui-dashboard.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@4/dark.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/jquery-ui.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Alatsi">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/nucleo-icons.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/nucleo-svg.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/soft-ui-dashboard.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@4/dark.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/css/jquery-ui.min.css">
</noscript>
<% // By default system theme is loaded, unless a user has changed it. Probably could be optimised further but :shrug:
if(req.cookies?.selectedTheme == "dark" || req.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %>
<link href="/css/darkMode.css" rel='stylesheet' <% if(req?.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %> media="(prefers-color-scheme: dark)"<% } %>>
<% if (themeConfig?.icons?.sidebar?.darkUrl) { %>
<style <% if(req?.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %> media="(prefers-color-scheme: dark)"<% } %>>
.navbar-brand-img {
content:url("<%= themeConfig.icons.sidebar.darkUrl %>") !important;
}
</style>
<% } %>
<link href="/css/darkMode.css" rel='stylesheet' <% if(req?.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %> media="(prefers-color-scheme: dark)"<% } %>>
<% if (themeConfig?.icons?.sidebar?.darkUrl) { %>
<style <% if(req?.cookies?.selectedTheme == "auto" || !req.cookies?.selectedTheme) { %> media="(prefers-color-scheme: dark)"<% } %>>
.navbar-brand-img {
content:url("<%= themeConfig.icons.sidebar.darkUrl %>") !important;
}
</style>
<% } %>
<% } %>
<!-- End of Stylesheets -->
@ -68,127 +68,127 @@ if(req.cookies?.selectedTheme == "dark" || req.cookies?.selectedTheme == "auto"
<%- include('colorscheme.ejs') %>
<script>
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const swal = params.get('swal');
const result = params.get('result');
if (swal) {
if (swal === "savedSuccess") sweetalert('success', '<%= themeConfig?.sweetalert?.success?.settingsSave || 'Successfully saved setttings!' %>', 3000);
if (swal === "savedError") sweetalert('error', '<%= themeConfig?.sweetalert?.error?.settingsSave || 'Failed to save setttings!' %>', 3000);
<% if (req.session.user) { %>if (swal === "logged") sweetalert('success', '<%= themeConfig?.sweetalert?.success?.login || 'Successfully logged in!' %>', 3000); <% } %>
<% if (!req.session.user) { %>if (swal === "loggedout") sweetalert('success', '<%= themeConfig?.sweetalert?.success?.logout || 'Successfully logged out!' %>', 3000); <% } %>
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const swal = params.get('swal');
const result = params.get('result');
if (swal) {
if (swal === "savedSuccess") sweetalert('success', '<%= themeConfig?.sweetalert?.success?.settingsSave || 'Successfully saved setttings!' %>', 3000);
if (swal === "savedError") sweetalert('error', '<%= themeConfig?.sweetalert?.error?.settingsSave || 'Failed to save setttings!' %>', 3000);
params.delete('swal');
}
if (result) {
if (result === "true") sweetalert('success', 'Checked for updates!', 3000);
if (result === "false") sweetalert('error', 'Failed to check for updates!', 3000);
<% if (req.session.user) { %>if (swal === "logged") sweetalert('success', '<%= themeConfig?.sweetalert?.success?.login || 'Successfully logged in!' %>', 3000); <% } %>
<% if (!req.session.user) { %>if (swal === "loggedout") sweetalert('success', '<%= themeConfig?.sweetalert?.success?.logout || 'Successfully logged out!' %>', 3000); <% } %>
params.delete('result');
}
params.delete('swal');
}
if (result) {
if (result === "true") sweetalert('success', 'Checked for updates!', 3000);
if (result === "false") sweetalert('error', 'Failed to check for updates!', 3000);
window.history.replaceState({}, document.title, `${window.location.pathname}${params.toString() ? "?" + params.toString() : ""}`);
});
params.delete('result');
}
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
window.history.replaceState({}, document.title, `${window.location.pathname}${params.toString() ? "?" + params.toString() : ""}`);
});
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function deleteCookie(name) {
document.cookie = name + '=; Max-Age=0'
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
let prog_width = 0;
let disabled = false;
document.onreadystatechange = function (e) {
if (disabled) return;
if (document.readyState === "interactive") {
var all = document.getElementsByTagName("*");
for (var i = 0, max = all.length; i < max; i++) {
checkProgress(all[i]);
}
}
}
function deleteCookie(name) {
document.cookie = name + '=; Max-Age=0'
}
function checkProgress(ele) {
var all = document.getElementsByTagName("*");
var per_inc = 100 / all.length;
if (disabled) return;
let prog_width = 0;
let disabled = false;
document.onreadystatechange = function (e) {
if (disabled) return;
if (document.readyState === "interactive") {
var all = document.getElementsByTagName("*");
for (var i = 0, max = all.length; i < max; i++) {
checkProgress(all[i]);
}
}
}
prog_width = prog_width + per_inc;
$("#progress").width(`${Math.floor(prog_width)}%`);
function checkProgress(ele) {
var all = document.getElementsByTagName("*");
var per_inc = 100 / all.length;
if (disabled) return;
if (prog_width >= 100 && !disabled) {
disabled = true;
$(".preloader").fadeOut("slow")
//() => { $(".preloader").remove() }
$("#scroll").css('overflow', 'auto');
} else {
checkProgress(ele);
}
}
<% if (req.session.user) { %>
let userID = '<%- req.session.user.id %>';
let userTag = '<%- req.session.user.tag %>';
<% } %>
prog_width = prog_width + per_inc;
$("#progress").width(`${Math.floor(prog_width)}%`);
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
if (prog_width >= 100 && !disabled) {
disabled = true;
$(".preloader").fadeOut("slow")
//() => { $(".preloader").remove() }
$("#scroll").css('overflow', 'auto');
} else {
checkProgress(ele);
}
}
<% if (req.session.user) { %>
let userID = '<%- req.session.user.id %>';
let userTag = '<%- req.session.user.tag %>';
<% } %>
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
</script>
<!-- End of Scripts -->
<% if(now !== "maintenance" && now !== "error") { %>
<%- include('theme.ejs') %>
<%- include('theme.ejs') %>
<% } %>

View file

@ -1,72 +1,72 @@
<% if (req.cookies?.premiumCard == "false" || !req.cookies?.premiumCard) { %>
<div class="rightCircle"><i class="fas fa-times"></i></div>
<div class="premium-card card card-background shadow-none card-background-mask-primary" id="sidenavCard">
<div class="full-background"
style="background-image: url('<%- themeConfig.premium.card.bgImage %>'); margin-bottom: 0 !important;"></div>
<div class="card-body text-start p-3 w-100">
<div class="docs-info">
<h6 class="hide-click text-white up mb-0"><%- req?.locales?.partials?.premium?.title %></h6>
<p class="hide-click text-xs font-weight-bold"><%- req?.locales?.partials?.premium?.description %></p>
<a style="margin-bottom: 0 !important;" class="premium-button btn bg-gradient-primary mt-4 w-100"
target="_blank"
href="<%- themeConfig.premium.card.button.url %>"
type="button"><%- req?.locales?.partials?.premium?.buttonText %></a>
</div>
</div>
</div>
<div class="rightCircle"><i class="fas fa-times"></i></div>
<div class="premium-card card card-background shadow-none card-background-mask-primary" id="sidenavCard">
<div class="full-background"
style="background-image: url('<%- themeConfig.premium.card.bgImage %>'); margin-bottom: 0 !important;"></div>
<div class="card-body text-start p-3 w-100">
<div class="docs-info">
<h6 class="hide-click text-white up mb-0"><%- req?.locales?.partials?.premium?.title %></h6>
<p class="hide-click text-xs font-weight-bold"><%- req?.locales?.partials?.premium?.description %></p>
<a style="margin-bottom: 0 !important;" class="premium-button btn bg-gradient-primary mt-4 w-100"
target="_blank"
href="<%- themeConfig.premium.card.button.url %>"
type="button"><%- req?.locales?.partials?.premium?.buttonText %></a>
</div>
</div>
</div>
<% } %>
<script>
$('.rightCircle').on('click', function () {
var date = new Date();
date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
document.cookie = "premiumCard=true" + expires + "; path=/";
$(".sidenav-footer").fadeOut("slow");
});
$('.rightCircle').on('click', function () {
var date = new Date();
date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
document.cookie = "premiumCard=true" + expires + "; path=/";
$(".sidenav-footer").fadeOut("slow");
});
</script>
<style>
.margin-top-0 {
margin-top: 0 !important;
}
.margin-top-0 {
margin-top: 0 !important;
}
.sidenav-footer {
width: 90%;
}
.sidenav-footer {
width: 90%;
}
.rightCircle {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
position: absolute;
right: -5px;
top: -5px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 0 0 1px #fff;
z-index: 100;
}
.rightCircle {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
position: absolute;
right: -5px;
top: -5px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 0 0 1px #fff;
z-index: 100;
}
.sidebarPremium {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
position: absolute;
right: 10px;
width: 20px;
height: 7px;
border-radius: 50%;
background-color: transparent;
z-index: 100;
}
.sidebarPremium {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
position: absolute;
right: 10px;
width: 20px;
height: 7px;
border-radius: 50%;
background-color: transparent;
z-index: 100;
}
</style>

View file

@ -1,158 +1,158 @@
<!-- Core JS Files -->
<script src="https://cdn.jsdelivr.net/npm/jquery.skeleton.loader@1.2.0/dist/jquery.scheletrone.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"
integrity="sha256-eTyxS0rkjpLEo16uXTS0uVCS4815lc40K2iVpWDvdSY=" crossorigin="anonymous"></script>
integrity="sha256-eTyxS0rkjpLEo16uXTS0uVCS4815lc40K2iVpWDvdSY=" crossorigin="anonymous"></script>
<script>
function login(url) {
<% if (!req.session.user) { %>
const newWindow = window.open('/discord', 'Log in with discord', `directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width=500, height=800`);
newWindow.focus();
setInterval(() => {
if (newWindow.closed) window.location.href = `${url}?swal=logged`;
}, 500);
<% } else { %>
window.location.href = `${url}?swal=alreadyloggedin`;
<% } %>
}
function login(url) {
<% if (!req.session.user) { %>
const newWindow = window.open('/discord', 'Log in with discord', `directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width=500, height=800`);
newWindow.focus();
setInterval(() => {
if (newWindow.closed) window.location.href = `${url}?swal=logged`;
}, 500);
<% } else { %>
window.location.href = `${url}?swal=alreadyloggedin`;
<% } %>
}
$('.account').click(function (e) {
e.preventDefault();
login(e.currentTarget.href)
});
$('.account').click(function (e) {
e.preventDefault();
login(e.currentTarget.href)
});
$('.theme').click(function () {
$('.theme').removeClass('active');
$(this).addClass('active');
const theme = $(this).attr('data-theme');
setCookie('selectedTheme', theme, 365);
location.reload();
});
$('.theme').click(function () {
$('.theme').removeClass('active');
$(this).addClass('active');
const theme = $(this).attr('data-theme');
setCookie('selectedTheme', theme, 365);
location.reload();
});
const sidenav = document.getElementById('sidenav-main');
const sidenav = document.getElementById('sidenav-main');
function hideSidenav() {
body.classList.remove(className);
setTimeout(function () {
sidenav.classList.remove('bg-white');
}, 100);
sidenav.classList.remove('bg-transparent');
}
function hideSidenav() {
body.classList.remove(className);
setTimeout(function () {
sidenav.classList.remove('bg-white');
}, 100);
sidenav.classList.remove('bg-transparent');
}
function showSidenav() {
try {
body.classList.add(className);
sidenav.classList.add('bg-white');
sidenav.classList.remove('bg-transparent');
iconSidenav.classList.remove('d-none');
} catch (error) {
}
}
function showSidenav() {
try {
body.classList.add(className);
sidenav.classList.add('bg-white');
sidenav.classList.remove('bg-transparent');
iconSidenav.classList.remove('d-none');
} catch (error) {
}
}
<% if (!themeConfig?.sidebar?.gestures?.disabled) { %>
document.addEventListener('touchstart', handleTouchStart, false);
document.addEventListener('touchmove', handleTouchMove, false);
document.addEventListener('touchend', handleTouchEnd, false);
<% if (!themeConfig?.sidebar?.gestures?.disabled) { %>
document.addEventListener('touchstart', handleTouchStart, false);
document.addEventListener('touchmove', handleTouchMove, false);
document.addEventListener('touchend', handleTouchEnd, false);
const SWIPE_BLOCK_ELEMS = [
'swipBlock',
'handle',
'drag-ruble'
]
const SWIPE_BLOCK_ELEMS = [
'swipBlock',
'handle',
'drag-ruble'
]
let xDown = null;
let yDown = null;
let xDiff = null;
let yDiff = null;
let timeDown = null;
let xDown = null;
let yDown = null;
let xDiff = null;
let yDiff = null;
let timeDown = null;
const TIME_THRESHOLD = <%= themeConfig?.sidebar?.gestures?.gestureTimer || 200 %>;
const DIFF_THRESHOLD = <%= themeConfig?.sidebar?.gestures?.gestureSensitivity || 50 %>;
const TIME_THRESHOLD = <%= themeConfig?.sidebar?.gestures?.gestureTimer || 200 %>;
const DIFF_THRESHOLD = <%= themeConfig?.sidebar?.gestures?.gestureSensitivity || 50 %>;
function handleTouchEnd() {
function handleTouchEnd() {
let timeDiff = Date.now() - timeDown;
if (Math.abs(xDiff) > Math.abs(yDiff)) {
if (Math.abs(xDiff) > DIFF_THRESHOLD && timeDiff < TIME_THRESHOLD) {
if (xDiff > 0) {
hideSidenav()
xDown = null;
yDown = null;
timeDown = null;
} else {
showSidenav()
xDown = null;
yDown = null;
timeDown = null;
}
}
}
let timeDiff = Date.now() - timeDown;
if (Math.abs(xDiff) > Math.abs(yDiff)) {
if (Math.abs(xDiff) > DIFF_THRESHOLD && timeDiff < TIME_THRESHOLD) {
if (xDiff > 0) {
hideSidenav()
xDown = null;
yDown = null;
timeDown = null;
} else {
showSidenav()
xDown = null;
yDown = null;
timeDown = null;
}
}
}
xDown = null;
yDown = null;
timeDown = null;
}
xDown = null;
yDown = null;
timeDown = null;
}
function containsClassName(evntarget, classArr) {
for (var i = classArr.length - 1; i >= 0; i--) {
if (evntarget.classList.contains(classArr[i])) {
return true;
}
}
}
function containsClassName(evntarget, classArr) {
for (var i = classArr.length - 1; i >= 0; i--) {
if (evntarget.classList.contains(classArr[i])) {
return true;
}
}
}
function handleTouchStart(evt) {
let touchStartTarget = evt.target;
if (containsClassName(touchStartTarget, SWIPE_BLOCK_ELEMS)) {
return;
}
timeDown = Date.now()
xDown = evt.touches[0].clientX;
yDown = evt.touches[0].clientY;
xDiff = 0;
yDiff = 0;
function handleTouchStart(evt) {
let touchStartTarget = evt.target;
if (containsClassName(touchStartTarget, SWIPE_BLOCK_ELEMS)) {
return;
}
timeDown = Date.now()
xDown = evt.touches[0].clientX;
yDown = evt.touches[0].clientY;
xDiff = 0;
yDiff = 0;
}
}
function handleTouchMove(evt) {
if (!xDown || !yDown) {
return;
}
function handleTouchMove(evt) {
if (!xDown || !yDown) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
xDiff = xDown - xUp;
yDiff = yDown - yUp;
}
<% } %>
function sweetalert(icons, text, timer) {
var is_mobile = !!navigator.userAgent.match(/iphone|android|blackberry/ig);
let pos = 'top-end';
if (is_mobile) pos = 'bottom-end';
const Toast = Swal.mixin({
toast: true,
position: pos,
showConfirmButton: false,
timer: timer,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
xDiff = xDown - xUp;
yDiff = yDown - yUp;
}
<% } %>
function sweetalert(icons, text, timer) {
var is_mobile = !!navigator.userAgent.match(/iphone|android|blackberry/ig);
let pos = 'top-end';
if (is_mobile) pos = 'bottom-end';
const Toast = Swal.mixin({
toast: true,
position: pos,
showConfirmButton: false,
timer: timer,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
Toast.fire({
icon: icons,
title: text
})
}
Toast.fire({
icon: icons,
title: text
})
}
<% if (req.displayLoggedInInfo == true) { %>
window.onload = function () {
sweetalert("success", "<%= themeConfig?.sweetalert?.success?.login || 'Successfully signed in.' %>", 2000)
};
<% } %>
<% if (req.displayLoggedInInfo == true) { %>
window.onload = function () {
sweetalert("success", "<%= themeConfig?.sweetalert?.success?.login || 'Successfully signed in.' %>", 2000)
};
<% } %>
</script>
<script src="https://cdn.jsdelivr.net/gh/Assistants-Center/DBD-Soft-UI/views/src/js/plugins/chartjs.min.js"></script>
<script src="js/dashboard/sweetalert.js"></script>

File diff suppressed because one or more lines are too long

View file

@ -1,45 +1,45 @@
<%
for(var i in req.session.guilds){ %>
<% if((req.session.guilds[i].permissions & 0x00000020) == 0x00000020){ %>
<% if(!bot.guilds.cache.get(req.session.guilds[i].id)){
let icon = `https://cdn.discordapp.com/icons/${req.session.guilds[i].id}/${req.session.guilds[i].icon}.png`;
const friendlyName = req.session.guilds[i].name.replace('`', '');
if (!req.session.guilds[i].icon) icon = themeConfig.iconURL;
%>
<a href="#">
<img id="servericon" onclick="select<%- req.session.guilds[i].id %>()" onerror="this.src = '<%= icon %>';"
src="https://cdn.discordapp.com/icons/<%= req.session.guilds[i].id %>/<%= req.session.guilds[i].icon %>.png">
</a>
<script>
async function select<%- req.session.guilds[i].id %>() {
$('#select').html(`<%= friendlyName %>`);
$('#selectedImg').attr('src', '<%= icon %>');
$("#inviteButton").attr('href', "../invite?g=<%- req.session.guilds[i].id %>");
$("#notInServer").show();
setUser(`<%= friendlyName %>`, `<%= icon %>`, `Server ID: <%= req.session.guilds[i].id %>`);
}
</script>
<% }else{
const guild = bot.guilds.cache.get(req.session.guilds[i].id);
let icon;
<% if((req.session.guilds[i].permissions & 0x00000020) == 0x00000020){ %>
<% if(!bot.guilds.cache.get(req.session.guilds[i].id)){
let icon = `https://cdn.discordapp.com/icons/${req.session.guilds[i].id}/${req.session.guilds[i].icon}.png`;
const friendlyName = req.session.guilds[i].name.replace('`', '');
if (!req.session.guilds[i].icon) icon = themeConfig.iconURL;
%>
<a href="#">
<img id="servericon" onclick="select<%- req.session.guilds[i].id %>()" onerror="this.src = '<%= icon %>';"
src="https://cdn.discordapp.com/icons/<%= req.session.guilds[i].id %>/<%= req.session.guilds[i].icon %>.png">
</a>
<script>
async function select<%- req.session.guilds[i].id %>() {
$('#select').html(`<%= friendlyName %>`);
$('#selectedImg').attr('src', '<%= icon %>');
$("#inviteButton").attr('href', "../invite?g=<%- req.session.guilds[i].id %>");
$("#notInServer").show();
setUser(`<%= friendlyName %>`, `<%= icon %>`, `Server ID: <%= req.session.guilds[i].id %>`);
}
</script>
<% }else{
const guild = bot.guilds.cache.get(req.session.guilds[i].id);
let icon;
if (!guild.iconURL()) icon = themeConfig.iconURL;
else icon = guild.iconURL();
const friendlyName = guild.name.replace('`', '');
%>
<a href="#" onclick="select<%- guild.id %>()">
<img id="servericon" onerror="this.src = '<%= themeConfig.iconURL %>';" src="<%= icon %>">
</a>
<script>
async function select<%- guild.id %>() {
$('#select').html(`<%= friendlyName %>`);
$('#selectedImg').attr('src', '<%= icon %>');
$("#notInServer").hide();
setUser(`<%= friendlyName %>`, `<%= icon %>`, `Server ID: <%= req.session.guilds[i].id %>`);
window.location = "../guild/<%= req.session.guilds[i].id %>";
}
</script>
<!--/guild/<%= req.session.guilds[i].id %>-->
if (!guild.iconURL()) icon = themeConfig.iconURL;
else icon = guild.iconURL();
const friendlyName = guild.name.replace('`', '');
%>
<a href="#" onclick="select<%- guild.id %>()">
<img id="servericon" onerror="this.src = '<%= themeConfig.iconURL %>';" src="<%= icon %>">
</a>
<script>
async function select<%- guild.id %>() {
$('#select').html(`<%= friendlyName %>`);
$('#selectedImg').attr('src', '<%= icon %>');
$("#notInServer").hide();
setUser(`<%= friendlyName %>`, `<%= icon %>`, `Server ID: <%= req.session.guilds[i].id %>`);
window.location = "../guild/<%= req.session.guilds[i].id %>";
}
</script>
<!--/guild/<%= req.session.guilds[i].id %>-->
<%
}
}

View file

@ -1,342 +1,342 @@
<style>
.navbar-vertical.navbar-expand-xs .navbar-collapse {
height: auto !important;
}
.navbar-vertical.navbar-expand-xs .navbar-collapse {
height: auto !important;
}
</style>
<aside class="sidenav navbar navbar-vertical navbar-expand-xs border-0 border-radius-xl my-3 fixed-start ms-3 ps"
style="float:left;" id="sidenav-main">
<div id="sidebarMain">
<div class="sidenav-header">
<a onclick="toggleSidenav()"><i
class="fas fa-times p-3 cursor-pointer text-secondary opacity-5 position-absolute end-0 top-0 d-none d-xl-none"
aria-hidden="true" id="iconSidenav"></i></a>
<a
<% if(themeConfig.icons.sidebar.alignCenter) { %> style="text-align: center;"
<% } %>
class="navbar-brand m-0" href="/">
<img src="<%- themeConfig.icons.sidebar.lightUrl %>"
class="navbar-brand-img h-100"
<% if(themeConfig.icons.sidebar.borderRadius) { %>style="border-radius: <%- themeConfig.icons.sidebar.borderRadius %>;"
<% } %>
alt="main_logo">
<% if(!themeConfig.icons.sidebar.hideName){ %>
<span class="ms-1 font-weight-bold" id="sitename"><%= themeConfig.websiteName %></span>
<% } %>
</a>
</div>
<hr class="horizontal dark mt-0">
<div class="collapse navbar-collapse w-auto max-height-vh-80 h-80" id="sidenav-collapse-main">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link <% if(now == 'index'){ %>active<% } else { %>" href='/'
<% } %>
">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 45 40" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>shop </title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-1716.000000, -439.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="shop-" transform="translate(0.000000, 148.000000)">
<path class="color-background"
d="M46.7199583,10.7414583 L40.8449583,0.949791667 C40.4909749,0.360605034 39.8540131,0 39.1666667,0 L7.83333333,0 C7.1459869,0 6.50902508,0.360605034 6.15504167,0.949791667 L0.280041667,10.7414583 C0.0969176761,11.0460037 -1.23209662e-05,11.3946378 -1.23209662e-05,11.75 C-0.00758042603,16.0663731 3.48367543,19.5725301 7.80004167,19.5833333 L7.81570833,19.5833333 C9.75003686,19.5882688 11.6168794,18.8726691 13.0522917,17.5760417 C16.0171492,20.2556967 20.5292675,20.2556967 23.494125,17.5760417 C26.4604562,20.2616016 30.9794188,20.2616016 33.94575,17.5760417 C36.2421905,19.6477597 39.5441143,20.1708521 42.3684437,18.9103691 C45.1927731,17.649886 47.0084685,14.8428276 47.0000295,11.75 C47.0000295,11.3946378 46.9030823,11.0460037 46.7199583,10.7414583 Z"
id="Path" opacity="0.598981585"></path>
<path class="color-background"
d="M39.198,22.4912623 C37.3776246,22.4928106 35.5817531,22.0149171 33.951625,21.0951667 L33.92225,21.1107282 C31.1430221,22.6838032 27.9255001,22.9318916 24.9844167,21.7998837 C24.4750389,21.605469 23.9777983,21.3722567 23.4960833,21.1018359 L23.4745417,21.1129513 C20.6961809,22.6871153 17.4786145,22.9344611 14.5386667,21.7998837 C14.029926,21.6054643 13.533337,21.3722507 13.0522917,21.1018359 C11.4250962,22.0190609 9.63246555,22.4947009 7.81570833,22.4912623 C7.16510551,22.4842162 6.51607673,22.4173045 5.875,22.2911849 L5.875,44.7220845 C5.875,45.9498589 6.7517757,46.9451667 7.83333333,46.9451667 L19.5833333,46.9451667 L19.5833333,33.6066734 L27.4166667,33.6066734 L27.4166667,46.9451667 L39.1666667,46.9451667 C40.2482243,46.9451667 41.125,45.9498589 41.125,44.7220845 L41.125,22.2822926 C40.4887822,22.4116582 39.8442868,22.4815492 39.198,22.4912623 Z"
id="Path"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.dash || "Dashboard" %></span>
</a>
</li>
<li class="nav-item">
<a href="/manage" id="serverSelector"
class="account nav-link <% if(now == 'manage'){ %>active<% } %>">
<div id="icon" class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 40 40" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>settings</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2020.000000, -442.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="settings" transform="translate(304.000000, 151.000000)">
<polygon class="color-background" id="Path" opacity="0.596981957"
points="18.0883333 15.7316667 11.1783333 8.82166667 13.3333333 6.66666667 6.66666667 0 0 6.66666667 6.66666667 13.3333333 8.82166667 11.1783333 15.315 17.6716667">
</polygon>
<path class="color-background"
d="M31.5666667,23.2333333 C31.0516667,23.2933333 30.53,23.3333333 30,23.3333333 C29.4916667,23.3333333 28.9866667,23.3033333 28.48,23.245 L22.4116667,30.7433333 L29.9416667,38.2733333 C32.2433333,40.575 35.9733333,40.575 38.275,38.2733333 L38.275,38.2733333 C40.5766667,35.9716667 40.5766667,32.2416667 38.275,29.94 L31.5666667,23.2333333 Z"
id="Path" opacity="0.596981957"></path>
<path class="color-background"
d="M33.785,11.285 L28.715,6.215 L34.0616667,0.868333333 C32.82,0.315 31.4483333,0 30,0 C24.4766667,0 20,4.47666667 20,10 C20,10.99 20.1483333,11.9433333 20.4166667,12.8466667 L2.435,27.3966667 C0.95,28.7083333 0.0633333333,30.595 0.00333333333,32.5733333 C-0.0583333333,34.5533333 0.71,36.4916667 2.11,37.89 C3.47,39.2516667 5.27833333,40 7.20166667,40 C9.26666667,40 11.2366667,39.1133333 12.6033333,37.565 L27.1533333,19.5833333 C28.0566667,19.8516667 29.01,20 30,20 C35.5233333,20 40,15.5233333 40,10 C40,8.55166667 39.685,7.18 39.1316667,5.93666667 L33.785,11.285 Z"
id="Path"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.manage || "Manage Guilds" %></span>
</a>
</li>
<% if(themeConfig.shardspage?.enabled == true) { %>
<li class="nav-item">
<a class="nav-link <% if(now == 'shards'){ %>active<% } else { %>" href='/shards'
<% } %>
">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M0 336c0 79.5 64.5 144 144 144H512c70.7 0 128-57.3 128-128c0-61.9-44-113.6-102.4-125.4c4.1-10.7 6.4-22.4 6.4-34.6c0-53-43-96-96-96c-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32C167.6 32 96 103.6 96 192c0 2.7 .1 5.4 .2 8.1C40.2 219.8 0 273.2 0 336z"/></svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.shards || "Shards" %></span>
</a>
</li>
<% } %>
<% if (now == "commands") { %>
<li class="nav-item">
<a data-bs-toggle="collapse" href="#dashboardsExamples"
class="nav-link <% if(now == 'commands'){ %>active<% } %> collapsed"
aria-controls="dashboardsExamples" role="button"
aria-expanded="<% if(now == "commands"){ %>true<% } else{ %>false<% } %>">
<div class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center d-flex align-items-center justify-content-center me-2">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 43 36" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>credit-card</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2169.000000, -745.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="credit-card" transform="translate(453.000000, 454.000000)">
<path class="color-background"
d="M43,10.7482083 L43,3.58333333 C43,1.60354167 41.3964583,0 39.4166667,0 L3.58333333,0 C1.60354167,0 0,1.60354167 0,3.58333333 L0,10.7482083 L43,10.7482083 Z"
id="Path" opacity="0.593633743"></path>
<path class="color-background"
d="M0,16.125 L0,32.25 C0,34.2297917 1.60354167,35.8333333 3.58333333,35.8333333 L39.4166667,35.8333333 C41.3964583,35.8333333 43,34.2297917 43,32.25 L43,16.125 L0,16.125 Z M19.7083333,26.875 L7.16666667,26.875 L7.16666667,23.2916667 L19.7083333,23.2916667 L19.7083333,26.875 Z M35.8333333,26.875 L28.6666667,26.875 L28.6666667,23.2916667 L35.8333333,23.2916667 L35.8333333,26.875 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.commands || "Commands" %></span>
</a>
<div class="collapse <% if(now == 'commands'){ %>show<% } %>" id="dashboardsExamples">
<ul class="nav ms-4 ps-3">
<li class="nav-item ">
<a id="all" class="nav-link glow active_all" href="#">
<span class="sidenav-mini-icon"> A </span>
<span class="sidenav-normal"> All </span>
</a>
</li>
<% themeConfig.commands.forEach(category => {
if (category.hideSidebarItem) return;
%>
<li class="nav-item">
<a id="<%= category.categoryId %>" class="nav-link glow active_<%= category.categoryId %>"
href="<% if(now !== 'commands'){ %>/commands<% } %>#<%= category.categoryId %>">
<span class="sidenav-mini-icon"> A </span>
<span class="sidenav-normal"> <%= category.category %> </span>
</a>
</li>
<% }) %>
</ul>
</div>
</li>
<% } else { %>
<li class="nav-item">
<a class="nav-link" href="/commands">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 43 36" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>credit-card</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2169.000000, -745.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="credit-card" transform="translate(453.000000, 454.000000)">
<path class="color-background"
d="M43,10.7482083 L43,3.58333333 C43,1.60354167 41.3964583,0 39.4166667,0 L3.58333333,0 C1.60354167,0 0,1.60354167 0,3.58333333 L0,10.7482083 L43,10.7482083 Z"
id="Path" opacity="0.593633743"></path>
<path class="color-background"
d="M0,16.125 L0,32.25 C0,34.2297917 1.60354167,35.8333333 3.58333333,35.8333333 L39.4166667,35.8333333 C41.3964583,35.8333333 43,34.2297917 43,32.25 L43,16.125 L0,16.125 Z M19.7083333,26.875 L7.16666667,26.875 L7.16666667,23.2916667 L19.7083333,23.2916667 L19.7083333,26.875 Z M35.8333333,26.875 L28.6666667,26.875 L28.6666667,23.2916667 L35.8333333,23.2916667 L35.8333333,26.875 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.commands || "Commands" %></span>
</a>
</li>
<% } %>
style="float:left;" id="sidenav-main">
<div id="sidebarMain">
<div class="sidenav-header">
<a onclick="toggleSidenav()"><i
class="fas fa-times p-3 cursor-pointer text-secondary opacity-5 position-absolute end-0 top-0 d-none d-xl-none"
aria-hidden="true" id="iconSidenav"></i></a>
<a
<% if(themeConfig.icons.sidebar.alignCenter) { %> style="text-align: center;"
<% } %>
class="navbar-brand m-0" href="/">
<img src="<%- themeConfig.icons.sidebar.lightUrl %>"
class="navbar-brand-img h-100"
<% if(themeConfig.icons.sidebar.borderRadius) { %>style="border-radius: <%- themeConfig.icons.sidebar.borderRadius %>;"
<% } %>
alt="main_logo">
<% if(!themeConfig.icons.sidebar.hideName){ %>
<span class="ms-1 font-weight-bold" id="sitename"><%= themeConfig.websiteName %></span>
<% } %>
</a>
</div>
<hr class="horizontal dark mt-0">
<div class="collapse navbar-collapse w-auto max-height-vh-80 h-80" id="sidenav-collapse-main">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link <% if(now == 'index'){ %>active<% } else { %>" href='/'
<% } %>
">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 45 40" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>shop </title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-1716.000000, -439.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="shop-" transform="translate(0.000000, 148.000000)">
<path class="color-background"
d="M46.7199583,10.7414583 L40.8449583,0.949791667 C40.4909749,0.360605034 39.8540131,0 39.1666667,0 L7.83333333,0 C7.1459869,0 6.50902508,0.360605034 6.15504167,0.949791667 L0.280041667,10.7414583 C0.0969176761,11.0460037 -1.23209662e-05,11.3946378 -1.23209662e-05,11.75 C-0.00758042603,16.0663731 3.48367543,19.5725301 7.80004167,19.5833333 L7.81570833,19.5833333 C9.75003686,19.5882688 11.6168794,18.8726691 13.0522917,17.5760417 C16.0171492,20.2556967 20.5292675,20.2556967 23.494125,17.5760417 C26.4604562,20.2616016 30.9794188,20.2616016 33.94575,17.5760417 C36.2421905,19.6477597 39.5441143,20.1708521 42.3684437,18.9103691 C45.1927731,17.649886 47.0084685,14.8428276 47.0000295,11.75 C47.0000295,11.3946378 46.9030823,11.0460037 46.7199583,10.7414583 Z"
id="Path" opacity="0.598981585"></path>
<path class="color-background"
d="M39.198,22.4912623 C37.3776246,22.4928106 35.5817531,22.0149171 33.951625,21.0951667 L33.92225,21.1107282 C31.1430221,22.6838032 27.9255001,22.9318916 24.9844167,21.7998837 C24.4750389,21.605469 23.9777983,21.3722567 23.4960833,21.1018359 L23.4745417,21.1129513 C20.6961809,22.6871153 17.4786145,22.9344611 14.5386667,21.7998837 C14.029926,21.6054643 13.533337,21.3722507 13.0522917,21.1018359 C11.4250962,22.0190609 9.63246555,22.4947009 7.81570833,22.4912623 C7.16510551,22.4842162 6.51607673,22.4173045 5.875,22.2911849 L5.875,44.7220845 C5.875,45.9498589 6.7517757,46.9451667 7.83333333,46.9451667 L19.5833333,46.9451667 L19.5833333,33.6066734 L27.4166667,33.6066734 L27.4166667,46.9451667 L39.1666667,46.9451667 C40.2482243,46.9451667 41.125,45.9498589 41.125,44.7220845 L41.125,22.2822926 C40.4887822,22.4116582 39.8442868,22.4815492 39.198,22.4912623 Z"
id="Path"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.dash || "Dashboard" %></span>
</a>
</li>
<li class="nav-item">
<a href="/manage" id="serverSelector"
class="account nav-link <% if(now == 'manage'){ %>active<% } %>">
<div id="icon" class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 40 40" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>settings</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2020.000000, -442.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="settings" transform="translate(304.000000, 151.000000)">
<polygon class="color-background" id="Path" opacity="0.596981957"
points="18.0883333 15.7316667 11.1783333 8.82166667 13.3333333 6.66666667 6.66666667 0 0 6.66666667 6.66666667 13.3333333 8.82166667 11.1783333 15.315 17.6716667">
</polygon>
<path class="color-background"
d="M31.5666667,23.2333333 C31.0516667,23.2933333 30.53,23.3333333 30,23.3333333 C29.4916667,23.3333333 28.9866667,23.3033333 28.48,23.245 L22.4116667,30.7433333 L29.9416667,38.2733333 C32.2433333,40.575 35.9733333,40.575 38.275,38.2733333 L38.275,38.2733333 C40.5766667,35.9716667 40.5766667,32.2416667 38.275,29.94 L31.5666667,23.2333333 Z"
id="Path" opacity="0.596981957"></path>
<path class="color-background"
d="M33.785,11.285 L28.715,6.215 L34.0616667,0.868333333 C32.82,0.315 31.4483333,0 30,0 C24.4766667,0 20,4.47666667 20,10 C20,10.99 20.1483333,11.9433333 20.4166667,12.8466667 L2.435,27.3966667 C0.95,28.7083333 0.0633333333,30.595 0.00333333333,32.5733333 C-0.0583333333,34.5533333 0.71,36.4916667 2.11,37.89 C3.47,39.2516667 5.27833333,40 7.20166667,40 C9.26666667,40 11.2366667,39.1133333 12.6033333,37.565 L27.1533333,19.5833333 C28.0566667,19.8516667 29.01,20 30,20 C35.5233333,20 40,15.5233333 40,10 C40,8.55166667 39.685,7.18 39.1316667,5.93666667 L33.785,11.285 Z"
id="Path"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.manage || "Manage Guilds" %></span>
</a>
</li>
<% if(themeConfig.shardspage?.enabled == true) { %>
<li class="nav-item">
<a class="nav-link <% if(now == 'shards'){ %>active<% } else { %>" href='/shards'
<% } %>
">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M0 336c0 79.5 64.5 144 144 144H512c70.7 0 128-57.3 128-128c0-61.9-44-113.6-102.4-125.4c4.1-10.7 6.4-22.4 6.4-34.6c0-53-43-96-96-96c-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32C167.6 32 96 103.6 96 192c0 2.7 .1 5.4 .2 8.1C40.2 219.8 0 273.2 0 336z"/></svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.shards || "Shards" %></span>
</a>
</li>
<% } %>
<% if (now == "commands") { %>
<li class="nav-item">
<a data-bs-toggle="collapse" href="#dashboardsExamples"
class="nav-link <% if(now == 'commands'){ %>active<% } %> collapsed"
aria-controls="dashboardsExamples" role="button"
aria-expanded="<% if(now == "commands"){ %>true<% } else{ %>false<% } %>">
<div class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center d-flex align-items-center justify-content-center me-2">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 43 36" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>credit-card</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2169.000000, -745.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="credit-card" transform="translate(453.000000, 454.000000)">
<path class="color-background"
d="M43,10.7482083 L43,3.58333333 C43,1.60354167 41.3964583,0 39.4166667,0 L3.58333333,0 C1.60354167,0 0,1.60354167 0,3.58333333 L0,10.7482083 L43,10.7482083 Z"
id="Path" opacity="0.593633743"></path>
<path class="color-background"
d="M0,16.125 L0,32.25 C0,34.2297917 1.60354167,35.8333333 3.58333333,35.8333333 L39.4166667,35.8333333 C41.3964583,35.8333333 43,34.2297917 43,32.25 L43,16.125 L0,16.125 Z M19.7083333,26.875 L7.16666667,26.875 L7.16666667,23.2916667 L19.7083333,23.2916667 L19.7083333,26.875 Z M35.8333333,26.875 L28.6666667,26.875 L28.6666667,23.2916667 L35.8333333,23.2916667 L35.8333333,26.875 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.commands || "Commands" %></span>
</a>
<div class="collapse <% if(now == 'commands'){ %>show<% } %>" id="dashboardsExamples">
<ul class="nav ms-4 ps-3">
<li class="nav-item ">
<a id="all" class="nav-link glow active_all" href="#">
<span class="sidenav-mini-icon"> A </span>
<span class="sidenav-normal"> All </span>
</a>
</li>
<% themeConfig.commands.forEach(category => {
if (category.hideSidebarItem) return;
%>
<li class="nav-item">
<a id="<%= category.categoryId %>" class="nav-link glow active_<%= category.categoryId %>"
href="<% if(now !== 'commands'){ %>/commands<% } %>#<%= category.categoryId %>">
<span class="sidenav-mini-icon"> A </span>
<span class="sidenav-normal"> <%= category.category %> </span>
</a>
</li>
<% }) %>
</ul>
</div>
</li>
<% } else { %>
<li class="nav-item">
<a class="nav-link" href="/commands">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 43 36" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>credit-card</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2169.000000, -745.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="credit-card" transform="translate(453.000000, 454.000000)">
<path class="color-background"
d="M43,10.7482083 L43,3.58333333 C43,1.60354167 41.3964583,0 39.4166667,0 L3.58333333,0 C1.60354167,0 0,1.60354167 0,3.58333333 L0,10.7482083 L43,10.7482083 Z"
id="Path" opacity="0.593633743"></path>
<path class="color-background"
d="M0,16.125 L0,32.25 C0,34.2297917 1.60354167,35.8333333 3.58333333,35.8333333 L39.4166667,35.8333333 C41.3964583,35.8333333 43,34.2297917 43,32.25 L43,16.125 L0,16.125 Z M19.7083333,26.875 L7.16666667,26.875 L7.16666667,23.2916667 L19.7083333,23.2916667 L19.7083333,26.875 Z M35.8333333,26.875 L28.6666667,26.875 L28.6666667,23.2916667 L35.8333333,23.2916667 L35.8333333,26.875 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.commands || "Commands" %></span>
</a>
</li>
<% } %>
<li class="nav-item">
<a class="nav-link <% if(now == 'pp'){ %>active"
<% } else { %>" href='/privacy-policy'
<% } %>
>
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 40 44" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>document</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-1870.000000, -591.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="document" transform="translate(154.000000, 300.000000)">
<path class="color-background"
d="M40,40 L36.3636364,40 L36.3636364,3.63636364 L5.45454545,3.63636364 L5.45454545,0 L38.1818182,0 C39.1854545,0 40,0.814545455 40,1.81818182 L40,40 Z"
id="Path" opacity="0.603585379"></path>
<path class="color-background"
d="M30.9090909,7.27272727 L1.81818182,7.27272727 C0.814545455,7.27272727 0,8.08727273 0,9.09090909 L0,41.8181818 C0,42.8218182 0.814545455,43.6363636 1.81818182,43.6363636 L30.9090909,43.6363636 C31.9127273,43.6363636 32.7272727,42.8218182 32.7272727,41.8181818 L32.7272727,9.09090909 C32.7272727,8.08727273 31.9127273,7.27272727 30.9090909,7.27272727 Z M18.1818182,34.5454545 L7.27272727,34.5454545 L7.27272727,30.9090909 L18.1818182,30.9090909 L18.1818182,34.5454545 Z M25.4545455,27.2727273 L7.27272727,27.2727273 L7.27272727,23.6363636 L25.4545455,23.6363636 L25.4545455,27.2727273 Z M25.4545455,20 L7.27272727,20 L7.27272727,16.3636364 L25.4545455,16.3636364 L25.4545455,20 Z"
id="Shape"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.pp || "Privacy Policy" %></span>
</a>
</li>
<% if(req.session.user && config.ownerIDs?.includes(req.session.user.id)) { %>
<li class="nav-item">
<a class="nav-link <% if(now == 'admin'){ %>active"
<% } else { %>" href='/admin'
<% } %>
>
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 42 42" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2319.000000, -291.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="box-3d-50" transform="translate(603.000000, 0.000000)">
<path class="color-background"
d="M22.7597136,19.3090182 L38.8987031,11.2395234 C39.3926816,10.9925342 39.592906,10.3918611 39.3459167,9.89788265 C39.249157,9.70436312 39.0922432,9.5474453 38.8987261,9.45068056 L20.2741875,0.1378125 L20.2741875,0.1378125 C19.905375,-0.04725 19.469625,-0.04725 19.0995,0.1378125 L3.1011696,8.13815822 C2.60720568,8.38517662 2.40701679,8.98586148 2.6540352,9.4798254 C2.75080129,9.67332903 2.90771305,9.83023153 3.10122239,9.9269862 L21.8652864,19.3090182 C22.1468139,19.4497819 22.4781861,19.4497819 22.7597136,19.3090182 Z"
id="Path"></path>
<path class="color-background"
d="M23.625,22.429159 L23.625,39.8805372 C23.625,40.4328219 24.0727153,40.8805372 24.625,40.8805372 C24.7802551,40.8805372 24.9333778,40.8443874 25.0722402,40.7749511 L41.2741875,32.673375 L41.2741875,32.673375 C41.719125,32.4515625 42,31.9974375 42,31.5 L42,14.241659 C42,13.6893742 41.5522847,13.241659 41,13.241659 C40.8447549,13.241659 40.6916418,13.2778041 40.5527864,13.3472318 L24.1777864,21.5347318 C23.8390024,21.7041238 23.625,22.0503869 23.625,22.429159 Z"
id="Path" opacity="0.7"></path>
<path class="color-background"
d="M20.4472136,21.5347318 L1.4472136,12.0347318 C0.953235098,11.7877425 0.352562058,11.9879669 0.105572809,12.4819454 C0.0361450918,12.6208008 6.47121774e-16,12.7739139 0,12.929159 L0,30.1875 L0,30.1875 C0,30.6849375 0.280875,31.1390625 0.7258125,31.3621875 L19.5528096,40.7750766 C20.0467945,41.0220531 20.6474623,40.8218132 20.8944388,40.3278283 C20.963859,40.1889789 21,40.0358742 21,39.8806379 L21,22.429159 C21,22.0503869 20.7859976,21.7041238 20.4472136,21.5347318 Z"
id="Path" opacity="0.7"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.admin || "Admin" %></span>
</a>
</li>
<% } %>
<% if(now == 'commands'){ %>
<li class="nav-item mt-3">
<h6 class="ps-4 ms-2 text-uppercase text-xs font-weight-bolder opacity-6"><%- req?.locales?.partials?.sidebar.commands || "Commands" %></h6>
</li>
<div class="form-group" style="width: 190px; margin-left: 33px !important;">
<div class="input-group mb-4" style="margin-bottom: 0px !important;">
<span class="input-group-text"><i class="ni ni-zoom-split-in"></i></span>
<input class="form-control" type="text" id="searchBar"
placeholder="Search for commands..">
</div>
</div>
<% } %>
<li class="nav-item mt-3">
<h6 class="ps-4 ms-2 text-uppercase text-xs font-weight-bolder opacity-6"><%- req?.locales?.partials?.sidebar.account || "Account pages" %></h6>
</li>
<% if(!req.session.user) { %>
<li class="nav-item">
<a class="nav-link account" href="<%= req.originalUrl %>">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg width="12px" height="12px" viewBox="0 0 40 44" version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<title>document</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-1870.000000, -591.000000)" fill="#FFFFFF"
fill-rule="nonzero">
<g transform="translate(1716.000000, 291.000000)">
<g transform="translate(154.000000, 300.000000)">
<path class="color-background opacity-6"
d="M40,40 L36.3636364,40 L36.3636364,3.63636364 L5.45454545,3.63636364 L5.45454545,0 L38.1818182,0 C39.1854545,0 40,0.814545455 40,1.81818182 L40,40 Z">
</path>
<path class="color-background"
d="M30.9090909,7.27272727 L1.81818182,7.27272727 C0.814545455,7.27272727 0,8.08727273 0,9.09090909 L0,41.8181818 C0,42.8218182 0.814545455,43.6363636 1.81818182,43.6363636 L30.9090909,43.6363636 C31.9127273,43.6363636 32.7272727,42.8218182 32.7272727,41.8181818 L32.7272727,9.09090909 C32.7272727,8.08727273 31.9127273,7.27272727 30.9090909,7.27272727 Z M18.1818182,34.5454545 L7.27272727,34.5454545 L7.27272727,30.9090909 L18.1818182,30.9090909 L18.1818182,34.5454545 Z M25.4545455,27.2727273 L7.27272727,27.2727273 L7.27272727,23.6363636 L25.4545455,23.6363636 L25.4545455,27.2727273 Z M25.4545455,20 L7.27272727,20 L7.27272727,16.3636364 L25.4545455,16.3636364 L25.4545455,20 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.login || "Sign In" %></span>
</a>
</li>
<% } else { %>
<li class="nav-item">
<a class="nav-link" href="/discord/logout?r=/?swal=loggedout">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg width="12px" height="20px" viewBox="0 0 40 40" version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<title>spaceship</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-1720.000000, -592.000000)" fill="#FFFFFF"
fill-rule="nonzero">
<g transform="translate(1716.000000, 291.000000)">
<g transform="translate(4.000000, 301.000000)">
<path class="color-background"
d="M39.3,0.706666667 C38.9660984,0.370464027 38.5048767,0.192278529 38.0316667,0.216666667 C14.6516667,1.43666667 6.015,22.2633333 5.93166667,22.4733333 C5.68236407,23.0926189 5.82664679,23.8009159 6.29833333,24.2733333 L15.7266667,33.7016667 C16.2013871,34.1756798 16.9140329,34.3188658 17.535,34.065 C17.7433333,33.98 38.4583333,25.2466667 39.7816667,1.97666667 C39.8087196,1.50414529 39.6335979,1.04240574 39.3,0.706666667 Z M25.69,19.0233333 C24.7367525,19.9768687 23.3029475,20.2622391 22.0572426,19.7463614 C20.8115377,19.2304837 19.9992882,18.0149658 19.9992882,16.6666667 C19.9992882,15.3183676 20.8115377,14.1028496 22.0572426,13.5869719 C23.3029475,13.0710943 24.7367525,13.3564646 25.69,14.31 C26.9912731,15.6116662 26.9912731,17.7216672 25.69,19.0233333 L25.69,19.0233333 Z">
</path>
<path class="color-background opacity-6"
d="M1.855,31.4066667 C3.05106558,30.2024182 4.79973884,29.7296005 6.43969145,30.1670277 C8.07964407,30.6044549 9.36054508,31.8853559 9.7979723,33.5253085 C10.2353995,35.1652612 9.76258177,36.9139344 8.55833333,38.11 C6.70666667,39.9616667 0,40 0,40 C0,40 0,33.2566667 1.855,31.4066667 Z">
</path>
<path class="color-background opacity-6"
d="M17.2616667,3.90166667 C12.4943643,3.07192755 7.62174065,4.61673894 4.20333333,8.04166667 C3.31200265,8.94126033 2.53706177,9.94913142 1.89666667,11.0416667 C1.5109569,11.6966059 1.61721591,12.5295394 2.155,13.0666667 L5.47,16.3833333 C8.55036617,11.4946947 12.5559074,7.25476565 17.2616667,3.90166667 L17.2616667,3.90166667 Z">
</path>
<path class="color-background opacity-6"
d="M36.0983333,22.7383333 C36.9280725,27.5056357 35.3832611,32.3782594 31.9583333,35.7966667 C31.0587397,36.6879974 30.0508686,37.4629382 28.9583333,38.1033333 C28.3033941,38.4890431 27.4704606,38.3827841 26.9333333,37.845 L23.6166667,34.53 C28.5053053,31.4496338 32.7452344,27.4440926 36.0983333,22.7383333 L36.0983333,22.7383333 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.logout || "Sign Out" %></span>
</a>
</li>
<% } %>
</ul>
</div>
<% if(themeConfig?.premium && req.session.user) { %>
<div class="sidenav-footer mx-3 pb-4" style="position: absolute;bottom: 0;">
<%- include('premium.ejs') %>
</div>
<% } %>
<li class="nav-item">
<a class="nav-link <% if(now == 'pp'){ %>active"
<% } else { %>" href='/privacy-policy'
<% } %>
>
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 40 44" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>document</title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-1870.000000, -591.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="document" transform="translate(154.000000, 300.000000)">
<path class="color-background"
d="M40,40 L36.3636364,40 L36.3636364,3.63636364 L5.45454545,3.63636364 L5.45454545,0 L38.1818182,0 C39.1854545,0 40,0.814545455 40,1.81818182 L40,40 Z"
id="Path" opacity="0.603585379"></path>
<path class="color-background"
d="M30.9090909,7.27272727 L1.81818182,7.27272727 C0.814545455,7.27272727 0,8.08727273 0,9.09090909 L0,41.8181818 C0,42.8218182 0.814545455,43.6363636 1.81818182,43.6363636 L30.9090909,43.6363636 C31.9127273,43.6363636 32.7272727,42.8218182 32.7272727,41.8181818 L32.7272727,9.09090909 C32.7272727,8.08727273 31.9127273,7.27272727 30.9090909,7.27272727 Z M18.1818182,34.5454545 L7.27272727,34.5454545 L7.27272727,30.9090909 L18.1818182,30.9090909 L18.1818182,34.5454545 Z M25.4545455,27.2727273 L7.27272727,27.2727273 L7.27272727,23.6363636 L25.4545455,23.6363636 L25.4545455,27.2727273 Z M25.4545455,20 L7.27272727,20 L7.27272727,16.3636364 L25.4545455,16.3636364 L25.4545455,20 Z"
id="Shape"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.pp || "Privacy Policy" %></span>
</a>
</li>
<% if(req.session.user && config.ownerIDs?.includes(req.session.user.id)) { %>
<li class="nav-item">
<a class="nav-link <% if(now == 'admin'){ %>active"
<% } else { %>" href='/admin'
<% } %>
>
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 42 42" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-2319.000000, -291.000000)"
fill="#FFFFFF"
fill-rule="nonzero">
<g id="Icons-with-opacity" transform="translate(1716.000000, 291.000000)">
<g id="box-3d-50" transform="translate(603.000000, 0.000000)">
<path class="color-background"
d="M22.7597136,19.3090182 L38.8987031,11.2395234 C39.3926816,10.9925342 39.592906,10.3918611 39.3459167,9.89788265 C39.249157,9.70436312 39.0922432,9.5474453 38.8987261,9.45068056 L20.2741875,0.1378125 L20.2741875,0.1378125 C19.905375,-0.04725 19.469625,-0.04725 19.0995,0.1378125 L3.1011696,8.13815822 C2.60720568,8.38517662 2.40701679,8.98586148 2.6540352,9.4798254 C2.75080129,9.67332903 2.90771305,9.83023153 3.10122239,9.9269862 L21.8652864,19.3090182 C22.1468139,19.4497819 22.4781861,19.4497819 22.7597136,19.3090182 Z"
id="Path"></path>
<path class="color-background"
d="M23.625,22.429159 L23.625,39.8805372 C23.625,40.4328219 24.0727153,40.8805372 24.625,40.8805372 C24.7802551,40.8805372 24.9333778,40.8443874 25.0722402,40.7749511 L41.2741875,32.673375 L41.2741875,32.673375 C41.719125,32.4515625 42,31.9974375 42,31.5 L42,14.241659 C42,13.6893742 41.5522847,13.241659 41,13.241659 C40.8447549,13.241659 40.6916418,13.2778041 40.5527864,13.3472318 L24.1777864,21.5347318 C23.8390024,21.7041238 23.625,22.0503869 23.625,22.429159 Z"
id="Path" opacity="0.7"></path>
<path class="color-background"
d="M20.4472136,21.5347318 L1.4472136,12.0347318 C0.953235098,11.7877425 0.352562058,11.9879669 0.105572809,12.4819454 C0.0361450918,12.6208008 6.47121774e-16,12.7739139 0,12.929159 L0,30.1875 L0,30.1875 C0,30.6849375 0.280875,31.1390625 0.7258125,31.3621875 L19.5528096,40.7750766 C20.0467945,41.0220531 20.6474623,40.8218132 20.8944388,40.3278283 C20.963859,40.1889789 21,40.0358742 21,39.8806379 L21,22.429159 C21,22.0503869 20.7859976,21.7041238 20.4472136,21.5347318 Z"
id="Path" opacity="0.7"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.admin || "Admin" %></span>
</a>
</li>
<% } %>
<% if(now == 'commands'){ %>
<li class="nav-item mt-3">
<h6 class="ps-4 ms-2 text-uppercase text-xs font-weight-bolder opacity-6"><%- req?.locales?.partials?.sidebar.commands || "Commands" %></h6>
</li>
<div class="form-group" style="width: 190px; margin-left: 33px !important;">
<div class="input-group mb-4" style="margin-bottom: 0px !important;">
<span class="input-group-text"><i class="ni ni-zoom-split-in"></i></span>
<input class="form-control" type="text" id="searchBar"
placeholder="Search for commands..">
</div>
</div>
<% } %>
<li class="nav-item mt-3">
<h6 class="ps-4 ms-2 text-uppercase text-xs font-weight-bolder opacity-6"><%- req?.locales?.partials?.sidebar.account || "Account pages" %></h6>
</li>
<% if(!req.session.user) { %>
<li class="nav-item">
<a class="nav-link account" href="<%= req.originalUrl %>">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg width="12px" height="12px" viewBox="0 0 40 44" version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<title>document</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-1870.000000, -591.000000)" fill="#FFFFFF"
fill-rule="nonzero">
<g transform="translate(1716.000000, 291.000000)">
<g transform="translate(154.000000, 300.000000)">
<path class="color-background opacity-6"
d="M40,40 L36.3636364,40 L36.3636364,3.63636364 L5.45454545,3.63636364 L5.45454545,0 L38.1818182,0 C39.1854545,0 40,0.814545455 40,1.81818182 L40,40 Z">
</path>
<path class="color-background"
d="M30.9090909,7.27272727 L1.81818182,7.27272727 C0.814545455,7.27272727 0,8.08727273 0,9.09090909 L0,41.8181818 C0,42.8218182 0.814545455,43.6363636 1.81818182,43.6363636 L30.9090909,43.6363636 C31.9127273,43.6363636 32.7272727,42.8218182 32.7272727,41.8181818 L32.7272727,9.09090909 C32.7272727,8.08727273 31.9127273,7.27272727 30.9090909,7.27272727 Z M18.1818182,34.5454545 L7.27272727,34.5454545 L7.27272727,30.9090909 L18.1818182,30.9090909 L18.1818182,34.5454545 Z M25.4545455,27.2727273 L7.27272727,27.2727273 L7.27272727,23.6363636 L25.4545455,23.6363636 L25.4545455,27.2727273 Z M25.4545455,20 L7.27272727,20 L7.27272727,16.3636364 L25.4545455,16.3636364 L25.4545455,20 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.login || "Sign In" %></span>
</a>
</li>
<% } else { %>
<li class="nav-item">
<a class="nav-link" href="/discord/logout?r=/?swal=loggedout">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg width="12px" height="20px" viewBox="0 0 40 40" version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<title>spaceship</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-1720.000000, -592.000000)" fill="#FFFFFF"
fill-rule="nonzero">
<g transform="translate(1716.000000, 291.000000)">
<g transform="translate(4.000000, 301.000000)">
<path class="color-background"
d="M39.3,0.706666667 C38.9660984,0.370464027 38.5048767,0.192278529 38.0316667,0.216666667 C14.6516667,1.43666667 6.015,22.2633333 5.93166667,22.4733333 C5.68236407,23.0926189 5.82664679,23.8009159 6.29833333,24.2733333 L15.7266667,33.7016667 C16.2013871,34.1756798 16.9140329,34.3188658 17.535,34.065 C17.7433333,33.98 38.4583333,25.2466667 39.7816667,1.97666667 C39.8087196,1.50414529 39.6335979,1.04240574 39.3,0.706666667 Z M25.69,19.0233333 C24.7367525,19.9768687 23.3029475,20.2622391 22.0572426,19.7463614 C20.8115377,19.2304837 19.9992882,18.0149658 19.9992882,16.6666667 C19.9992882,15.3183676 20.8115377,14.1028496 22.0572426,13.5869719 C23.3029475,13.0710943 24.7367525,13.3564646 25.69,14.31 C26.9912731,15.6116662 26.9912731,17.7216672 25.69,19.0233333 L25.69,19.0233333 Z">
</path>
<path class="color-background opacity-6"
d="M1.855,31.4066667 C3.05106558,30.2024182 4.79973884,29.7296005 6.43969145,30.1670277 C8.07964407,30.6044549 9.36054508,31.8853559 9.7979723,33.5253085 C10.2353995,35.1652612 9.76258177,36.9139344 8.55833333,38.11 C6.70666667,39.9616667 0,40 0,40 C0,40 0,33.2566667 1.855,31.4066667 Z">
</path>
<path class="color-background opacity-6"
d="M17.2616667,3.90166667 C12.4943643,3.07192755 7.62174065,4.61673894 4.20333333,8.04166667 C3.31200265,8.94126033 2.53706177,9.94913142 1.89666667,11.0416667 C1.5109569,11.6966059 1.61721591,12.5295394 2.155,13.0666667 L5.47,16.3833333 C8.55036617,11.4946947 12.5559074,7.25476565 17.2616667,3.90166667 L17.2616667,3.90166667 Z">
</path>
<path class="color-background opacity-6"
d="M36.0983333,22.7383333 C36.9280725,27.5056357 35.3832611,32.3782594 31.9583333,35.7966667 C31.0587397,36.6879974 30.0508686,37.4629382 28.9583333,38.1033333 C28.3033941,38.4890431 27.4704606,38.3827841 26.9333333,37.845 L23.6166667,34.53 C28.5053053,31.4496338 32.7452344,27.4440926 36.0983333,22.7383333 L36.0983333,22.7383333 Z">
</path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1"><%- req?.locales?.partials?.sidebar.logout || "Sign Out" %></span>
</a>
</li>
<% } %>
</ul>
</div>
<% if(themeConfig?.premium && req.session.user) { %>
<div class="sidenav-footer mx-3 pb-4" style="position: absolute;bottom: 0;">
<%- include('premium.ejs') %>
</div>
<% } %>
</aside>

View file

@ -1,71 +1,71 @@
<div class="fixed-plugin">
<a id="themeButton" class="fixed-plugin-button text-dark position-fixed px-3 py-2">
<i class="fa fa-cog py-2"> </i>
</a>
<div class="card shadow-lg ">
<div class="card-header pb-0 pt-3 ">
<div class="float-start">
<h5 class="mt-3 mb-0"><%- req?.locales?.partials?.settings?.title || "Site Configuration" %></h5>
<p><%- req?.locales?.partials?.settings?.description || "Configurable Viewing Options" %></p>
</div>
<div class="float-end mt-4">
<button aria-label="Close Panel" class="btn btn-link text-dark p-0 fixed-plugin-close-button">
<i class="fa fa-close"></i>
</button>
</div>
<!-- End Toggle Button -->
</div>
<hr class="horizontal dark my-1">
<div class="card-body pt-sm-3 pt-0">
<!-- Sidebar Backgrounds -->
<!-- Sidenav Type -->
<div class="mt-3">
<h6 class="mb-0"><%- req?.locales?.partials?.settings?.theme?.title || "Site Theme" %></h6>
<p class="text-sm"><%- req?.locales?.partials?.settings?.theme?.description || "Make the site more appealing for your eyes!" %></p>
</div>
<div class="d-flex">
<button data-theme="auto"
class="theme btn bg-gradient-primary w-100 px-3 mb-2 ms-2 <% if (req.cookies?.selectedTheme == "auto") { %>active<% } %>"
data-class="bg-white">
Auto
</button>
<button data-theme="light"
class="theme btn bg-gradient-primary w-100 mb-2 ms-2 <% if (req.cookies?.selectedTheme == "light") { %>active<% } %>"
data-class="bg-transparent">
Light
</button>
<button data-theme="dark"
class="theme btn bg-gradient-primary w-100 px-3 mb-2 ms-2 <% if (req.cookies?.selectedTheme == "dark") { %>active<% } %>"
data-class="bg-white">
Dark
</button>
<a id="themeButton" class="fixed-plugin-button text-dark position-fixed px-3 py-2">
<i class="fa fa-cog py-2"> </i>
</a>
<div class="card shadow-lg ">
<div class="card-header pb-0 pt-3 ">
<div class="float-start">
<h5 class="mt-3 mb-0"><%- req?.locales?.partials?.settings?.title || "Site Configuration" %></h5>
<p><%- req?.locales?.partials?.settings?.description || "Configurable Viewing Options" %></p>
</div>
<div class="float-end mt-4">
<button aria-label="Close Panel" class="btn btn-link text-dark p-0 fixed-plugin-close-button">
<i class="fa fa-close"></i>
</button>
</div>
<!-- End Toggle Button -->
</div>
<hr class="horizontal dark my-1">
<div class="card-body pt-sm-3 pt-0">
<!-- Sidebar Backgrounds -->
<!-- Sidenav Type -->
<div class="mt-3">
<h6 class="mb-0"><%- req?.locales?.partials?.settings?.theme?.title || "Site Theme" %></h6>
<p class="text-sm"><%- req?.locales?.partials?.settings?.theme?.description || "Make the site more appealing for your eyes!" %></p>
</div>
<div class="d-flex">
<button data-theme="auto"
class="theme btn bg-gradient-primary w-100 px-3 mb-2 ms-2 <% if (req.cookies?.selectedTheme == "auto") { %>active<% } %>"
data-class="bg-white">
Auto
</button>
<button data-theme="light"
class="theme btn bg-gradient-primary w-100 mb-2 ms-2 <% if (req.cookies?.selectedTheme == "light") { %>active<% } %>"
data-class="bg-transparent">
Light
</button>
<button data-theme="dark"
class="theme btn bg-gradient-primary w-100 px-3 mb-2 ms-2 <% if (req.cookies?.selectedTheme == "dark") { %>active<% } %>"
data-class="bg-white">
Dark
</button>
</div>
<div class="mt-5">
<h6 class="mb-0"><%- req?.locales?.partials?.settings?.language?.title || "Site Language" %></h6>
<p class="text-sm"><%- req?.locales?.partials?.settings?.language?.description || "Select your preferred language!" %></p>
</div>
<div class="d-flex">
<select name="languages" id="lang" class="form-control">
<%
let locales = {};
locales = (themeConfig.locales) ? themeConfig.locales : themeConfig.defaultLocales;
Object.keys(locales).forEach((lang) => { %>
<option value="<%= lang %>" <%= lang === req?.lang ? 'selected' : '' %>><%= locales[lang].name %></option>
<% }) %>
</select>
</div>
<p class="text-sm d-xl-none d-block mt-2">You can change the sidenav type just on desktop view.</p>
</div>
</div>
</div>
<div class="mt-5">
<h6 class="mb-0"><%- req?.locales?.partials?.settings?.language?.title || "Site Language" %></h6>
<p class="text-sm"><%- req?.locales?.partials?.settings?.language?.description || "Select your preferred language!" %></p>
</div>
<div class="d-flex">
<select name="languages" id="lang" class="form-control">
<%
let locales = {};
locales = (themeConfig.locales) ? themeConfig.locales : themeConfig.defaultLocales;
Object.keys(locales).forEach((lang) => { %>
<option value="<%= lang %>" <%= lang === req?.lang ? 'selected' : '' %>><%= locales[lang].name %></option>
<% }) %>
</select>
</div>
<p class="text-sm d-xl-none d-block mt-2">You can change the sidenav type just on desktop view.</p>
</div>
</div>
</div>
<script>
$("#lang").change(function () {
var lang = $(this).val();
setCookie('lang', lang, 365);
$("#lang").change(function () {
var lang = $(this).val();
setCookie('lang', lang, 365);
location.reload()
});
location.reload()
});
</script>
<script src="./js/configMenu.js"></script>

View file

@ -1,478 +1,462 @@
<!--
=========================================================
* Now UI Dashboard - v1.5.0
=========================================================
* Product Page: https://www.creative-tim.com/product/now-ui-dashboard
* Copyright 2019 Creative Tim (http://www.creative-tim.com)
* Designed by www.invisionapp.com Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now: 'pp'}) %>
<%- themeConfig?.customHtml %>
<%- include('partials/preloader.ejs', {now: 'pp'}) %>
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now: 'pp'}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now: 'pp'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="content">
<div class="row">
<div class="col-md-12 mb-4">
<div class="card">
<div class="card-header">
<h4 class="card-title"><%- req?.locales?.privacyPolicy?.title || "Privacy Policy" %></h4>
<p class="category"><%- req?.locales?.privacyPolicy?.description || "Privacy Policy and Terms of Service" %></p>
</div>
<div class="card-body">
<% if (req?.locales?.privacyPolicy?.pp){ %>
<%- req.locales.privacyPolicy.pp %>
<% } else { %>
<p>Last updated: October 10, 2021</p>
<p>This Privacy Policy describes Our policies and procedures on the collection, use and
disclosure of Your information when You use the Service and tells You about Your
privacy
rights and how the law protects You.</p>
<p>We use Your Personal data to provide and improve the Service. By using the Service,
You
agree to the collection and use of information in accordance with this Privacy
Policy.
This Privacy Policy has been created with the help of the <a
href="https://www.termsfeed.com/privacy-policy-generator/" target="_blank">Privacy
Policy Generator</a>.</p>
<h1>Interpretation and Definitions</h1>
<h2>Interpretation</h2>
<p>The words of which the initial letter is capitalized have meanings defined under the
following conditions. The following definitions shall have the same meaning
regardless
of whether they appear in singular or in plural.</p>
<h2>Definitions</h2>
<p>For the purposes of this Privacy Policy:</p>
<ul>
<li>
<p><strong>Account</strong> means a unique account created for You to access our
Service or parts of our Service.</p>
</li>
<li>
<p><strong>Company</strong> (referred to as either "the Company", "We", "Us" or
"Our" in this Agreement) refers to <%= themeConfig.websiteName %>.</p>
</li>
<li>
<p><strong>Cookies</strong> are small files that are placed on Your computer,
mobile
device or any other device by a website, containing the details of Your
browsing
history on that website among its many uses.</p>
</li>
<li>
<p><strong>Country</strong> refers to: United Kingdom</p>
</li>
<li>
<p><strong>Device</strong> means any device that can access the Service such as
a
computer, a cellphone or a digital tablet.</p>
</li>
<li>
<p><strong>Personal Data</strong> is any information that relates to an
identified
or identifiable individual.</p>
</li>
<li>
<p><strong>Service</strong> refers to the Website.</p>
</li>
<li>
<p><strong>Service Provider</strong> means any natural or legal person who
processes
the data on behalf of the Company. It refers to third-party companies or
individuals employed by the Company to facilitate the Service, to provide
the
Service on behalf of the Company, to perform services related to the Service
or
to assist the Company in analyzing how the Service is used.</p>
</li>
<li>
<p><strong>Third-party Social Media Service</strong> refers to any website or
any
social network website through which a User can log in or create an account
to
use the Service.</p>
</li>
<li>
<p><strong>Usage Data</strong> refers to data collected automatically, either
generated by the use of the Service or from the Service infrastructure
itself
(for example, the duration of a page visit).</p>
</li>
<li>
<p><strong>Website</strong> refers to <%= themeConfig.websiteName %>, accessible
from <a href="<%= config.domain %>" rel="external nofollow noopener"
target="_blank"><%= config.domain %></a></p>
</li>
<li>
<p><strong>You</strong> means the individual accessing or using the Service, or
the
company, or other legal entity on behalf of which such individual is
accessing
or using the Service, as applicable.</p>
</li>
</ul>
<h1>Collecting and Using Your Personal Data</h1>
<h2>Types of Data Collected</h2>
<h3>Personal Data</h3>
<p>While using Our Service, We may ask You to provide Us with certain personally
identifiable information that can be used to contact or identify You. Personally
identifiable information may include, but is not limited to:</p>
<ul>
<li>Usage Data</li>
</ul>
<h3>Usage Data</h3>
<p>Usage Data is collected automatically when using the Service.</p>
<p>Usage Data may include information such as Your Device's Internet Protocol address
(e.g.
IP address), browser type, browser version, the pages of our Service that You visit,
the
time and date of Your visit, the time spent on those pages, unique device
identifiers
and other diagnostic data.</p>
<p>When You access the Service by or through a mobile device, We may collect certain
information automatically, including, but not limited to, the type of mobile device
You
use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile
operating system, the type of mobile Internet browser You use, unique device
identifiers
and other diagnostic data.</p>
<p>We may also collect information that Your browser sends whenever You visit our
Service or
when You access the Service by or through a mobile device.</p>
<h3>Information from Third-Party Social Media Services</h3>
<p>The Company allows You to create an account and log in to use the Service through the
following Third-party Social Media Services:</p>
<ul>
<li>Google</li>
<li>Facebook</li>
<li>Twitter</li>
</ul>
<p>If You decide to register through or otherwise grant us access to a Third-Party
Social
Media Service, We may collect Personal data that is already associated with Your
Third-Party Social Media Service's account, such as Your name, Your email address,
Your
activities or Your contact list associated with that account.</p>
<p>You may also have the option of sharing additional information with the Company
through
Your Third-Party Social Media Service's account. If You choose to provide such
information and Personal Data, during registration or otherwise, You are giving the
Company permission to use, share, and store it in a manner consistent with this
Privacy
Policy.</p>
<h3>Tracking Technologies and Cookies</h3>
<p>We use Cookies and similar tracking technologies to track the activity on Our Service
and
store certain information. Tracking technologies used are beacons, tags, and scripts
to
collect and track information and to improve and analyze Our Service. The
technologies
We use may include:</p>
<ul>
<li><strong>Cookies or Browser Cookies.</strong> A cookie is a small file placed on
Your
Device. You can instruct Your browser to refuse all Cookies or to indicate when
a
Cookie is being sent. However, if You do not accept Cookies, You may not be able
to
use some parts of our Service. Unless you have adjusted Your browser setting so
that
it will refuse Cookies, our Service may use Cookies.
</li>
<li><strong>Flash Cookies.</strong> Certain features of our Service may use local
stored
objects (or Flash Cookies) to collect and store information about Your
preferences
or Your activity on our Service. Flash Cookies are not managed by the same
browser
settings as those used for Browser Cookies. For more information on how You can
delete Flash Cookies, please read "Where can I change the settings for
disabling, or
deleting local shared objects?" available at <a
href="https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_"
rel="external nofollow noopener" target="_blank">https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_</a>
</li>
<li><strong>Web Beacons.</strong> Certain sections of our Service and our emails may
contain small electronic files known as web beacons (also referred to as clear
gifs,
pixel tags, and single-pixel gifs) that permit the Company, for example, to
count
users who have visited those pages or opened an email and for other related
website
statistics (for example, recording the popularity of a certain section and
verifying
system and server integrity).
</li>
</ul>
<p>Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on Your
personal computer or mobile device when You go offline, while Session Cookies are
deleted as soon as You close Your web browser. You can learn more about cookies
here: <a
href="https://www.termsfeed.com/privacy-policy-generator/#faq-8"
target="_blank">Cookies by TermsFeed Generator</a>.</p>
<p>We use both Session and Persistent Cookies for the purposes set out below:</p>
<ul>
<li>
<p><strong>Necessary / Essential Cookies</strong></p>
<p>Type: Session Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies are essential to provide You with services available
through the Website and to enable You to use some of its features. They help
to
authenticate users and prevent fraudulent use of user accounts. Without
these
Cookies, the services that You have asked for cannot be provided, and We
only
use these Cookies to provide You with those services.</p>
</li>
<li>
<p><strong>Cookies Policy / Notice Acceptance Cookies</strong></p>
<p>Type: Persistent Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies identify if users have accepted the use of cookies on
the
Website.</p>
</li>
<li>
<p><strong>Functionality Cookies</strong></p>
<p>Type: Persistent Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies allow us to remember choices You make when You use the
Website, such as remembering your login details or language preference. The
purpose of these Cookies is to provide You with a more personal experience
and
to avoid You having to re-enter your preferences every time You use the
Website.</p>
</li>
</ul>
<p>For more information about the cookies we use and your choices regarding cookies,
please
visit our Cookies Policy or the Cookies section of our Privacy Policy.</p>
<h2>Use of Your Personal Data</h2>
<p>The Company may use Personal Data for the following purposes:</p>
<ul>
<li>
<p><strong>To provide and maintain our Service</strong>, including to monitor
the
usage of our Service.</p>
</li>
<li>
<p><strong>To manage Your Account:</strong> to manage Your registration as a
user of
the Service. The Personal Data You provide can give You access to different
functionalities of the Service that are available to You as a registered
user.
</p>
</li>
<li>
<p><strong>For the performance of a contract:</strong> the development,
compliance
and undertaking of the purchase contract for the products, items or services
You
have purchased or of any other contract with Us through the Service.</p>
</li>
<li>
<p><strong>To contact You:</strong> To contact You by email, telephone calls,
SMS,
or other equivalent forms of electronic communication, such as a mobile
application's push notifications regarding updates or informative
communications
related to the functionalities, products or contracted services, including
the
security updates, when necessary or reasonable for their implementation.</p>
</li>
<li>
<p><strong>To provide You</strong> with news, special offers and general
information
about other goods, services and events which we offer that are similar to
those
that you have already purchased or enquired about unless You have opted not
to
receive such information.</p>
</li>
<li>
<p><strong>To manage Your requests:</strong> To attend and manage Your requests
to
Us.</p>
</li>
<li>
<p><strong>For business transfers:</strong> We may use Your information to
evaluate
or conduct a merger, divestiture, restructuring, reorganization,
dissolution, or
other sale or transfer of some or all of Our assets, whether as a going
concern
or as part of bankruptcy, liquidation, or similar proceeding, in which
Personal
Data held by Us about our Service users is among the assets transferred.</p>
</li>
<li>
<p><strong>For other purposes</strong>: We may use Your information for other
purposes, such as data analysis, identifying usage trends, determining the
effectiveness of our promotional campaigns and to evaluate and improve our
Service, products, services, marketing and your experience.</p>
</li>
</ul>
<p>We may share Your personal information in the following situations:</p>
<ul>
<li><strong>With Service Providers:</strong> We may share Your personal information
with
Service Providers to monitor and analyze the use of our Service, to contact You.
</li>
<li><strong>For business transfers:</strong> We may share or transfer Your personal
information in connection with, or during negotiations of, any merger, sale of
Company assets, financing, or acquisition of all or a portion of Our business to
another company.
</li>
<li><strong>With Affiliates:</strong> We may share Your information with Our
affiliates,
in which case we will require those affiliates to honor this Privacy Policy.
Affiliates include Our parent company and any other subsidiaries, joint venture
partners or other companies that We control or that are under common control
with
Us.
</li>
<li><strong>With business partners:</strong> We may share Your information with Our
business partners to offer You certain products, services or promotions.
</li>
<li><strong>With other users:</strong> when You share personal information or
otherwise
interact in the public areas with other users, such information may be viewed by
all
users and may be publicly distributed outside. If You interact with other users
or
register through a Third-Party Social Media Service, Your contacts on the
Third-Party Social Media Service may see Your name, profile, pictures and
description of Your activity. Similarly, other users will be able to view
descriptions of Your activity, communicate with You and view Your profile.
</li>
<li><strong>With Your consent</strong>: We may disclose Your personal information
for
any other purpose with Your consent.
</li>
</ul>
<h2>Retention of Your Personal Data</h2>
<p>The Company will retain Your Personal Data only for as long as is necessary for the
purposes set out in this Privacy Policy. We will retain and use Your Personal Data
to
the extent necessary to comply with our legal obligations (for example, if we are
required to retain your data to comply with applicable laws), resolve disputes, and
enforce our legal agreements and policies.</p>
<p>The Company will also retain Usage Data for internal analysis purposes. Usage Data is
generally retained for a shorter period of time, except when this data is used to
strengthen the security or to improve the functionality of Our Service, or We are
legally obligated to retain this data for longer time periods.</p>
<h2>Transfer of Your Personal Data</h2>
<p>Your information, including Personal Data, is processed at the Company's operating
offices and in any other places where the parties involved in the processing are
located. It means that this information may be transferred to — and maintained on —
computers located outside of Your state, province, country or other governmental
jurisdiction where the data protection laws may differ than those from Your
jurisdiction.</p>
<p>Your consent to this Privacy Policy followed by Your submission of such information
represents Your agreement to that transfer.</p>
<p>The Company will take all steps reasonably necessary to ensure that Your data is
treated
securely and in accordance with this Privacy Policy and no transfer of Your Personal
Data will take place to an organization or a country unless there are adequate
controls
in place including the security of Your data and other personal information.</p>
<h2>Disclosure of Your Personal Data</h2>
<h3>Business Transactions</h3>
<p>If the Company is involved in a merger, acquisition or asset sale, Your Personal Data
may
be transferred. We will provide notice before Your Personal Data is transferred and
becomes subject to a different Privacy Policy.</p>
<h3>Law enforcement</h3>
<p>Under certain circumstances, the Company may be required to disclose Your Personal
Data
if required to do so by law or in response to valid requests by public authorities
(e.g.
a court or a government agency).</p>
<h3>Other legal requirements</h3>
<p>The Company may disclose Your Personal Data in the good faith belief that such action
is
necessary to:</p>
<ul>
<li>Comply with a legal obligation</li>
<li>Protect and defend the rights or property of the Company</li>
<li>Prevent or investigate possible wrongdoing in connection with the Service</li>
<li>Protect the personal safety of Users of the Service or the public</li>
<li>Protect against legal liability</li>
</ul>
<h2>Security of Your Personal Data</h2>
<p>The security of Your Personal Data is important to Us, but remember that no method of
transmission over the Internet, or method of electronic storage is 100% secure.
While We
strive to use commercially acceptable means to protect Your Personal Data, We cannot
guarantee its absolute security.</p>
<h1>Children's Privacy</h1>
<p>Our Service does not address anyone under the age of 13. We do not knowingly collect
personally identifiable information from anyone under the age of 13. If You are a
parent
or guardian and You are aware that Your child has provided Us with Personal Data,
please
contact Us. If We become aware that We have collected Personal Data from anyone
under
the age of 13 without verification of parental consent, We take steps to remove that
information from Our servers.</p>
<p>If We need to rely on consent as a legal basis for processing Your information and
Your
country requires consent from a parent, We may require Your parent's consent before
We
collect and use that information.</p>
<h1>Links to Other Websites</h1>
<p>Our Service may contain links to other websites that are not operated by Us. If You
click
on a third party link, You will be directed to that third party's site. We strongly
advise You to review the Privacy Policy of every site You visit.</p>
<p>We have no control over and assume no responsibility for the content, privacy
policies or
practices of any third party sites or services.</p>
<h1>Changes to this Privacy Policy</h1>
<p>We may update Our Privacy Policy from time to time. We will notify You of any changes
by
posting the new Privacy Policy on this page.</p>
<p>We will let You know via email and/or a prominent notice on Our Service, prior to the
change becoming effective and update the "Last updated" date at the top of this
Privacy
Policy.</p>
<p>You are advised to review this Privacy Policy periodically for any changes. Changes
to
this Privacy Policy are effective when they are posted on this page.</p>
<h1>Contact Us</h1>
<p>If you have any questions about this Privacy Policy, You can contact us:</p>
<ul>
<li>By email: <a
href="mailto: <%= themeConfig.supporteMail %>"><%= themeConfig.supporteMail %></a>
</li>
<% } %>
</div>
</div>
</div>
</div>
</div>
<%- include('partials/footer.ejs', {now: 'pp'}) %>
</div>
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now: 'pp'}) %>
<!-- End Navbar -->
<div class="container-fluid py-4">
<div class="content">
<div class="row">
<div class="col-md-12 mb-4">
<div class="card">
<div class="card-header">
<h4 class="card-title"><%- req?.locales?.privacyPolicy?.title || "Privacy Policy" %></h4>
<p class="category"><%- req?.locales?.privacyPolicy?.description || "Privacy Policy and Terms of Service" %></p>
</div>
<div class="card-body">
<% if (req?.locales?.privacyPolicy?.pp){ %>
<%- req.locales.privacyPolicy.pp %>
<% } else { %>
<p>Last updated: October 10, 2021</p>
<p>This Privacy Policy describes Our policies and procedures on the collection, use and
disclosure of Your information when You use the Service and tells You about Your
privacy
rights and how the law protects You.</p>
<p>We use Your Personal data to provide and improve the Service. By using the Service,
You
agree to the collection and use of information in accordance with this Privacy
Policy.
This Privacy Policy has been created with the help of the <a
href="https://www.termsfeed.com/privacy-policy-generator/" target="_blank">Privacy
Policy Generator</a>.</p>
<h1>Interpretation and Definitions</h1>
<h2>Interpretation</h2>
<p>The words of which the initial letter is capitalized have meanings defined under the
following conditions. The following definitions shall have the same meaning
regardless
of whether they appear in singular or in plural.</p>
<h2>Definitions</h2>
<p>For the purposes of this Privacy Policy:</p>
<ul>
<li>
<p><strong>Account</strong> means a unique account created for You to access our
Service or parts of our Service.</p>
</li>
<li>
<p><strong>Company</strong> (referred to as either "the Company", "We", "Us" or
"Our" in this Agreement) refers to <%= themeConfig.websiteName %>.</p>
</li>
<li>
<p><strong>Cookies</strong> are small files that are placed on Your computer,
mobile
device or any other device by a website, containing the details of Your
browsing
history on that website among its many uses.</p>
</li>
<li>
<p><strong>Country</strong> refers to: United Kingdom</p>
</li>
<li>
<p><strong>Device</strong> means any device that can access the Service such as
a
computer, a cellphone or a digital tablet.</p>
</li>
<li>
<p><strong>Personal Data</strong> is any information that relates to an
identified
or identifiable individual.</p>
</li>
<li>
<p><strong>Service</strong> refers to the Website.</p>
</li>
<li>
<p><strong>Service Provider</strong> means any natural or legal person who
processes
the data on behalf of the Company. It refers to third-party companies or
individuals employed by the Company to facilitate the Service, to provide
the
Service on behalf of the Company, to perform services related to the Service
or
to assist the Company in analyzing how the Service is used.</p>
</li>
<li>
<p><strong>Third-party Social Media Service</strong> refers to any website or
any
social network website through which a User can log in or create an account
to
use the Service.</p>
</li>
<li>
<p><strong>Usage Data</strong> refers to data collected automatically, either
generated by the use of the Service or from the Service infrastructure
itself
(for example, the duration of a page visit).</p>
</li>
<li>
<p><strong>Website</strong> refers to <%= themeConfig.websiteName %>, accessible
from <a href="<%= config.domain %>" rel="external nofollow noopener"
target="_blank"><%= config.domain %></a></p>
</li>
<li>
<p><strong>You</strong> means the individual accessing or using the Service, or
the
company, or other legal entity on behalf of which such individual is
accessing
or using the Service, as applicable.</p>
</li>
</ul>
<h1>Collecting and Using Your Personal Data</h1>
<h2>Types of Data Collected</h2>
<h3>Personal Data</h3>
<p>While using Our Service, We may ask You to provide Us with certain personally
identifiable information that can be used to contact or identify You. Personally
identifiable information may include, but is not limited to:</p>
<ul>
<li>Usage Data</li>
</ul>
<h3>Usage Data</h3>
<p>Usage Data is collected automatically when using the Service.</p>
<p>Usage Data may include information such as Your Device's Internet Protocol address
(e.g.
IP address), browser type, browser version, the pages of our Service that You visit,
the
time and date of Your visit, the time spent on those pages, unique device
identifiers
and other diagnostic data.</p>
<p>When You access the Service by or through a mobile device, We may collect certain
information automatically, including, but not limited to, the type of mobile device
You
use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile
operating system, the type of mobile Internet browser You use, unique device
identifiers
and other diagnostic data.</p>
<p>We may also collect information that Your browser sends whenever You visit our
Service or
when You access the Service by or through a mobile device.</p>
<h3>Information from Third-Party Social Media Services</h3>
<p>The Company allows You to create an account and log in to use the Service through the
following Third-party Social Media Services:</p>
<ul>
<li>Google</li>
<li>Facebook</li>
<li>Twitter</li>
</ul>
<p>If You decide to register through or otherwise grant us access to a Third-Party
Social
Media Service, We may collect Personal data that is already associated with Your
Third-Party Social Media Service's account, such as Your name, Your email address,
Your
activities or Your contact list associated with that account.</p>
<p>You may also have the option of sharing additional information with the Company
through
Your Third-Party Social Media Service's account. If You choose to provide such
information and Personal Data, during registration or otherwise, You are giving the
Company permission to use, share, and store it in a manner consistent with this
Privacy
Policy.</p>
<h3>Tracking Technologies and Cookies</h3>
<p>We use Cookies and similar tracking technologies to track the activity on Our Service
and
store certain information. Tracking technologies used are beacons, tags, and scripts
to
collect and track information and to improve and analyze Our Service. The
technologies
We use may include:</p>
<ul>
<li><strong>Cookies or Browser Cookies.</strong> A cookie is a small file placed on
Your
Device. You can instruct Your browser to refuse all Cookies or to indicate when
a
Cookie is being sent. However, if You do not accept Cookies, You may not be able
to
use some parts of our Service. Unless you have adjusted Your browser setting so
that
it will refuse Cookies, our Service may use Cookies.
</li>
<li><strong>Flash Cookies.</strong> Certain features of our Service may use local
stored
objects (or Flash Cookies) to collect and store information about Your
preferences
or Your activity on our Service. Flash Cookies are not managed by the same
browser
settings as those used for Browser Cookies. For more information on how You can
delete Flash Cookies, please read "Where can I change the settings for
disabling, or
deleting local shared objects?" available at <a
href="https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_"
rel="external nofollow noopener" target="_blank">https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_</a>
</li>
<li><strong>Web Beacons.</strong> Certain sections of our Service and our emails may
contain small electronic files known as web beacons (also referred to as clear
gifs,
pixel tags, and single-pixel gifs) that permit the Company, for example, to
count
users who have visited those pages or opened an email and for other related
website
statistics (for example, recording the popularity of a certain section and
verifying
system and server integrity).
</li>
</ul>
<p>Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on Your
personal computer or mobile device when You go offline, while Session Cookies are
deleted as soon as You close Your web browser. You can learn more about cookies
here: <a
href="https://www.termsfeed.com/privacy-policy-generator/#faq-8"
target="_blank">Cookies by TermsFeed Generator</a>.</p>
<p>We use both Session and Persistent Cookies for the purposes set out below:</p>
<ul>
<li>
<p><strong>Necessary / Essential Cookies</strong></p>
<p>Type: Session Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies are essential to provide You with services available
through the Website and to enable You to use some of its features. They help
to
authenticate users and prevent fraudulent use of user accounts. Without
these
Cookies, the services that You have asked for cannot be provided, and We
only
use these Cookies to provide You with those services.</p>
</li>
<li>
<p><strong>Cookies Policy / Notice Acceptance Cookies</strong></p>
<p>Type: Persistent Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies identify if users have accepted the use of cookies on
the
Website.</p>
</li>
<li>
<p><strong>Functionality Cookies</strong></p>
<p>Type: Persistent Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies allow us to remember choices You make when You use the
Website, such as remembering your login details or language preference. The
purpose of these Cookies is to provide You with a more personal experience
and
to avoid You having to re-enter your preferences every time You use the
Website.</p>
</li>
</ul>
<p>For more information about the cookies we use and your choices regarding cookies,
please
visit our Cookies Policy or the Cookies section of our Privacy Policy.</p>
<h2>Use of Your Personal Data</h2>
<p>The Company may use Personal Data for the following purposes:</p>
<ul>
<li>
<p><strong>To provide and maintain our Service</strong>, including to monitor
the
usage of our Service.</p>
</li>
<li>
<p><strong>To manage Your Account:</strong> to manage Your registration as a
user of
the Service. The Personal Data You provide can give You access to different
functionalities of the Service that are available to You as a registered
user.
</p>
</li>
<li>
<p><strong>For the performance of a contract:</strong> the development,
compliance
and undertaking of the purchase contract for the products, items or services
You
have purchased or of any other contract with Us through the Service.</p>
</li>
<li>
<p><strong>To contact You:</strong> To contact You by email, telephone calls,
SMS,
or other equivalent forms of electronic communication, such as a mobile
application's push notifications regarding updates or informative
communications
related to the functionalities, products or contracted services, including
the
security updates, when necessary or reasonable for their implementation.</p>
</li>
<li>
<p><strong>To provide You</strong> with news, special offers and general
information
about other goods, services and events which we offer that are similar to
those
that you have already purchased or enquired about unless You have opted not
to
receive such information.</p>
</li>
<li>
<p><strong>To manage Your requests:</strong> To attend and manage Your requests
to
Us.</p>
</li>
<li>
<p><strong>For business transfers:</strong> We may use Your information to
evaluate
or conduct a merger, divestiture, restructuring, reorganization,
dissolution, or
other sale or transfer of some or all of Our assets, whether as a going
concern
or as part of bankruptcy, liquidation, or similar proceeding, in which
Personal
Data held by Us about our Service users is among the assets transferred.</p>
</li>
<li>
<p><strong>For other purposes</strong>: We may use Your information for other
purposes, such as data analysis, identifying usage trends, determining the
effectiveness of our promotional campaigns and to evaluate and improve our
Service, products, services, marketing and your experience.</p>
</li>
</ul>
<p>We may share Your personal information in the following situations:</p>
<ul>
<li><strong>With Service Providers:</strong> We may share Your personal information
with
Service Providers to monitor and analyze the use of our Service, to contact You.
</li>
<li><strong>For business transfers:</strong> We may share or transfer Your personal
information in connection with, or during negotiations of, any merger, sale of
Company assets, financing, or acquisition of all or a portion of Our business to
another company.
</li>
<li><strong>With Affiliates:</strong> We may share Your information with Our
affiliates,
in which case we will require those affiliates to honor this Privacy Policy.
Affiliates include Our parent company and any other subsidiaries, joint venture
partners or other companies that We control or that are under common control
with
Us.
</li>
<li><strong>With business partners:</strong> We may share Your information with Our
business partners to offer You certain products, services or promotions.
</li>
<li><strong>With other users:</strong> when You share personal information or
otherwise
interact in the public areas with other users, such information may be viewed by
all
users and may be publicly distributed outside. If You interact with other users
or
register through a Third-Party Social Media Service, Your contacts on the
Third-Party Social Media Service may see Your name, profile, pictures and
description of Your activity. Similarly, other users will be able to view
descriptions of Your activity, communicate with You and view Your profile.
</li>
<li><strong>With Your consent</strong>: We may disclose Your personal information
for
any other purpose with Your consent.
</li>
</ul>
<h2>Retention of Your Personal Data</h2>
<p>The Company will retain Your Personal Data only for as long as is necessary for the
purposes set out in this Privacy Policy. We will retain and use Your Personal Data
to
the extent necessary to comply with our legal obligations (for example, if we are
required to retain your data to comply with applicable laws), resolve disputes, and
enforce our legal agreements and policies.</p>
<p>The Company will also retain Usage Data for internal analysis purposes. Usage Data is
generally retained for a shorter period of time, except when this data is used to
strengthen the security or to improve the functionality of Our Service, or We are
legally obligated to retain this data for longer time periods.</p>
<h2>Transfer of Your Personal Data</h2>
<p>Your information, including Personal Data, is processed at the Company's operating
offices and in any other places where the parties involved in the processing are
located. It means that this information may be transferred to — and maintained on —
computers located outside of Your state, province, country or other governmental
jurisdiction where the data protection laws may differ than those from Your
jurisdiction.</p>
<p>Your consent to this Privacy Policy followed by Your submission of such information
represents Your agreement to that transfer.</p>
<p>The Company will take all steps reasonably necessary to ensure that Your data is
treated
securely and in accordance with this Privacy Policy and no transfer of Your Personal
Data will take place to an organization or a country unless there are adequate
controls
in place including the security of Your data and other personal information.</p>
<h2>Disclosure of Your Personal Data</h2>
<h3>Business Transactions</h3>
<p>If the Company is involved in a merger, acquisition or asset sale, Your Personal Data
may
be transferred. We will provide notice before Your Personal Data is transferred and
becomes subject to a different Privacy Policy.</p>
<h3>Law enforcement</h3>
<p>Under certain circumstances, the Company may be required to disclose Your Personal
Data
if required to do so by law or in response to valid requests by public authorities
(e.g.
a court or a government agency).</p>
<h3>Other legal requirements</h3>
<p>The Company may disclose Your Personal Data in the good faith belief that such action
is
necessary to:</p>
<ul>
<li>Comply with a legal obligation</li>
<li>Protect and defend the rights or property of the Company</li>
<li>Prevent or investigate possible wrongdoing in connection with the Service</li>
<li>Protect the personal safety of Users of the Service or the public</li>
<li>Protect against legal liability</li>
</ul>
<h2>Security of Your Personal Data</h2>
<p>The security of Your Personal Data is important to Us, but remember that no method of
transmission over the Internet, or method of electronic storage is 100% secure.
While We
strive to use commercially acceptable means to protect Your Personal Data, We cannot
guarantee its absolute security.</p>
<h1>Children's Privacy</h1>
<p>Our Service does not address anyone under the age of 13. We do not knowingly collect
personally identifiable information from anyone under the age of 13. If You are a
parent
or guardian and You are aware that Your child has provided Us with Personal Data,
please
contact Us. If We become aware that We have collected Personal Data from anyone
under
the age of 13 without verification of parental consent, We take steps to remove that
information from Our servers.</p>
<p>If We need to rely on consent as a legal basis for processing Your information and
Your
country requires consent from a parent, We may require Your parent's consent before
We
collect and use that information.</p>
<h1>Links to Other Websites</h1>
<p>Our Service may contain links to other websites that are not operated by Us. If You
click
on a third party link, You will be directed to that third party's site. We strongly
advise You to review the Privacy Policy of every site You visit.</p>
<p>We have no control over and assume no responsibility for the content, privacy
policies or
practices of any third party sites or services.</p>
<h1>Changes to this Privacy Policy</h1>
<p>We may update Our Privacy Policy from time to time. We will notify You of any changes
by
posting the new Privacy Policy on this page.</p>
<p>We will let You know via email and/or a prominent notice on Our Service, prior to the
change becoming effective and update the "Last updated" date at the top of this
Privacy
Policy.</p>
<p>You are advised to review this Privacy Policy periodically for any changes. Changes
to
this Privacy Policy are effective when they are posted on this page.</p>
<h1>Contact Us</h1>
<p>If you have any questions about this Privacy Policy, You can contact us:</p>
<ul>
<li>By email: <a
href="mailto: <%= themeConfig.supporteMail %>"><%= themeConfig.supporteMail %></a>
</li>
<% } %>
</div>
</div>
</div>
</div>
</div>
<%- include('partials/footer.ejs', {now: 'pp'}) %>
</div>
</div>
<%- include('partials/scripts.ejs', {now: "pp"}) %>
</body>

View file

@ -1,451 +1,436 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/preloader.ejs', {now:'settings'}) %>
<link href='/css/dashboard/settings.css' rel='stylesheet'>
<%- themeConfig?.customHtml %>
<%- include("partials/preloader.ejs", {now:"settings"}) %>
<link href="/css/dashboard/settings.css" rel="stylesheet">
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100">
<%- include('partials/preload.ejs') %>
<aside
class="sidenav navbar navbar-vertical navbar-expand-xs border-0 border-radius-xl my-3 fixed-start ms-3 ps"
style="float:left;" id="sidenav-main">
<div id="sidebarMain">
<div class="sidenav-header">
<a onclick="toggleSidenav()"><i
class="fas fa-times p-3 cursor-pointer text-secondary opacity-5 position-absolute end-0 top-0 d-none d-xl-none"
aria-hidden="true" id="iconSidenav"></i></a>
<a <% if(themeConfig?.icons?.sidebar?.alignCenter) { %> style="text-align: center;"
<% } %>
class="navbar-brand m-0" href="/">
<img src="<%= themeConfig.icons.sidebar.lightUrl %>" class="navbar-brand-img h-100" <%
if(themeConfig.icons.sidebar.borderRadius) { %>style="border-radius: <%-
themeConfig.icons.sidebar.borderRadius %>;"
<% } %>
alt="main_logo">
<% if(!themeConfig.icons.sidebar.hideName){ %>
<span class="ms-1 font-weight-bold" id="sitename">
<%= themeConfig.websiteName %>
</span>
<% } %>
</a>
</div>
<hr class="horizontal dark mt-0">
<div class="collapse navbar-collapse w-auto max-height-vh-80 h-80" id="sidenav-collapse-main">
<ul class="navbar-nav">
<li class="nav-item" style="text-align: center;">
<div class="configIcon border-radius-xl"
style="margin: 0 auto;width: fit-content;text-align: center;">
<img class="border-radius-xl" style="width: 100px; padding: 10px;"
src="<%= gIcon %>?size=64" alt="">
</div>
<h5 style="margin-top: 10px;">
<%= guild.name %>
</h5>
<p style="margin: 0 !important;"><i class="fa fa-user-friends" aria-hidden="true"></i>
<%= guild.memberCount %> Members
</p>
</li>
<li class="nav-item mt-3">
<a class="nav-link <% if(!req.params.category) { %>active<% } %>"
href="/settings/<%- req.params.id %>/">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 45 40" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>shop </title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-1716.000000, -439.000000)"
fill="#FFFFFF" fill-rule="nonzero">
<g id="Icons-with-opacity"
transform="translate(1716.000000, 291.000000)">
<g id="shop-" transform="translate(0.000000, 148.000000)">
<path class="color-background"
d="M46.7199583,10.7414583 L40.8449583,0.949791667 C40.4909749,0.360605034 39.8540131,0 39.1666667,0 L7.83333333,0 C7.1459869,0 6.50902508,0.360605034 6.15504167,0.949791667 L0.280041667,10.7414583 C0.0969176761,11.0460037 -1.23209662e-05,11.3946378 -1.23209662e-05,11.75 C-0.00758042603,16.0663731 3.48367543,19.5725301 7.80004167,19.5833333 L7.81570833,19.5833333 C9.75003686,19.5882688 11.6168794,18.8726691 13.0522917,17.5760417 C16.0171492,20.2556967 20.5292675,20.2556967 23.494125,17.5760417 C26.4604562,20.2616016 30.9794188,20.2616016 33.94575,17.5760417 C36.2421905,19.6477597 39.5441143,20.1708521 42.3684437,18.9103691 C45.1927731,17.649886 47.0084685,14.8428276 47.0000295,11.75 C47.0000295,11.3946378 46.9030823,11.0460037 46.7199583,10.7414583 Z"
id="Path" opacity="0.598981585"></path>
<path class="color-background"
d="M39.198,22.4912623 C37.3776246,22.4928106 35.5817531,22.0149171 33.951625,21.0951667 L33.92225,21.1107282 C31.1430221,22.6838032 27.9255001,22.9318916 24.9844167,21.7998837 C24.4750389,21.605469 23.9777983,21.3722567 23.4960833,21.1018359 L23.4745417,21.1129513 C20.6961809,22.6871153 17.4786145,22.9344611 14.5386667,21.7998837 C14.029926,21.6054643 13.533337,21.3722507 13.0522917,21.1018359 C11.4250962,22.0190609 9.63246555,22.4947009 7.81570833,22.4912623 C7.16510551,22.4842162 6.51607673,22.4173045 5.875,22.2911849 L5.875,44.7220845 C5.875,45.9498589 6.7517757,46.9451667 7.83333333,46.9451667 L19.5833333,46.9451667 L19.5833333,33.6066734 L27.4166667,33.6066734 L27.4166667,46.9451667 L39.1666667,46.9451667 C40.2482243,46.9451667 41.125,45.9498589 41.125,44.7220845 L41.125,22.2822926 C40.4887822,22.4116582 39.8442868,22.4815492 39.198,22.4912623 Z"
id="Path"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1">Home</span>
</a>
</li>
<li class="nav-item mt-3">
<h6 class="ps-4 ms-2 text-uppercase text-xs font-weight-bolder opacity-6">Settings
Categories</h6>
</li>
<% settings.forEach(s=> { %>
<a class="<%- s.categoryId %>">
<% if(s.premium) { %>
<div class="sidebarPremium"><i style="color: var(--colone) !important;"
class="fas fa-crown"></i></div>
<% } %>
<li class="nav-item categories" id="<%- s.categoryId %>">
<a class="nav-link <% if (req.params.category == s.categoryId) { %>active<% } %>"
id="<%- s.categoryId %>">
<% if(s.categoryImageURL) { %>
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<img width="20px" src="<%= s.categoryImageURL %>">
</div>
<% } %>
<span class="nav-link-text ms-1">
<%- s.categoryName %>
</span>
<% if(s.toggleable) { %>
<span style="text-align: right; width: 100%;">
<div class="form-check form-switch ps-0"
style="float: right !important;">
<input name="<%- s.categoryId %>"
category="<%- s.categoryName %>" switch="true"
class="form-check-input ms-auto category-toggle"
style="height: 20px !important; margin-left: 10px !important;"
type="checkbox" id="switch-<%= s.categoryId %>"
<%=toggle[s.categoryId] ? "checked" : "" %>
<%- include("partials/preload.ejs") %>
<aside
class="sidenav navbar navbar-vertical navbar-expand-xs border-0 border-radius-xl my-3 fixed-start ms-3 ps"
style="float:left;" id="sidenav-main">
<div id="sidebarMain">
<div class="sidenav-header">
<a onclick="toggleSidenav()"><i
class="fas fa-times p-3 cursor-pointer text-secondary opacity-5 position-absolute end-0 top-0 d-none d-xl-none"
aria-hidden="true" id="iconSidenav"></i></a>
<a <% if(themeConfig?.icons?.sidebar?.alignCenter) { %> style="text-align: center;"
<% } %>
class="navbar-brand m-0" href="/">
<img src="<%= themeConfig.icons.sidebar.lightUrl %>" class="navbar-brand-img h-100" <%
if(themeConfig.icons.sidebar.borderRadius) { %>style="border-radius: <%-
themeConfig.icons.sidebar.borderRadius %>;"
<% } %>
alt="main_logo">
<% if(!themeConfig.icons.sidebar.hideName){ %>
<span class="ms-1 font-weight-bold" id="sitename">
<%= themeConfig.websiteName %>
</span>
<% } %>
</a>
</div>
<hr class="horizontal dark mt-0">
<div class="collapse navbar-collapse w-auto max-height-vh-80 h-80" id="sidenav-collapse-main">
<ul class="navbar-nav">
<li class="nav-item" style="text-align: center;">
<div class="configIcon border-radius-xl"
style="margin: 0 auto;width: fit-content;text-align: center;">
<img class="border-radius-xl" style="width: 100px; padding: 10px;"
src="<%= gIcon %>?size=64" alt="">
</div>
<h5 style="margin-top: 10px;">
<%= guild.name %>
</h5>
<p style="margin: 0 !important;"><i class="fa fa-user-friends" aria-hidden="true"></i>
<%= guild.memberCount %> Members
</p>
</li>
<li class="nav-item mt-3">
<a class="nav-link <% if(!req.params.category) { %>active<% } %>"
href="/settings/<%- req.params.id %>/">
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<svg class="text-dark" width="16px" height="16px" viewBox="0 0 45 40" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<title>shop </title>
<g id="Basic-Elements" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g id="Rounded-Icons" transform="translate(-1716.000000, -439.000000)"
fill="#FFFFFF" fill-rule="nonzero">
<g id="Icons-with-opacity"
transform="translate(1716.000000, 291.000000)">
<g id="shop-" transform="translate(0.000000, 148.000000)">
<path class="color-background"
d="M46.7199583,10.7414583 L40.8449583,0.949791667 C40.4909749,0.360605034 39.8540131,0 39.1666667,0 L7.83333333,0 C7.1459869,0 6.50902508,0.360605034 6.15504167,0.949791667 L0.280041667,10.7414583 C0.0969176761,11.0460037 -1.23209662e-05,11.3946378 -1.23209662e-05,11.75 C-0.00758042603,16.0663731 3.48367543,19.5725301 7.80004167,19.5833333 L7.81570833,19.5833333 C9.75003686,19.5882688 11.6168794,18.8726691 13.0522917,17.5760417 C16.0171492,20.2556967 20.5292675,20.2556967 23.494125,17.5760417 C26.4604562,20.2616016 30.9794188,20.2616016 33.94575,17.5760417 C36.2421905,19.6477597 39.5441143,20.1708521 42.3684437,18.9103691 C45.1927731,17.649886 47.0084685,14.8428276 47.0000295,11.75 C47.0000295,11.3946378 46.9030823,11.0460037 46.7199583,10.7414583 Z"
id="Path" opacity="0.598981585"></path>
<path class="color-background"
d="M39.198,22.4912623 C37.3776246,22.4928106 35.5817531,22.0149171 33.951625,21.0951667 L33.92225,21.1107282 C31.1430221,22.6838032 27.9255001,22.9318916 24.9844167,21.7998837 C24.4750389,21.605469 23.9777983,21.3722567 23.4960833,21.1018359 L23.4745417,21.1129513 C20.6961809,22.6871153 17.4786145,22.9344611 14.5386667,21.7998837 C14.029926,21.6054643 13.533337,21.3722507 13.0522917,21.1018359 C11.4250962,22.0190609 9.63246555,22.4947009 7.81570833,22.4912623 C7.16510551,22.4842162 6.51607673,22.4173045 5.875,22.2911849 L5.875,44.7220845 C5.875,45.9498589 6.7517757,46.9451667 7.83333333,46.9451667 L19.5833333,46.9451667 L19.5833333,33.6066734 L27.4166667,33.6066734 L27.4166667,46.9451667 L39.1666667,46.9451667 C40.2482243,46.9451667 41.125,45.9498589 41.125,44.7220845 L41.125,22.2822926 C40.4887822,22.4116582 39.8442868,22.4815492 39.198,22.4912623 Z"
id="Path"></path>
</g>
</g>
</g>
</g>
</svg>
</div>
<span class="nav-link-text ms-1">Home</span>
</a>
</li>
<li class="nav-item mt-3">
<h6 class="ps-4 ms-2 text-uppercase text-xs font-weight-bolder opacity-6">Settings
Categories</h6>
</li>
<% settings.forEach(s=> { %>
<a class="<%- s.categoryId %>">
<% if(s.premium) { %>
<div class="sidebarPremium"><i style="color: var(--colone) !important;"
class="fas fa-crown"></i></div>
<% } %>
<li class="nav-item categories" id="<%- s.categoryId %>">
<a class="nav-link <% if (req.params.category == s.categoryId) { %>active<% } %>"
id="<%- s.categoryId %>">
<% if(s.categoryImageURL) { %>
<div
class="icon icon-shape icon-sm shadow border-radius-md bg-white text-center me-2 d-flex align-items-center justify-content-center">
<img width="20px" src="<%= s.categoryImageURL %>">
</div>
<% } %>
<span class="nav-link-text ms-1">
<%- s.categoryName %>
</span>
<% if(s.toggleable) { %>
<span style="text-align: right; width: 100%;">
<div class="form-check form-switch ps-0"
style="float: right !important;">
<input name="<%- s.categoryId %>"
category="<%- s.categoryName %>" switch="true"
class="form-check-input ms-auto category-toggle"
style="height: 20px !important; margin-left: 10px !important;"
type="checkbox" id="switch-<%= s.categoryId %>"
<%=toggle[s.categoryId] ? "checked" : "" %>
>
<label style="z-index: 100; position: relative;"
class="form-check-label text-body ms-3 text-truncate w-80 mb-0 d-none"
for="switch-<%= s.categoryId %>"></label>
</div>
</span>
<% } %>
</a>
</li>
<% }) %>
>
<label style="z-index: 100; position: relative;"
class="form-check-label text-body ms-3 text-truncate w-80 mb-0 d-none"
for="switch-<%= s.categoryId %>"></label>
</div>
</span>
<% } %>
</a>
</li>
<% }) %>
</ul>
</div>
<% if(themeConfig?.premium && req.session.user) { %>
<div class="sidenav-footer mx-3 pb-4" style="position: absolute;bottom: 0;">
<%- include('partials/premium.ejs') %>
</div>
<% } %>
</ul>
</div>
<% if(themeConfig?.premium && req.session.user) { %>
<div class="sidenav-footer mx-3 pb-4" style="position: absolute;bottom: 0;">
<%- include("partials/premium.ejs") %>
</div>
<% } %>
</div>
</div>
</aside>
</aside>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<nav style="padding-bottom: 0;"
class="navbar navbar-main navbar-expand-lg px-0 mx-4 shadow-none border-radius-xl pb-4" id="navbarBlur"
navbar-scroll="false">
<div class="container-fluid py-1 px-3">
<nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent mb-0 pb-0 pt-1 px-0 me-sm-6 me-5">
<li class="breadcrumb-item text-sm"><a class="opacity-9 text-dark"
href="javascript:">Pages</a>
</li>
<li class="breadcrumb-item text-sm text-dark active" aria-current="page">Dashboard</li>
</ol>
<h6 class="font-weight-bolder mb-0">Manage Guilds</h6>
</nav>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<nav style="padding-bottom: 0;"
class="navbar navbar-main navbar-expand-lg px-0 mx-4 shadow-none border-radius-xl pb-4" id="navbarBlur"
navbar-scroll="false">
<div class="container-fluid py-1 px-3">
<nav aria-label="breadcrumb">
<ol class="breadcrumb bg-transparent mb-0 pb-0 pt-1 px-0 me-sm-6 me-5">
<li class="breadcrumb-item text-sm"><a class="opacity-9 text-dark"
href="javascript:">Pages</a>
</li>
<li class="breadcrumb-item text-sm text-dark active" aria-current="page">Dashboard</li>
</ol>
<h6 class="font-weight-bolder mb-0">Manage Guilds</h6>
</nav>
<div class="collapse navbar-collapse mt-sm-0 mt-2 me-md-0 me-sm-4" id="navbar">
<div class="ms-md-auto pe-md-3 d-flex align-items-center">
</div>
<ul class="navbar-nav justify-content-end">
<div class="_3a41" style="display: contents;">
<div class="collapse navbar-collapse mt-sm-0 mt-2 me-md-0 me-sm-4" id="navbar">
<div class="ms-md-auto pe-md-3 d-flex align-items-center">
</div>
<ul class="navbar-nav justify-content-end">
<div class="_3a41" style="display: contents;">
<% for(var i in req.session.guilds){ if((req.session.guilds[i].permissions &
0x00000020)==0x00000020){ if(bot.guilds.cache.get(req.session.guilds[i].id)){ const
g=bot.guilds.cache.get(req.session.guilds[i].id); let icon; if (!g.iconURL())
icon=themeConfig.icons.noGuildIcon; else icon=g.iconURL(); let gClass="server" ; if
(g.id===guild.id) gClass="server activeServer" ; %>
<a href="/settings/<%- g.id %>" style="padding-right: 10px;">
<div class="<%- gClass %>"><img height="64" width="64" src="<%- icon %>"
alt="<%- g.name %>"></div>
</a>
<% } } } %>
<a href="/manage">
<div class="server">
<div class="newServer"><i class="fa fa-plus"
style="margin: 0;position: absolute;top: 50%;left: 50%;-ms-transform: translate(-50%, -50%);transform: translate(-50%, -50%);"></i>
</div>
</div>
</a>
</div>
<li class="nav-item d-xl-none ps-3 d-flex align-items-center">
<a onclick="toggleSidenav()" style="cursor: pointer;" class="nav-link text-body p-0"
id="iconNavbarSidenav">
<div class="sidenav-toggler-inner">
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
</div>
</a>
</li>
</ul>
</div>
</div>
</nav>
<% const images=["curved-1", "curved-2" , "curved-3" , "curved-4" , "curved-5" , "curved-6" , "curved-7"
, "curved-8" , "curved-9" , "curved-10" , "curved-11" , "curved-12" , "curved-13" , "curved-14"
, "curved-15" , "curved-16" , "curved-17" , "curved-18" ]; const image=images[Math.floor(Math.random() *
images.length)]; %>
<div class="container-fluid">
<div class="page-header min-height-300 border-radius-xl mt-4"
style="background-image: url('/img/curved-images/<%- image %>.webp'); background-position-y: 50%;">
<span class="mask bg-gradient-primary opacity-6"></span>
</div>
<div class="card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
<div class="row gx-4">
<% if(gIcon) { %>
<div class="col-auto">
<div class="avatar avatar-xl position-relative">
<img id="img" src="<%= gIcon %>" alt="profile_image"
class="w-100 border-radius-lg shadow-sm">
</div>
</div>
<% } %>
<div class="col-auto my-auto">
<div class="h-100">
<h5 id="title" class="mb-1">
<%= guild.name %>
</h5>
<p id="desc" class="mb-0 font-weight-bold text-sm">
<b>Server ID: </b>
<%= guild.id %>
</p>
</div>
</div>
<% if (themeConfig.leaderboard) { %>
<div class="col-lg-4 col-md-6 my-sm-auto ms-sm-auto me-sm-0 mx-auto mt-3">
<div class="nav-wrapper position-relative end-0">
<ul class="nav nav-pills nav-fill p-1 bg-transparent" role="tablist">
<li class="nav-item">
<a class="nav-link mb-0 px-0 py-1"
href="/leaderboard/<%= req.params.id %>">
<svg class="text-dark" width="16px" height="16px"
viewBox="0 0 42 42" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g transform="translate(-2319.000000, -291.000000)"
fill="#FFFFFF" fill-rule="nonzero">
<g transform="translate(1716.000000, 291.000000)">
<g transform="translate(603.000000, 0.000000)">
<path class="color-background"
d="M22.7597136,19.3090182 L38.8987031,11.2395234 C39.3926816,10.9925342 39.592906,10.3918611 39.3459167,9.89788265 C39.249157,9.70436312 39.0922432,9.5474453 38.8987261,9.45068056 L20.2741875,0.1378125 L20.2741875,0.1378125 C19.905375,-0.04725 19.469625,-0.04725 19.0995,0.1378125 L3.1011696,8.13815822 C2.60720568,8.38517662 2.40701679,8.98586148 2.6540352,9.4798254 C2.75080129,9.67332903 2.90771305,9.83023153 3.10122239,9.9269862 L21.8652864,19.3090182 C22.1468139,19.4497819 22.4781861,19.4497819 22.7597136,19.3090182 Z">
</path>
<path class="color-background"
d="M23.625,22.429159 L23.625,39.8805372 C23.625,40.4328219 24.0727153,40.8805372 24.625,40.8805372 C24.7802551,40.8805372 24.9333778,40.8443874 25.0722402,40.7749511 L41.2741875,32.673375 L41.2741875,32.673375 C41.719125,32.4515625 42,31.9974375 42,31.5 L42,14.241659 C42,13.6893742 41.5522847,13.241659 41,13.241659 C40.8447549,13.241659 40.6916418,13.2778041 40.5527864,13.3472318 L24.1777864,21.5347318 C23.8390024,21.7041238 23.625,22.0503869 23.625,22.429159 Z"
opacity="0.7"></path>
<path class="color-background"
d="M20.4472136,21.5347318 L1.4472136,12.0347318 C0.953235098,11.7877425 0.352562058,11.9879669 0.105572809,12.4819454 C0.0361450918,12.6208008 6.47121774e-16,12.7739139 0,12.929159 L0,30.1875 L0,30.1875 C0,30.6849375 0.280875,31.1390625 0.7258125,31.3621875 L19.5528096,40.7750766 C20.0467945,41.0220531 20.6474623,40.8218132 20.8944388,40.3278283 C20.963859,40.1889789 21,40.0358742 21,39.8806379 L21,22.429159 C21,22.0503869 20.7859976,21.7041238 20.4472136,21.5347318 Z"
opacity="0.7"></path>
</g>
</g>
</g>
</g>
</svg>
<span class="ms-1">Leaderboard</span>
</a>
</li>
</div>
</div>
<% } %>
</div>
</div>
<style>
.form-switch.larger .form-check-input:checked:after {
transform: scale(1.5) translate(23px, 3px);
}
<% for(var i in req.session.guilds){ if((req.session.guilds[i].permissions &
0x00000020)==0x00000020){ if(bot.guilds.cache.get(req.session.guilds[i].id)){ const
g=bot.guilds.cache.get(req.session.guilds[i].id); let icon; if (!g.iconURL())
icon=themeConfig.icons.noGuildIcon; else icon=g.iconURL(); let gClass="server" ; if
(g.id===guild.id) gClass="server activeServer" ; %>
<a href="/settings/<%- g.id %>" style="padding-right: 10px;">
<div class="<%- gClass %>"><img height="64" width="64" src="<%- icon %>"
alt="<%- g.name %>"></div>
</a>
<% } } } %>
<a href="/manage">
<div class="server">
<div class="newServer"><i class="fa fa-plus"
style="margin: 0;position: absolute;top: 50%;left: 50%;-ms-transform: translate(-50%, -50%);transform: translate(-50%, -50%);"></i>
</div>
</div>
</a>
</div>
<li class="nav-item d-xl-none ps-3 d-flex align-items-center">
<a onclick="toggleSidenav()" style="cursor: pointer;" class="nav-link text-body p-0"
id="iconNavbarSidenav">
<div class="sidenav-toggler-inner">
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
</div>
</a>
</li>
</ul>
</div>
</div>
</nav>
<% const images=["curved-1", "curved-2" , "curved-3" , "curved-4" , "curved-5" , "curved-6" , "curved-7"
, "curved-8" , "curved-9" , "curved-10" , "curved-11" , "curved-12" , "curved-13" , "curved-14"
, "curved-15" , "curved-16" , "curved-17" , "curved-18" ]; const image=images[Math.floor(Math.random() *
images.length)]; %>
<div class="container-fluid">
<div class="page-header min-height-300 border-radius-xl mt-4"
style="background-image: url("/img/curved-images/<%- image %>.webp"); background-position-y: 50%;">
<span class="mask bg-gradient-primary opacity-6"></span>
</div>
<div class="card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
<div class="row gx-4">
<% if(gIcon) { %>
<div class="col-auto">
<div class="avatar avatar-xl position-relative">
<img id="img" src="<%= gIcon %>" alt="profile_image"
class="w-100 border-radius-lg shadow-sm">
</div>
</div>
<% } %>
<div class="col-auto my-auto">
<div class="h-100">
<h5 id="title" class="mb-1">
<%= guild.name %>
</h5>
<p id="desc" class="mb-0 font-weight-bold text-sm">
<b>Server ID: </b>
<%= guild.id %>
</p>
</div>
</div>
<% if (themeConfig.leaderboard) { %>
<div class="col-lg-4 col-md-6 my-sm-auto ms-sm-auto me-sm-0 mx-auto mt-3">
<div class="nav-wrapper position-relative end-0">
<ul class="nav nav-pills nav-fill p-1 bg-transparent" role="tablist">
<li class="nav-item">
<a class="nav-link mb-0 px-0 py-1"
href="/leaderboard/<%= req.params.id %>">
<svg class="text-dark" width="16px" height="16px"
viewBox="0 0 42 42" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<g transform="translate(-2319.000000, -291.000000)"
fill="#FFFFFF" fill-rule="nonzero">
<g transform="translate(1716.000000, 291.000000)">
<g transform="translate(603.000000, 0.000000)">
<path class="color-background"
d="M22.7597136,19.3090182 L38.8987031,11.2395234 C39.3926816,10.9925342 39.592906,10.3918611 39.3459167,9.89788265 C39.249157,9.70436312 39.0922432,9.5474453 38.8987261,9.45068056 L20.2741875,0.1378125 L20.2741875,0.1378125 C19.905375,-0.04725 19.469625,-0.04725 19.0995,0.1378125 L3.1011696,8.13815822 C2.60720568,8.38517662 2.40701679,8.98586148 2.6540352,9.4798254 C2.75080129,9.67332903 2.90771305,9.83023153 3.10122239,9.9269862 L21.8652864,19.3090182 C22.1468139,19.4497819 22.4781861,19.4497819 22.7597136,19.3090182 Z">
</path>
<path class="color-background"
d="M23.625,22.429159 L23.625,39.8805372 C23.625,40.4328219 24.0727153,40.8805372 24.625,40.8805372 C24.7802551,40.8805372 24.9333778,40.8443874 25.0722402,40.7749511 L41.2741875,32.673375 L41.2741875,32.673375 C41.719125,32.4515625 42,31.9974375 42,31.5 L42,14.241659 C42,13.6893742 41.5522847,13.241659 41,13.241659 C40.8447549,13.241659 40.6916418,13.2778041 40.5527864,13.3472318 L24.1777864,21.5347318 C23.8390024,21.7041238 23.625,22.0503869 23.625,22.429159 Z"
opacity="0.7"></path>
<path class="color-background"
d="M20.4472136,21.5347318 L1.4472136,12.0347318 C0.953235098,11.7877425 0.352562058,11.9879669 0.105572809,12.4819454 C0.0361450918,12.6208008 6.47121774e-16,12.7739139 0,12.929159 L0,30.1875 L0,30.1875 C0,30.6849375 0.280875,31.1390625 0.7258125,31.3621875 L19.5528096,40.7750766 C20.0467945,41.0220531 20.6474623,40.8218132 20.8944388,40.3278283 C20.963859,40.1889789 21,40.0358742 21,39.8806379 L21,22.429159 C21,22.0503869 20.7859976,21.7041238 20.4472136,21.5347318 Z"
opacity="0.7"></path>
</g>
</g>
</g>
</g>
</svg>
<span class="ms-1">Leaderboard</span>
</a>
</li>
</div>
</div>
<% } %>
</div>
</div>
<style>
.form-switch.larger .form-check-input:checked:after {
transform: scale(1.5) translate(23px, 3px);
}
.form-switch.larger .form-check-input::after {
transform: scale(1.5) translate(5px, 3px);
}
</style>
<% if (!req.params.category) { %>
<div class="container-fluid py-4 settings">
<div class="row">
<% settings.forEach(s=> { %>
<a style="color: inherit; text-decoration: none;" href="/settings/<%- req.params.id %>/<%= s.categoryId %>">
<div style="flex: 50%;" class="item" id="divtable">
<div class="card mb-4">
<div class="card-header d-flex"
style="border-radius: 10px; justify-content: space-between;">
<div>
<h4>
<%- s.categoryName %>
</h4>
<p>
<%- s.categoryDescription %>
</p>
</div>
<div>
<% if(s.toggleable) { %>
<span style="text-align: right; width: 100%;">
<div class="form-check form-switch ps-0 larger"
style="float: right !important;">
<input name="<%- s.categoryId %>"
category="<%- s.categoryName %>" switch="true"
class="form-check-input ms-auto category-toggle"
style="height: 20px !important; margin-left: 10px !important; height: 30px !important; width: 60px !important;"
type="checkbox" id="switch-<%= s.categoryId %>"
<%=toggle[s.categoryId] ? "checked" : "" %>
.form-switch.larger .form-check-input::after {
transform: scale(1.5) translate(5px, 3px);
}
</style>
<% if (!req.params.category) { %>
<div class="container-fluid py-4 settings">
<div class="row">
<% settings.forEach(s=> { %>
<a style="color: inherit; text-decoration: none;" href="/settings/<%- req.params.id %>/<%= s.categoryId %>">
<div style="flex: 50%;" class="item" id="divtable">
<div class="card mb-4">
<div class="card-header d-flex"
style="border-radius: 10px; justify-content: space-between;">
<div>
<h4>
<%- s.categoryName %>
</h4>
<p>
<%- s.categoryDescription %>
</p>
</div>
<div>
<% if(s.toggleable) { %>
<span style="text-align: right; width: 100%;">
<div class="form-check form-switch ps-0 larger"
style="float: right !important;">
<input name="<%- s.categoryId %>"
category="<%- s.categoryName %>" switch="true"
class="form-check-input ms-auto category-toggle"
style="height: 20px !important; margin-left: 10px !important; height: 30px !important; width: 60px !important;"
type="checkbox" id="switch-<%= s.categoryId %>"
<%=toggle[s.categoryId] ? "checked" : "" %>
>
<label style="z-index: 100; position: relative;"
class="form-check-label text-body ms-3 text-truncate w-80 mb-0 d-none"
for="switch-<%= s.categoryId %>"></label>
</div>
</span>
<% } %>
</div>
</div>
</div>
</div>
</a>
<% }) %>
</div>
</div>
<% } %>
</div>
<div style="padding-bottom: 100px;">
<% settings.forEach(s=> {
if (s.categoryId !== req.params.category) return;
%>
<script>
document.addEventListener("DOMContentLoaded", function () {
$(`#title`).html(`<%- s.categoryName %>`)
$(`#desc`).html(`<%- s.categoryDescription %>`)
<% if(s.categoryImageURL) { %>
$("#img").attr("src", `<%- s.categoryImageURL %>`);
<% } %>
});
</script>
<div class="container-fluid settings mb-4" id="<%= s.categoryId %>div">
<% s.categoryOptionsList.forEach( option=> {
let Allowed = canUseList[s.categoryId][option.optionId];
%>
>
<label style="z-index: 100; position: relative;"
class="form-check-label text-body ms-3 text-truncate w-80 mb-0 d-none"
for="switch-<%= s.categoryId %>"></label>
</div>
</span>
<% } %>
</div>
</div>
</div>
</div>
</a>
<% }) %>
</div>
</div>
<% } %>
</div>
<div style="padding-bottom: 100px;">
<% settings.forEach(s=> {
if (s.categoryId !== req.params.category) return;
%>
<script>
document.addEventListener("DOMContentLoaded", function () {
$(`#title`).html(`<%- s.categoryName %>`)
$(`#desc`).html(`<%- s.categoryDescription %>`)
<% if(s.categoryImageURL) { %>
$("#img").attr("src", `<%- s.categoryImageURL %>`);
<% } %>
});
</script>
<div class="container-fluid settings mb-4" id="<%= s.categoryId %>div">
<% s.categoryOptionsList.forEach( option=> {
let Allowed = canUseList[s.categoryId][option.optionId];
%>
<% if (!option.themeOptions) option.themeOptions={}; let
themeOptions=option.themeOptions; %>
<% if (themeOptions?.startNewSection?.first || !themeOptions?.startNewSection) { %>
<div class="mt-4">
<div class="col-12 item starting">
<div class="card mb-4">
<div class="card-header pb-0">
<% if(option.optionType.type !=="collapsable" &&
option.optionType.type !=="modal" ) { if
(!option.themeOptions?.hideOptionName || !option.optionName)
{ %>
<% if (themeOptions?.startNewSection?.first &&
themeOptions?.startNewSection?.title ) { %>
<h4>
<%- themeOptions?.startNewSection?.title %>
</h4>
<% } else { %>
<h4>
<%- option.optionName %>
</h4>
<% } %>
<% } %>
<% if (!option.themeOptions?.hideOptionDesc
|| !option.optionDescription) { %>
<% if
(themeOptions?.startNewSection?.first
&&
themeOptions?.startNewSection?.description)
{ %>
<a>
<%- themeOptions?.startNewSection?.description
%>
</a>
<% } else { %>
<a>
<%- option.optionDescription
%>
</a>
<% } %>
<% } } %>
</div>
<% if(option.optionType.type !=="collapsable" &&
option.optionType.type !=="modal" ) { %>
<hr>
<% } %>
<div class="card-body px-0 pt-0 pb-2"
style="padding: 0 1.5rem 1.5rem !important;">
<% } %>
<div class="mt-3">
<%- include(`components/formTypes/${option.optionType.type}.ejs`,
{option, s, Allowed}); %>
</div>
<% if (!themeOptions?.startNewSection ||
themeOptions?.startNewSection &&
themeOptions?.startNewSection?.last &&
!themeOptions?.startNewSection?.first) { %>
</div>
</div>
</div>
</div>
<% } %>
<% }); %>
<% }); %>
</div>
<div id="saveChanges"
class="animated card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
<div class="row gx-4">
<div class="col-auto my-auto">
<div class="h-100">
<h5 class="mb-1">
Changes Detected!
</h5>
</div>
</div>
<div class="buttons col-lg-4">
<div class="nav-wrapper position-relative end-0" style="width: max-content;">
<ul class="nav nav-pills nav-fill p-1 bg-transparent" role="tablist">
<li class="nav-item" style="height: min-content;">
<a style="float: right; margin: 0;" class="btn" data-bs-toggle="tab"
onclick="discardChanges()" role="tab" aria-selected="false">
<span class="ms-1">Reset</span>
</a>
</li>
<li class="nav-item">
<a style="margin: 0 20px; float: right;" class="btn bg-gradient-primary"
data-bs-toggle="tab" onclick="saveChanges()" role="tab"
aria-selected="false">
<span class="ms-1">Save Changes</span>
</a>
</li>
</div>
</div>
</div>
</div>
</div>
<% if (!option.themeOptions) option.themeOptions={}; let
themeOptions=option.themeOptions; %>
<% if (themeOptions?.startNewSection?.first || !themeOptions?.startNewSection) { %>
<div class="mt-4">
<div class="col-12 item starting">
<div class="card mb-4">
<div class="card-header pb-0">
<% if(option.optionType.type !=="collapsable" &&
option.optionType.type !=="modal" ) { if
(!option.themeOptions?.hideOptionName || !option.optionName)
{ %>
<% if (themeOptions?.startNewSection?.first &&
themeOptions?.startNewSection?.title ) { %>
<h4>
<%- themeOptions?.startNewSection?.title %>
</h4>
<% } else { %>
<h4>
<%- option.optionName %>
</h4>
<% } %>
<% } %>
<% if (!option.themeOptions?.hideOptionDesc
|| !option.optionDescription) { %>
<% if
(themeOptions?.startNewSection?.first
&&
themeOptions?.startNewSection?.description)
{ %>
<a>
<%- themeOptions?.startNewSection?.description
%>
</a>
<% } else { %>
<a>
<%- option.optionDescription
%>
</a>
<% } %>
<% } } %>
</div>
<% if(option.optionType.type !=="collapsable" &&
option.optionType.type !=="modal" ) { %>
<hr>
<% } %>
<div class="card-body px-0 pt-0 pb-2"
style="padding: 0 1.5rem 1.5rem !important;">
<% } %>
<div class="mt-3">
<%- include(`components/formTypes/${option.optionType.type}.ejs`,
{option, s, Allowed}); %>
</div>
<% if (!themeOptions?.startNewSection ||
themeOptions?.startNewSection &&
themeOptions?.startNewSection?.last &&
!themeOptions?.startNewSection?.first) { %>
</div>
</div>
</div>
</div>
<% } %>
<% }); %>
<% }); %>
</div>
<div id="saveChanges"
class="animated card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
<div class="row gx-4">
<div class="col-auto my-auto">
<div class="h-100">
<h5 class="mb-1">
Changes Detected!
</h5>
</div>
</div>
<div class="buttons col-lg-4">
<div class="nav-wrapper position-relative end-0" style="width: max-content;">
<ul class="nav nav-pills nav-fill p-1 bg-transparent" role="tablist">
<li class="nav-item" style="height: min-content;">
<a style="float: right; margin: 0;" class="btn" data-bs-toggle="tab"
onclick="discardChanges()" role="tab" aria-selected="false">
<span class="ms-1">Reset</span>
</a>
</li>
<li class="nav-item">
<a style="margin: 0 20px; float: right;" class="btn bg-gradient-primary"
data-bs-toggle="tab" onclick="saveChanges()" role="tab"
aria-selected="false">
<span class="ms-1">Save Changes</span>
</a>
</li>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</main>
<!-- Core JS Files -->
<script id="helper" category="<%= req.params.category %>" gid="<%= req.params.id %>" refresh="<%= settings.find(s => s.categoryId === req.params?.category)?.refreshOnSave || false %>"
src="/js/dashboard/functions.js"></script>
src="/js/dashboard/functions.js"></script>
<script src="../assets/js/core/popper.min.js"></script>
<script src="../assets/js/core/bootstrap.min.js"></script>
<script src="../assets/js/plugins/perfect-scrollbar.min.js"></script>
@ -454,35 +439,35 @@
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/bootstrap.tagsinput/0.4.2/bootstrap-tagsinput.min.js"></script>
<script>
var win = navigator.platform.indexOf('Win') > -1;
if (win && document.querySelector('#sidenav-scrollbar')) {
var options = {
damping: '0.5'
}
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
}
var win = navigator.platform.indexOf("Win") > -1;
if (win && document.querySelector("#sidenav-scrollbar")) {
var options = {
damping: "0.5"
}
Scrollbar.init(document.querySelector("#sidenav-scrollbar"), options);
}
</script>
<script>
$(document).ready(function () {
<% if ( req.query.error === "premiumRequired" ) { %>
sweetalert("error", "<%= themeConfig?.sweetalert?.error?.requirePremium || 'Premium is required for this category' %>", 2000);
window.history.replaceState({}, title, window.location.href.split('?')[0]);
<% } %>
$('.multiSelect').select2({ closeOnSelect: true });
$(".tags").select2({ theme: "classic", tags: true })
$(".select2-selection").addClass("form-control")
$(".select2-search__field").attr('formType', 'tagInput');
});
$(document).ready(function () {
<% if ( req.query.error === "premiumRequired" ) { %>
sweetalert("error", "<%= themeConfig?.sweetalert?.error?.requirePremium || "Premium is required for this category" %>", 2000);
window.history.replaceState({}, title, window.location.href.split("?")[0]);
<% } %>
$(".multiSelect").select2({ closeOnSelect: true });
$(".tags").select2({ theme: "classic", tags: true })
$(".select2-selection").addClass("form-control")
$(".select2-search__field").attr("formType", "tagInput");
});
function updateSlider(slideAmount, id) {
var sliderDiv = document.getElementById(`value_${id}`);
sliderDiv.innerHTML = slideAmount;
}
</script>
<!-- Github buttons -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<!-- Control Center for Soft Dashboard: parallax effects, scripts for the example pages etc -->
<%- include('partials/scripts.ejs', {now: "settings" }) %>
function updateSlider(slideAmount, id) {
var sliderDiv = document.getElementById(`value_${id}`);
sliderDiv.innerHTML = slideAmount;
}
</script>
<!-- Github buttons -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<!-- Control Center for Soft Dashboard: parallax effects, scripts for the example pages etc -->
<%- include("partials/scripts.ejs", {now: "settings" }) %>
</body>
</html>

View file

@ -1,18 +1,3 @@
<!--
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://www.creative-tim.com/license)
* Coded by Creative Tim
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-->
<!DOCTYPE html>
<html lang="en">
<%- include('partials/preloader.ejs', {now:'index', req: req}) %>
@ -24,120 +9,120 @@ let gradone;
let gradtwo;
if (currentScheme == "blue") {
colone = "#21d4fd";
coltwo = "#2152ff";
gradone = "rgba(33,212,253,0.1)";
gradtwo = "rgba(33,82,255,0.1)";
colone = "#21d4fd";
coltwo = "#2152ff";
gradone = "rgba(33,212,253,0.1)";
gradtwo = "rgba(33,82,255,0.1)";
}
if (currentScheme == "pink") {
colone = "#FF0080";
coltwo = "#7928CA";
gradone = "rgba(255,0,128,0.1)";
gradtwo = "rgba(121,40,202,0.1)";
colone = "#FF0080";
coltwo = "#7928CA";
gradone = "rgba(255,0,128,0.1)";
gradtwo = "rgba(121,40,202,0.1)";
}
if (currentScheme == "red") {
colone = "#ea0606";
coltwo = "#ff667c";
gradone = "rgba(255,102,124,0.1)";
gradtwo = "rgba(234,6,6,0.1)";
colone = "#ea0606";
coltwo = "#ff667c";
gradone = "rgba(255,102,124,0.1)";
gradtwo = "rgba(234,6,6,0.1)";
}
if (currentScheme == "green") {
colone = "#17ad37";
coltwo = "#98ec2d";
gradone = "rgba(23,173,55,0.1)";
gradtwo = "rgba(152,236,45,0.1)";
colone = "#17ad37";
coltwo = "#98ec2d";
gradone = "rgba(23,173,55,0.1)";
gradtwo = "rgba(152,236,45,0.1)";
}
if (currentScheme == "yellow") {
colone = "#f53939";
coltwo = "#fbcf33";
gradone = "rgba(245,57,57,0.1)";
gradtwo = "rgba(251,207,51,0.1)";
colone = "#f53939";
coltwo = "#fbcf33";
gradone = "rgba(245,57,57,0.1)";
gradtwo = "rgba(251,207,51,0.1)";
}
if (currentScheme == "dark") {
colone = "#141727";
coltwo = "#3A416F";
gradone = "rgba(20,23,39,0.1)";
gradtwo = "rgba(58,65,111,0.1)";
colone = "#141727";
coltwo = "#3A416F";
gradone = "rgba(20,23,39,0.1)";
gradtwo = "rgba(58,65,111,0.1)";
}
if (currentScheme == "custom") {
colone = themeConfig.themeColors.primaryColor;
coltwo = themeConfig.themeColors.secondaryColor;
gradone = hexToRgbA(themeConfig.themeColors.primaryColor, 0.1);
gradtwo = hexToRgbA(themeConfig.themeColors.secondaryColor, 0.1);
colone = themeConfig.themeColors.primaryColor;
coltwo = themeConfig.themeColors.secondaryColor;
gradone = hexToRgbA(themeConfig.themeColors.primaryColor, 0.1);
gradtwo = hexToRgbA(themeConfig.themeColors.secondaryColor, 0.1);
}
function hexToRgbA(hex){
var c;
if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
c= hex.substring(1).split('');
if(c.length== 3){
c= [c[0], c[0], c[1], c[1], c[2], c[2]];
}
c= '0x'+c.join('');
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+',1)';
}
throw new Error('Bad Hex');
var c;
if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
c= hex.substring(1).split('');
if(c.length== 3){
c= [c[0], c[0], c[1], c[1], c[2], c[2]];
}
c= '0x'+c.join('');
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+',1)';
}
throw new Error('Bad Hex');
}
%>
<head>
<style>
.unselectable {
-webkit-user-select: none;
-webkit-touch-callout: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style>
<%- themeConfig?.customHtml %>
<style>
.unselectable {
-webkit-user-select: none;
-webkit-touch-callout: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style>
<%- themeConfig?.customHtml %>
</head>
<body class="g-sidenav-show bg-gray-100" id="scroll">
<%- include('partials/preload.ejs') %>
<%- include('partials/sidebar.ejs', {config: config, now:'shards'}) %>
<div class="main-content position-relative bg-gray-100 max-height-vh-100 h-100">
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'shards'}) %>
<!-- End Navbar -->
<% let image; if (themeConfig.shardspage.backgroundUrl) { image=themeConfig.shardspage.backgroundUrl } else { const images=["curved-1", "curved-2" , "curved-3" , "curved-4" , "curved-5" , "curved-6" , "curved-7"
, "curved-8" , "curved-9" , "curved-10" , "curved-11" , "curved-12" , "curved-13" , "curved-14"
, "curved-15" , "curved-16" , "curved-17" , "curved-18" ]; image="/img/curved-images/" + images[Math.floor(Math.random() *
images.length)]+ ".webp";} %>
<div class="container-fluid">
<div class="page-header min-height-300 border-radius-xl mt-4"
style="background-image: url('<%- image %>'); background-position-y: 50%;">
<span class="mask bg-gradient-primary opacity-6"></span>
</div>
<div class="card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
<div class="row gx-4">
<div class="col-auto">
<div class="avatar avatar-xl position-relative">
<img id="img" src="<%- themeConfig.icons.sidebar.darkUrl %>" alt="profile_image"
class="w-100 border-radius-lg shadow-sm">
</div>
</div>
<div class="col-auto my-auto">
<div class="h-100">
<h5 id="title" class="mb-1">
Bot Shards Status
</h5>
<p id="desc" class="mb-0 font-weight-bold text-sm">
<b>Total Shards: </b>
<span id="totalshards">Loading</span>
</p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="container">
<div class="row" style="row-gap: 1rem;" id="shardlist">
<span>
Loading...
</span>
</div>
</div>
</div>
<%- include('partials/footer.ejs') %>
<!-- Navbar -->
<%- include('partials/navbar.ejs', {now:'shards'}) %>
<!-- End Navbar -->
<% let image; if (themeConfig.shardspage.backgroundUrl) { image=themeConfig.shardspage.backgroundUrl } else { const images=["curved-1", "curved-2" , "curved-3" , "curved-4" , "curved-5" , "curved-6" , "curved-7"
, "curved-8" , "curved-9" , "curved-10" , "curved-11" , "curved-12" , "curved-13" , "curved-14"
, "curved-15" , "curved-16" , "curved-17" , "curved-18" ]; image="/img/curved-images/" + images[Math.floor(Math.random() *
images.length)]+ ".webp";} %>
<div class="container-fluid">
<div class="page-header min-height-300 border-radius-xl mt-4"
style="background-image: url('<%- image %>'); background-position-y: 50%;">
<span class="mask bg-gradient-primary opacity-6"></span>
</div>
<div class="card card-body blur shadow-blur mx-4 mt-n6 overflow-hidden">
<div class="row gx-4">
<div class="col-auto">
<div class="avatar avatar-xl position-relative">
<img id="img" src="<%- themeConfig.icons.sidebar.darkUrl %>" alt="profile_image"
class="w-100 border-radius-lg shadow-sm">
</div>
</div>
<div class="col-auto my-auto">
<div class="h-100">
<h5 id="title" class="mb-1">
Bot Shards Status
</h5>
<p id="desc" class="mb-0 font-weight-bold text-sm">
<b>Total Shards: </b>
<span id="totalshards">Loading</span>
</p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="container">
<div class="row" style="row-gap: 1rem;" id="shardlist">
<span>
Loading...
</span>
</div>
</div>
</div>
<%- include('partials/footer.ejs') %>
</div>
</main>
</div>
@ -145,169 +130,169 @@ function hexToRgbA(hex){
<%- include('partials/scripts.ejs', {now: "shards"}) %>
<script>
let graphs = {};
async function updateshards(first){
let timeout
await $.get("/shards/get", function(data, status){
if (first)
$('#shardlist').empty()
let graphs = {};
async function updateshards(first){
let timeout
await $.get("/shards/get", function(data, status){
if (first)
$('#shardlist').empty()
data = data.sort((a, b) => a.id - b.id);
data = data.sort((a, b) => a.id - b.id);
$('#totalshards').html(data.length)
$('#totalshards').html(data.length)
if (!first) {
for (const shard in data) {
const shardObj = data[shard];
$(`userCount-${shardObj.id}`).html(shardObj.users)
$(`serverCount-${shardObj.id}`).html(shardObj.servers)
$(`channelCount-${shardObj.id}`).html(shardObj.channels)
const graph = Chart.getChart(`chart-line-${shardObj.id}`)
graph.data.datasets[0].data = data[shard].ping;
graph.update();
}
}
if (!first) {
for (const shard in data) {
const shardObj = data[shard];
$(`userCount-${shardObj.id}`).html(shardObj.users)
$(`serverCount-${shardObj.id}`).html(shardObj.servers)
$(`channelCount-${shardObj.id}`).html(shardObj.channels)
const graph = Chart.getChart(`chart-line-${shardObj.id}`)
graph.data.datasets[0].data = data[shard].ping;
graph.update();
}
}
if (first)
for (const shard in data) {
let row = $(`
<div class="col-sm-12 col-md-6">
<div class="card">
<div class="card-body p-3">
<div class="d-flex flex-column h-100">
<p class="mb-1 pt-2 text-bold">Shard - ${data[shard].id}</p>
<div class="m-0 d-flex" style="gap: 5px;">
<i class="ni ni-circle-08 align-self-center"></i> Users: <span id="userCount-${data[shard].id}">${data[shard].users.toLocaleString()}</span><br>
</div>
<div class="m-0 d-flex" style="gap: 5px;">
<i class="ni ni-laptop align-self-center"></i> Servers: <span id="serverCount-${data[shard].id}">${data[shard].guilds.toLocaleString()}</span><br>
</div>
<div class="m-0 d-flex" style="gap: 5px;">
<i class="ni ni-collection align-self-center"></i> Channels: <span id="channelCount-${data[shard].id}">${data[shard].channels.toLocaleString()}</span><br>
</div>
<div class="chart-container">
<canvas id="chart-line-${data[shard].id}" class="chart-canvas"></canvas>
</div>
</div>
</div>
</div>
</div>
`)
$('#shardlist').append(row.clone(true))
}
if (first)
for (const shard in data) {
let row = $(`
<div class="col-sm-12 col-md-6">
<div class="card">
<div class="card-body p-3">
<div class="d-flex flex-column h-100">
<p class="mb-1 pt-2 text-bold">Shard - ${data[shard].id}</p>
<div class="m-0 d-flex" style="gap: 5px;">
<i class="ni ni-circle-08 align-self-center"></i> Users: <span id="userCount-${data[shard].id}">${data[shard].users.toLocaleString()}</span><br>
</div>
<div class="m-0 d-flex" style="gap: 5px;">
<i class="ni ni-laptop align-self-center"></i> Servers: <span id="serverCount-${data[shard].id}">${data[shard].guilds.toLocaleString()}</span><br>
</div>
<div class="m-0 d-flex" style="gap: 5px;">
<i class="ni ni-collection align-self-center"></i> Channels: <span id="channelCount-${data[shard].id}">${data[shard].channels.toLocaleString()}</span><br>
</div>
<div class="chart-container">
<canvas id="chart-line-${data[shard].id}" class="chart-canvas"></canvas>
</div>
</div>
</div>
</div>
</div>
`)
$('#shardlist').append(row.clone(true))
}
if (first) {
for (const shard in data) {
const graph = createGraph(data[shard]);
graphs[data[shard].id] = graph;
}
}
timeout = data[0].interval
});
return timeout
}
window.onload = async function() {
const interval = await updateshards(true)
setInterval(function(){
updateshards(false)
}, interval || 15000);
};
if (first) {
for (const shard in data) {
const graph = createGraph(data[shard]);
graphs[data[shard].id] = graph;
}
}
timeout = data[0].interval
});
return timeout
}
window.onload = async function() {
const interval = await updateshards(true)
setInterval(function(){
updateshards(false)
}, interval || 15000);
};
</script>
<script>
function createGraph(shard) {
const { id, ping, interval } = shard;
function createGraph(shard) {
const { id, ping, interval } = shard;
const seconds = interval / 1000;
const seconds = interval / 1000;
let labels = [];
for (let i = 0; i < 10; i++) {
labels.push(`${i * seconds}s`);
}
let labels = [];
for (let i = 0; i < 10; i++) {
labels.push(`${i * seconds}s`);
}
let ctx = document.getElementById(`chart-line-${id}`).getContext("2d");
var gradientStroke1 = ctx.createLinearGradient(0, 230, 0, 50);
gradientStroke1.addColorStop(1, '<%= colone %>');
gradientStroke1.addColorStop(0.1, '<%= gradone %>');
gradientStroke1.addColorStop(0, '<%= gradtwo %>'); //purple colors
const chart = new Chart(ctx, {
type: "line",
data: {
labels,
datasets: [{
label: "ping",
tension: 0.4,
borderWidth: 0,
pointRadius: 0,
borderColor: "<%- colone %>",
borderWidth: 3,
backgroundColor: gradientStroke1,
fill: true,
data: ping,
maxBarThickness: 6
let ctx = document.getElementById(`chart-line-${id}`).getContext("2d");
var gradientStroke1 = ctx.createLinearGradient(0, 230, 0, 50);
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
}
},
interaction: {
intersect: false,
mode: 'index',
},
scales: {
y: {
suggestedMin: 0,
grid: {
drawBorder: false,
display: true,
drawOnChartArea: true,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
padding: 10,
color: '#b2b9bf',
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
x: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
color: '#b2b9bf',
padding: 20,
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
},
},
});
return chart
}
gradientStroke1.addColorStop(1, '<%= colone %>');
gradientStroke1.addColorStop(0.1, '<%= gradone %>');
gradientStroke1.addColorStop(0, '<%= gradtwo %>'); //purple colors
const chart = new Chart(ctx, {
type: "line",
data: {
labels,
datasets: [{
label: "ping",
tension: 0.4,
borderWidth: 0,
pointRadius: 0,
borderColor: "<%- colone %>",
borderWidth: 3,
backgroundColor: gradientStroke1,
fill: true,
data: ping,
maxBarThickness: 6
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
}
},
interaction: {
intersect: false,
mode: 'index',
},
scales: {
y: {
suggestedMin: 0,
grid: {
drawBorder: false,
display: true,
drawOnChartArea: true,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
padding: 10,
color: '#b2b9bf',
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
x: {
grid: {
drawBorder: false,
display: false,
drawOnChartArea: false,
drawTicks: false,
borderDash: [5, 5]
},
ticks: {
display: true,
color: '#b2b9bf',
padding: 20,
font: {
size: 11,
family: "Open Sans",
style: 'normal',
lineHeight: 2
},
}
},
},
},
});
return chart
}
</script>
</body>

View file

@ -14741,23 +14741,8 @@ fieldset:disabled .btn {
.d-print-none {
display: none !important;
}
} /*!
}
=========================================================
* Soft UI Dashboard - v1.0.3
=========================================================
* Product Page: https://www.creative-tim.com/product/soft-ui-dashboard
* Copyright 2021 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (site.license)
* Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
.alert-primary {
background-image: linear-gradient(310deg, #7928ca 0, #d6006c 100%);
}

827
yarn.lock

File diff suppressed because it is too large Load diff