diff --git a/index.js b/index.js index 884ffb1..d02aa08 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ const EventEmitter = require('events'); const DBDEvents = new EventEmitter(); +const version = require("./package.json").version; const err = (text) => { return text + ` Do you need help? Join our Discord server: ${'https://discord.gg/CzfMGtrdaA'.blue}`; @@ -105,5 +106,6 @@ module.exports = { Dashboard, formTypes: require('./ModuleExportsFunctions/formTypes'), customPagesTypes: require('./ModuleExportsFunctions/customPagesTypes'), - DBDEvents + DBDEvents, + version } \ No newline at end of file diff --git a/theme/dbd-soft-ui/database.sqlite b/theme/dbd-soft-ui/database.sqlite new file mode 100644 index 0000000..5e28c39 Binary files /dev/null and b/theme/dbd-soft-ui/database.sqlite differ diff --git a/theme/dbd-soft-ui/dbd-soft-ui.d.ts b/theme/dbd-soft-ui/dbd-soft-ui.d.ts new file mode 100644 index 0000000..f3bb2f2 --- /dev/null +++ b/theme/dbd-soft-ui/dbd-soft-ui.d.ts @@ -0,0 +1,538 @@ +declare module "dbd-soft-ui" { + import { Express, Request, Response } from "express"; + + type themeConfig = { + customThemeOptions: { + index: ({ req, res, config }: { + req: Request, + res: Response, + config: any + }) => { + cards: { + title: string, + icon: string, + getValue: string, + progressBar: { + enabled: boolean, + getProgress: number + } + }[], + graph: { + values: number[], + labels: string[] + } + } + }, + addons: string[], + websiteName: string, + colorScheme: "dark" | "pink" | "blue" | "red" | "green" | "yellow" | "custom", + themeColors?: { + primaryColor: string, + secondaryColor: string + } + supporteMail: string, + locales: Record, + footer: { + replaceDefault: boolean, + text: string, + } + admin: { + pterodactyl: { + enabled: boolean, + apiKey: string, + panelLink: string, + serverUUIDs: string[] + }, + logs?: { + enabled?: boolean, + key?: string, + } + }, + icons: { + favicon: string, + noGuildIcon: string, + sidebar: { + darkUrl: string, + lightUrl: string, + hideName: boolean, + borderRadius: boolean, + alignCenter: boolean + } + }, + index: { + graph: { + enabled: boolean, + lineGraph: boolean, + tag: string, + max: number + } + }, + premium: { + enabled: boolean, + card: { + title: string, + description: string, + bgImage: string, + button: { + text: string, + url: string + } + } + }, + preloader: { + image: string, + spinner: boolean, + text: string + }, + sidebar?: { + gestures: { + disabled: boolean, + gestureTimer: number, + gestureSensitivity: number + } + }, + shardspage?: { + enabled: boolean, + key: string, + }, + meta: { + author: string, + owner: string, + description: string, + ogLocale: string, + ogTitle: string, + ogImage: string, + ogType: string, + ogUrl: string, + ogSiteName: string, + ogDescription: string, + twitterTitle: string, + twitterDescription: string, + twitterDomain: string, + twitterUrl: string, + twitterCard: string, + twitterSite: string, + twitterSiteId: string, + twitterCreator: string, + twitterCreatorId: string, + twitterImage: string + }, + error: { + error404: { + title: string, + subtitle: string, + description: string + }, + dbdError: { + disableSecretMenu: boolean, + secretMenuCombination: string[] + } + }, + sweetalert: { + errors: { + requirePremium: string + }, + success: { + login: string + } + }, + blacklisted: { + title: string, + subtitle: string, + description: string, + button: { + enabled: boolean, + text: string, + link: string + } + }, + commands?: [ + { + category: string, + subTitle: string, + categoryId: string, + image: string, + hideAlias: boolean, + hideDescription: boolean, + hideSidebarItem: boolean, + list: [ + { + commandName: string, + commandUsage: string, + commandDescription: string, + commandAlias: string + } + ] + } + ] + + } + + export default function (options: themeConfig): { + themeCodename: string, + viewsPath: string, + staticPath: string, + embedBuilderComponent: string, + themeConfig: themeConfig, + init: (app: Express, config: Record) => void; + }; + + export const partials: any; + export const formTypes: FormTypes; + export const cmdHandler: (commands: Record[], prefix: string) => Record[]; + + /** + * @see [utils/feedHandler](./utils/feedHandler.js). + */ + export class Feed { + color: FeedColor; + description: string; + icon: FeedIcon; + id: string | number; + + setColor: (color: FeedColor) => Feed; + setDescription: (description: string) => Feed; + setIcon: (icon: FeedIcon) => Feed; + getFeed: (id: string | number) => Feed; + delete: () => Feed; + send: () => Promise; + constructor(); + } + + /** + * All possible colors that can be used against the + * `Feed#setColor()` method. They can be accessed with + * dot notation, eg `FeedColor.Red`. + */ + export enum FeedColor { + Red = "red", + Orange = "orange", + Pink = "pink", + Gray = "gray", + Green = "green", + Blue = "blue", + Dark = "dark" + } + + /** + * All possible icons that can be used against the + * `Feed#setIcon()` method. They can be accessed with + * bracket notation, eg `FeedIcon["address-book"]`. + */ + export enum FeedIcon { + "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", + + "youtube", + "discord", + "node", + "apple", + "sellsy", + "app-store", + "cloudflare", + "dev", + "github-alt", + "gitlab", + "google", + "itunes-note", + "node-js", + "npm", + "spotify", + "usb", + "windows" + } + + /** + * @see [utils/formtypes](./utils/formtypes.js). + */ + export interface FormTypes { + spacer: (themeOptions: Record) => { + type: string, + themeOptions: Record + } + emojiPicker: (disabled: boolean, themeOptions: Record) => { + type: string, + disabled: boolean, + themeOptions: Record + } + slider: (min: number, max: number, step: number, disabled: boolean, themeOptions: Record) => { + type: string, + min: number, + max: number, + step: number, + disabled: boolean, + themeOptions: Record + }, + date: (disabled: boolean, themeOptions: Record) => { + type: string, + disabled: boolean, + themeOptions: Record + }, + numberPicker: (min: number, max: number, disabled: boolean, themeOptions: Record) => { + type: string, + disabled: boolean, + themeOptions: Record + }, + tagInput: (disabled: boolean, themeOptions: Record) => { + type: string, + disabled: boolean, + themeOptions: Record + } + } +} diff --git a/theme/dbd-soft-ui/embedBuilderComponent.txt b/theme/dbd-soft-ui/embedBuilderComponent.txt new file mode 100644 index 0000000..76c4e3b --- /dev/null +++ b/theme/dbd-soft-ui/embedBuilderComponent.txt @@ -0,0 +1,1082 @@ + + + + + + + + + + + + + + + Embed Builder + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

GUI

+
+
+

JSON

+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + # + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+

Embed {{Colour}}

+

Pick the embed {{colour}}

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  +

+ {{botusername}} + + + + + BOT + + +

+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + +
+
+
+ +
+ + + + + + +
+
+
+
+
+
+
Nothing here
+
+
+
There is an error
+
+
+
+ + diff --git a/theme/dbd-soft-ui/icons.js b/theme/dbd-soft-ui/icons.js new file mode 100644 index 0000000..9a94b29 --- /dev/null +++ b/theme/dbd-soft-ui/icons.js @@ -0,0 +1,288 @@ +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' +] +const otherIcons = [ + '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 + } +} + +module.exports = run() diff --git a/theme/dbd-soft-ui/index.js b/theme/dbd-soft-ui/index.js new file mode 100644 index 0000000..8cc7bea --- /dev/null +++ b/theme/dbd-soft-ui/index.js @@ -0,0 +1,69 @@ +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') + +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}`); + + 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') + ) + + db.on('error', (err) => { + console.log('Connection Error', err) + process.exit() + }) + + 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) + } + } +} + +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 diff --git a/theme/dbd-soft-ui/locales.js b/theme/dbd-soft-ui/locales.js new file mode 100644 index 0000000..5234e86 --- /dev/null +++ b/theme/dbd-soft-ui/locales.js @@ -0,0 +1,95 @@ +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.
That's an example text.

Feel free to use HTML", + 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!' + } + } + } + } +} diff --git a/theme/dbd-soft-ui/package.json b/theme/dbd-soft-ui/package.json new file mode 100644 index 0000000..2951963 --- /dev/null +++ b/theme/dbd-soft-ui/package.json @@ -0,0 +1,49 @@ +{ + "name": "dbd-soft-ui", + "version": "1.6.48-beta.1", + "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", + "keyv": "^4.5.0", + "node-fetch": "2.6.7", + "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", + "prettier": "2.7.1" + } +} diff --git a/theme/dbd-soft-ui/pages/admin/control.js b/theme/dbd-soft-ui/pages/admin/control.js new file mode 100644 index 0000000..2acdb17 --- /dev/null +++ b/theme/dbd-soft-ui/pages/admin/control.js @@ -0,0 +1,27 @@ +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) + + 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') + } +} diff --git a/theme/dbd-soft-ui/pages/admin/feed.js b/theme/dbd-soft-ui/pages/admin/feed.js new file mode 100644 index 0000000..fcea454 --- /dev/null +++ b/theme/dbd-soft-ui/pages/admin/feed.js @@ -0,0 +1,193 @@ +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') + } + } +} diff --git a/theme/dbd-soft-ui/pages/get/admin.js b/theme/dbd-soft-ui/pages/get/admin.js new file mode 100644 index 0000000..e2f27a3 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/admin.js @@ -0,0 +1,48 @@ +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?' + ) + + 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 + } + + 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 + }) + } +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/pages/get/blacklisted.js b/theme/dbd-soft-ui/pages/get/blacklisted.js new file mode 100644 index 0000000..ab67475 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/blacklisted.js @@ -0,0 +1,11 @@ +module.exports = { + page: '/blacklisted', + execute: async (req, res, app, config, themeConfig, info) => { + res.render('blacklisted', { + req, + config, + themeConfig, + info + }) + } +} diff --git a/theme/dbd-soft-ui/pages/get/commands.js b/theme/dbd-soft-ui/pages/get/commands.js new file mode 100644 index 0000000..4ab6636 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/commands.js @@ -0,0 +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 + }) + } +} diff --git a/theme/dbd-soft-ui/pages/get/credits.js b/theme/dbd-soft-ui/pages/get/credits.js new file mode 100644 index 0000000..0ff79ca --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/credits.js @@ -0,0 +1,11 @@ +module.exports = { + page: '/credits', + execute: async (req, res, app, config, themeConfig, info) => { + res.render('credits', { + req: req, + config, + themeConfig, + info + }) + } +} diff --git a/theme/dbd-soft-ui/pages/get/debug.js b/theme/dbd-soft-ui/pages/get/debug.js new file mode 100644 index 0000000..09c68f4 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/debug.js @@ -0,0 +1,70 @@ +const fetch = require('node-fetch') +const fs = require('fs') +let DBD = require('discord-dashboard') + +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('/') + + 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` + ) + } + + 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' + ) + } + + 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() + + 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 + }) + } +} diff --git a/theme/dbd-soft-ui/pages/get/getshards.js b/theme/dbd-soft-ui/pages/get/getshards.js new file mode 100644 index 0000000..6228903 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/getshards.js @@ -0,0 +1,8 @@ +module.exports = { + page: '/shards/get', + execute: async (req, res, app, config, themeConfig, info, db) => { + let returned = await db.get('stats') + + res.json(returned) + } +} diff --git a/theme/dbd-soft-ui/pages/get/privacyPolicy.js b/theme/dbd-soft-ui/pages/get/privacyPolicy.js new file mode 100644 index 0000000..c85a564 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/privacyPolicy.js @@ -0,0 +1,11 @@ +module.exports = { + page: '/privacy-policy', + execute: async (req, res, app, config, themeConfig, info) => { + res.render('pp', { + req, + config, + themeConfig, + info + }) + } +} diff --git a/theme/dbd-soft-ui/pages/get/settings.js b/theme/dbd-soft-ui/pages/get/settings.js new file mode 100644 index 0000000..373df8f --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/settings.js @@ -0,0 +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) + + await config.guildSettings(req, res, false, req.params.category) + } +} diff --git a/theme/dbd-soft-ui/pages/get/settingsHome.js b/theme/dbd-soft-ui/pages/get/settingsHome.js new file mode 100644 index 0000000..ef3c558 --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/settingsHome.js @@ -0,0 +1,6 @@ +module.exports = { + page: '/settings/:id/', + execute: async (req, res, app, config, themeConfig, info) => { + await config.guildSettings(req, res, true) + } +} diff --git a/theme/dbd-soft-ui/pages/get/shards.js b/theme/dbd-soft-ui/pages/get/shards.js new file mode 100644 index 0000000..0ed1b7a --- /dev/null +++ b/theme/dbd-soft-ui/pages/get/shards.js @@ -0,0 +1,11 @@ +module.exports = { + page: '/shards', + execute: async (req, res, app, config, themeConfig, info, db) => { + res.render('shards', { + req: req, + config, + themeConfig, + info + }) + } +} diff --git a/theme/dbd-soft-ui/pages/post/guildSettings.js b/theme/dbd-soft-ui/pages/post/guildSettings.js new file mode 100644 index 0000000..05f2005 --- /dev/null +++ b/theme/dbd-soft-ui/pages/post/guildSettings.js @@ -0,0 +1,476 @@ +module.exports = { + page: '/guild/update/:guildId/', + execute: async (req, res, app, config, themeConfig, info) => { + const data = req.body + + let setNewRes + let errors = [] + let successes = [] + + 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) + + let category = config.settings?.find((c) => c.categoryId == req.query.categoryId) + + let catO = []; + let catToggle = []; + + 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: [], + }) + } + } + + 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 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 (!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 (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 (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) { + let 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 + }) + } +} diff --git a/theme/dbd-soft-ui/pages/post/logs.js b/theme/dbd-soft-ui/pages/post/logs.js new file mode 100644 index 0000000..5e4543d --- /dev/null +++ b/theme/dbd-soft-ui/pages/post/logs.js @@ -0,0 +1,23 @@ +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' }) + + const logs = await db.get('logs') + + let newLogs = [] + + if (!logs || !logs.length || !logs[0]) + newLogs = [req.body] + else + newLogs = [req.body, ...logs] + + await db.set('logs', newLogs) + + res.json({ status: 'Completed' }) + } +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/pages/post/shards.js b/theme/dbd-soft-ui/pages/post/shards.js new file mode 100644 index 0000000..526ac69 --- /dev/null +++ b/theme/dbd-soft-ui/pages/post/shards.js @@ -0,0 +1,36 @@ +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' }) + + 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 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) + + return { + ...s, + ping: nextPing ? [...nextPing, s.ping] : [0, 0, 0, 0, 0, 0, 0, 0, 0, s.ping], + } + }) + + await db.set('stats', clean) + + res.json({ status: 'Completed' }) + } +} diff --git a/theme/dbd-soft-ui/utils/cmdHandler.js b/theme/dbd-soft-ui/utils/cmdHandler.js new file mode 100644 index 0000000..712987b --- /dev/null +++ b/theme/dbd-soft-ui/utils/cmdHandler.js @@ -0,0 +1,52 @@ +module.exports = (commands, prefix) => { + if (!commands) + throw new Error('No commands were provided to the Soft UI cmdHandler.') + if (!prefix) prefix = '!' + + let finalCategories = [] + let categories = [] + + 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 = [] + + 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) + }) + + + const categoryObj = { + categoryId: category, + category: `${capitalizeFirstLetter(category)}`, + subTitle: `${capitalizeFirstLetter(category)} commands`, + list: commandsArr + } + + finalCategories.push(categoryObj) + } + + function capitalizeFirstLetter(string) { + return string.charAt(0).toUpperCase() + string.slice(1) + } + + return finalCategories +} diff --git a/theme/dbd-soft-ui/utils/feedHandler.js b/theme/dbd-soft-ui/utils/feedHandler.js new file mode 100644 index 0000000..2607bb9 --- /dev/null +++ b/theme/dbd-soft-ui/utils/feedHandler.js @@ -0,0 +1,165 @@ +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}`); + } + + 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.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.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}`); + } + + 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.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 + }) + } + } + } + } +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/utils/formtypes.js b/theme/dbd-soft-ui/utils/formtypes.js new file mode 100644 index 0000000..b7fb6e9 --- /dev/null +++ b/theme/dbd-soft-ui/utils/formtypes.js @@ -0,0 +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."); + + const hasType = (object) => object.hasOwnProperty('optionType') && object.optionType?.hasOwnProperty('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."); + + 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 + } + } +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/utils/functions/errorHandler.js b/theme/dbd-soft-ui/utils/functions/errorHandler.js new file mode 100644 index 0000000..bf2377a --- /dev/null +++ b/theme/dbd-soft-ui/utils/functions/errorHandler.js @@ -0,0 +1,47 @@ +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.' + } + + 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 (error) { + console.error(error) + } + + 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 + }) + } +} diff --git a/theme/dbd-soft-ui/utils/functions/settingsPage.js b/theme/dbd-soft-ui/utils/functions/settingsPage.js new file mode 100644 index 0000000..ebcf7d9 --- /dev/null +++ b/theme/dbd-soft-ui/utils/functions/settingsPage.js @@ -0,0 +1,399 @@ +const Discord = 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) + + let bot = config.bot + if (!bot.guilds.cache.get(req.params.id)) { + try { + await bot.guilds.fetch(req.params.id) + } catch (err) { } + } + + 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) + .members.cache.get(req.session.user.id) + .permissions.has(converted) + ) { + return res.redirect('/manage?error=noPermsToManageGuild') + } + } + + 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).roles.cache.size < 2) { + try { + await bot.guilds.cache.get(req.params.id).roles.fetch() + } catch (err) { } + } + + let actual = {} + let toggle = {} + let premium = {} + + let canUseList = {} + + 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 (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.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 (category.premium && premium[category.categoryId] == false) return res.redirect( + `/settings/${req.params.id}?error=premiumRequired` + ) + + + 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, + }, + }) + + 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 (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.`) + + } + } 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 + } + }) + } + + if (category) { + if (s.premium && premium[category] == false) { + return res.redirect( + `/settings/${req.params.id}?error=premiumRequired` + ) + } + } + + 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 (!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 + // boo + 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 + }) + } +} + +async function convert14(perm) { + var final = '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 + } + + return final +} diff --git a/theme/dbd-soft-ui/utils/initPages.js b/theme/dbd-soft-ui/utils/initPages.js new file mode 100644 index 0000000..f4859fa --- /dev/null +++ b/theme/dbd-soft-ui/utils/initPages.js @@ -0,0 +1,89 @@ +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 + ) + + 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`) + + 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}`); + } + } + } + + app.use('*', async function (req, res) { + res.status(404) + config.errorPage(req, res, undefined, 404) + }) + + app.use((err, req, res, next) => { + res.status(500) + config.errorPage(req, res, err, 500) + }) + + console.log(`${consolePrefix}${'Initialised all pages!'.cyan}`); + } +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/utils/updater/files.js b/theme/dbd-soft-ui/utils/updater/files.js new file mode 100644 index 0000000..f8dc411 --- /dev/null +++ b/theme/dbd-soft-ui/utils/updater/files.js @@ -0,0 +1,80 @@ +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() +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/utils/updater/npm.js b/theme/dbd-soft-ui/utils/updater/npm.js new file mode 100644 index 0000000..b822782 --- /dev/null +++ b/theme/dbd-soft-ui/utils/updater/npm.js @@ -0,0 +1,21 @@ +const consolePrefix = `${'['.blue}${'dbd-soft-ui'.yellow}${']'.blue} ` + +async function npmDashCheck() { + await npmThemeCheck(); + + const latestVersion = checkArray['dist-tags'].latest + const currentVersion = require("../../../../index").version + if (currentVersion < latestVersion) console.log(`${consolePrefix}${'Your version of discord-dashboard is'.cyan} ${'outdated'.red}${'!'.cyan}`); + else console.log(`${consolePrefix}${'Your version of discord-dashboard is'.cyan} ${'up-to-date'.green}${'!'.cyan}`); +} + +async function npmThemeCheck() { + const latestVersion = checkArray['dist-tags'].latest + const currentVersion = require("../../package.json").version + if (currentVersion < latestVersion) console.log(`${consolePrefix}${'Your version of dbd-soft-ui is'.cyan} ${'outdated'.red}${'!'.cyan}`); + else console.log(`${consolePrefix}${'Your version of dbd-soft-ui is'.cyan} ${'up-to-date'.green}${'!'.cyan}`); +} + +exports.update = async () => { + await npmDashCheck() +} \ No newline at end of file diff --git a/theme/dbd-soft-ui/utils/updater/versions.json b/theme/dbd-soft-ui/utils/updater/versions.json new file mode 100644 index 0000000..091e443 --- /dev/null +++ b/theme/dbd-soft-ui/utils/updater/versions.json @@ -0,0 +1,17 @@ +{ + "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" +} diff --git a/theme/dbd-soft-ui/utils/updater/versionsOnline.json b/theme/dbd-soft-ui/utils/updater/versionsOnline.json new file mode 100644 index 0000000..b97ca09 --- /dev/null +++ b/theme/dbd-soft-ui/utils/updater/versionsOnline.json @@ -0,0 +1,57 @@ +[ + { + "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" + } +] diff --git a/theme/dbd-soft-ui/views/admin.ejs b/theme/dbd-soft-ui/views/admin.ejs new file mode 100644 index 0000000..5cac1ce --- /dev/null +++ b/theme/dbd-soft-ui/views/admin.ejs @@ -0,0 +1,687 @@ + + + + + + <%- include('partials/preloader.ejs', {now: 'admin'}) %> + + <% + 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" + ] + const otherIcons = [ + "youtube", + "discord", + "node", + "apple", + "sellsy", + "app-store", + "cloudflare", + "dev", + "github-alt", + "gitlab", + "google", + "itunes-note", + "node-js", + "npm", + "spotify", + "usb", + "windows" + ] + %> + + <%- themeConfig?.customHtml %> + + + +<%- include('partials/preload.ejs') %> + +<%- include('partials/sidebar.ejs', {config: config, now:'admin'}) %> +
+ + <%- include('partials/navbar.ejs', {now:'admin'}) %> + +
+ <% + if(themeConfig?.admin?.pterodactyl?.enabled) { %> +
+ +
+
+
+
Pterodactyl List
+
+
+
+ + + + + + + + + + + <% + sData.forEach(data => { + %> + + + + + + + <% + }); + %> + + +
+ Server + + Info + + Status + + Controls +
+
+
+ user1 +
+
+
<%- data.name %>
+

<%- data.uuid %>

+
+
+
+

<%- data.description %>

+

<%- data.node %>

+
+ <% + if(data.status === "running") { %> + Online + <% } else if(data.status === "starting") { %> + Starting + <% } else if(data.status === "stopping") { %> + Stopping + <% } else { %> + Offline + <% } %> + + + <% + if(data.status === "running" || data.status === "starting") { %> + Stop + Restart + Kill + <% } else if(data.status === "restarting") { %> + Stop + Kill + <% } else if(data.status === "stopping") { %> + Kill + <% } else { %> + Start + + <% } %> +
+
+
+
+
+
+
+ <% } %> + <% if (themeConfig.admin?.logs?.enabled) { %> +
+
+
Bot Logs
+
+
+
Current Logs
+
+
+ <% if (ldata !== undefined) { %> + + <% } else { %> + + <% } %> +
+
+
+
+
+ <% } %> +
+
+
+
+
Feed Builder
+
+
+
Feed Icon
+
    +
  • +
    +
    + + + + + +
    +
    +
  • +
+
Feed Description
+
    +
  • +
    +
    + + + + + +
    +
    +
  • +
+
Feed Colour
+
    +
  • +
    + +
    +
  • +
+
+ +
+
+
+
+
+
+
Feed Preview
+
+
+
+ +
+
+
+
+
+
Admin Controls
+ CHECK FOR UPDATES +
+
+
+ + +
+
+
+
+
+
+
+
+
Current Feeds
+ <%- include('partials/feeds.ejs', {require, admin:true}) %> +
+ + <% + icons.forEach(async(icon) => { %> + + + + <%- include('partials/iconsList.ejs', {icons,otherIcons}) %> + +
+
+
+
+
+ <%- include('partials/footer.ejs') %> +
+
+ +
+ + + +<%- include('partials/scripts.ejs', {now: "admin"}) %> + + + \ No newline at end of file diff --git a/theme/dbd-soft-ui/views/commands.ejs b/theme/dbd-soft-ui/views/commands.ejs new file mode 100644 index 0000000..1702edb --- /dev/null +++ b/theme/dbd-soft-ui/views/commands.ejs @@ -0,0 +1,167 @@ + + + + + + <%- include('partials/preloader.ejs', {now: 'commands'}) %> + + <%- themeConfig?.customHtml %> + + + +<%- include('partials/preload.ejs') %> +<%- include('partials/sidebar.ejs', {config: config, now:'commands'}) %> +
+ + <%- include('partials/navbar.ejs', {now:'commands'}) %> + +
+
+
+ <% themeConfig.commands?.forEach(category => { %> +
+
+
+
+

<%= category.category %>

+ <%= category.subTitle %> +
+
+
+ + + + + + <% if(!category.hideDescription) { %> + + <% } %> + <% if(!category.hideAlias) { %> + + <% } %> + + + + + <% category.list.forEach((item)=>{ %> + + + + <% if(!category.hideDescription) { %> + + <% } %> + <% if(!category.hideAlias) { %> + + <% } %> + + + <% }) %> + +
+ Name + + Command Usage + + Description + + Aliases +
+
+
+ <% if(category.image){ %> + <%- category.image %> + <% } %> +
+
+
<%= item.commandName %>
+
+
+
+

<%= item.commandUsage %>

+
+

<%= item.commandDescription %>

+
+ <%= item.commandAlias %> + + + + +
+
+
+
+
+
+ <% }) %> +
+
+ + <%- include('partials/footer.ejs') %> + + <%- include('partials/scripts.ejs', {now: "commands"}) %> + + + \ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/channelsMultiSelect.ejs b/theme/dbd-soft-ui/views/components/formTypes/channelsMultiSelect.ejs new file mode 100644 index 0000000..de089e5 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/channelsMultiSelect.ejs @@ -0,0 +1,32 @@ + + +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + +
\ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/channelsSelect.ejs b/theme/dbd-soft-ui/views/components/formTypes/channelsSelect.ejs new file mode 100644 index 0000000..4a84f35 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/channelsSelect.ejs @@ -0,0 +1,19 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + diff --git a/theme/dbd-soft-ui/views/components/formTypes/checkbox.ejs b/theme/dbd-soft-ui/views/components/formTypes/checkbox.ejs new file mode 100644 index 0000000..132f25b --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/checkbox.ejs @@ -0,0 +1,14 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + +
\ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/colorSelect.ejs b/theme/dbd-soft-ui/views/components/formTypes/colorSelect.ejs new file mode 100644 index 0000000..12e6e80 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/colorSelect.ejs @@ -0,0 +1,9 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> +" + <% if(option.optionType.disabled){ %>disabled<% } %> + <% if(!Allowed.allowed){ %>style="border-color: red;" disabled<% } %> +> diff --git a/theme/dbd-soft-ui/views/components/formTypes/date.ejs b/theme/dbd-soft-ui/views/components/formTypes/date.ejs new file mode 100644 index 0000000..72c5d69 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/date.ejs @@ -0,0 +1,26 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + + 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 + <% } %> +> diff --git a/theme/dbd-soft-ui/views/components/formTypes/embedBuilder.ejs b/theme/dbd-soft-ui/views/components/formTypes/embedBuilder.ejs new file mode 100644 index 0000000..a66c328 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/embedBuilder.ejs @@ -0,0 +1,106 @@ + + +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + +
+ <% + 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); + } + + %> + +
+ \ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/emojiPicker.ejs b/theme/dbd-soft-ui/views/components/formTypes/emojiPicker.ejs new file mode 100644 index 0000000..6c5c94e --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/emojiPicker.ejs @@ -0,0 +1,176 @@ + + + +<% if(!Allowed.allowed){ %> + + <%- Allowed.errorMessage %> + +
+<% } %> + +" class="d-none" type="text" id="<%= option.optionId %>" formType="emojiPicker" type="text" onchange="optionEdited(this)"> + + + + + +<% if(!option.optionType.disabled && Allowed.allowed){ %> + +<% } %> \ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/input.ejs b/theme/dbd-soft-ui/views/components/formTypes/input.ejs new file mode 100644 index 0000000..a81194f --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/input.ejs @@ -0,0 +1,33 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + +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 %>" + <% } %> +/> + +<% if (option?.themeOptions?.optionPlaceholder) { %> +
+ <% option?.themeOptions?.optionPlaceholder?.values.forEach(array => { %> + + onclick="$('#<%= option.optionId %>').val(this.innerHTML);" + <% } %> + ><%- array %> + <% }) %> +
+<% } %> diff --git a/theme/dbd-soft-ui/views/components/formTypes/multiRow.ejs b/theme/dbd-soft-ui/views/components/formTypes/multiRow.ejs new file mode 100644 index 0000000..9a8b7d6 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/multiRow.ejs @@ -0,0 +1,10 @@ + +
+ <% option.optionType.options.forEach(opt => { %> +
+

<%- opt?.optionName || ""%>

+

<%- opt?.optionDescription || ""%>

+ <%- include(`./${opt.optionType.type}.ejs`, {option: opt, s, Allowed}) %> +
+ <% }) %> +
\ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/multiSelect.ejs b/theme/dbd-soft-ui/views/components/formTypes/multiSelect.ejs new file mode 100644 index 0000000..425e9d2 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/multiSelect.ejs @@ -0,0 +1,29 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + diff --git a/theme/dbd-soft-ui/views/components/formTypes/numberPicker.ejs b/theme/dbd-soft-ui/views/components/formTypes/numberPicker.ejs new file mode 100644 index 0000000..d5e5d36 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/numberPicker.ejs @@ -0,0 +1,27 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + + 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 + <% } %> +> diff --git a/theme/dbd-soft-ui/views/components/formTypes/rolesMultiSelect.ejs b/theme/dbd-soft-ui/views/components/formTypes/rolesMultiSelect.ejs new file mode 100644 index 0000000..664822d --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/rolesMultiSelect.ejs @@ -0,0 +1,26 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + + +
\ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/rolesSelect.ejs b/theme/dbd-soft-ui/views/components/formTypes/rolesSelect.ejs new file mode 100644 index 0000000..6bcd66a --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/rolesSelect.ejs @@ -0,0 +1,21 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + diff --git a/theme/dbd-soft-ui/views/components/formTypes/select.ejs b/theme/dbd-soft-ui/views/components/formTypes/select.ejs new file mode 100644 index 0000000..b2c110b --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/select.ejs @@ -0,0 +1,22 @@ +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> + diff --git a/theme/dbd-soft-ui/views/components/formTypes/slider.ejs b/theme/dbd-soft-ui/views/components/formTypes/slider.ejs new file mode 100644 index 0000000..dbfc5dc --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/slider.ejs @@ -0,0 +1,99 @@ + + +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> +<% if(option?.themeOptions?.dataList) { %> + + <% option.themeOptions.dataList.forEach(data => { %> + + <% }) %> + +<% } %> + + 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 %>" +<% if (option.themeOptions?.showValue) { %> + 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 +<% } %> +> +<% if (option.themeOptions?.showValue) { %> +

Slider is set to <% if(actual[s.categoryId][option.optionId]){ %><%= actual[s.categoryId][option.optionId] %><% } %>

+<% } %> diff --git a/theme/dbd-soft-ui/views/components/formTypes/spacer.ejs b/theme/dbd-soft-ui/views/components/formTypes/spacer.ejs new file mode 100644 index 0000000..ffd0883 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/spacer.ejs @@ -0,0 +1,3 @@ +

<%- option.title %>

+<%- option.description %> +
\ No newline at end of file diff --git a/theme/dbd-soft-ui/views/components/formTypes/switch.ejs b/theme/dbd-soft-ui/views/components/formTypes/switch.ejs new file mode 100644 index 0000000..0e85817 --- /dev/null +++ b/theme/dbd-soft-ui/views/components/formTypes/switch.ejs @@ -0,0 +1,78 @@ +<% let val = ""; +if (actual[s.categoryId][option.optionId]) val = "checked"; +%> + + + +<% if(!Allowed.allowed){ %><%- Allowed.errorMessage %>
<% } %> +