├── .gitignore ├── .gitattributes ├── static ├── images │ ├── discord.png │ ├── download.png │ └── indexpagae.gif └── stylesheet.css ├── config.json.example ├── router.js ├── routes ├── index.js ├── guildroutes.js └── discord.js ├── app.js ├── views ├── partials │ └── navbar.ejs ├── serverpage.ejs ├── index.ejs └── serverinfo.ejs ├── package.json ├── LICENSE ├── README.md ├── CONTRIBUTING.md └── bot └── webapi_handler.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | config.json -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /static/images/discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charfweh/discord-bot-dashboard/HEAD/static/images/discord.png -------------------------------------------------------------------------------- /static/images/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charfweh/discord-bot-dashboard/HEAD/static/images/download.png -------------------------------------------------------------------------------- /static/images/indexpagae.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charfweh/discord-bot-dashboard/HEAD/static/images/indexpagae.gif -------------------------------------------------------------------------------- /config.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "port": 3000, 3 | 4 | "clientId": "", 5 | "clientSecret": "", 6 | "scopes": ["identify", "guilds"], 7 | "redirectUri": "", 8 | "token":"", 9 | "inviteurl":"" 10 | } 11 | -------------------------------------------------------------------------------- /router.js: -------------------------------------------------------------------------------- 1 | module.exports = (app) => { 2 | // '/' 3 | app.use('/', require('./routes/index')); 4 | // '/authorize' 5 | app.use('/authorize', require('./routes/discord')); 6 | app.use('/manage',require('./routes/guildroutes')) 7 | } 8 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | const router = require('express').Router(); 2 | 3 | router.get('/', (req, res) => { 4 | res.render('index', { pageTitle: 'Dashboard', user: req.session.user || null}); 5 | 6 | }); 7 | // router.get('/servers',(req,res) =>{ 8 | // console.log(req.session.guilds) 9 | // res.render('serverpage',{pageTitle:'Server',guild : req.session.guilds || null }); 10 | // }) 11 | module.exports = router; 12 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | 4 | let port = require('./config.json').port || 3000; 5 | app.set('port', port); 6 | 7 | const session = require('express-session'); 8 | app.use(express.json()) // for parsing application/json 9 | app.use(express.urlencoded({ extended: true })) 10 | app.set('view engine', 'ejs'); 11 | app.use(express.static('static')); 12 | app.use(session({ 13 | secret: '48738924783748273742398747238', 14 | resave: false, 15 | saveUninitialized: false, 16 | expires: 300000, 17 | })); 18 | require('./router')(app); 19 | 20 | app.listen(port, () => console.info(`Listening on port ${port}`)); 21 | -------------------------------------------------------------------------------- /views/partials/navbar.ejs: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord.js-dashboard", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node app.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/charfweh/discord-bot-dashboard.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/charfweh/discord-bot-dashboard.git" 19 | }, 20 | "homepage": "https://github.com/charfweh/discord-bot-dashboard.git#readme", 21 | "dependencies": { 22 | "body-parser": "^1.19.0", 23 | "ejs": "^2.6.1", 24 | "express": "^4.16.3", 25 | "express-session": "^1.17.1", 26 | "form-data": "^2.3.2", 27 | "node-fetch": "^3.1.1", 28 | "uid-safe": "^2.1.5" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 caelinj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /views/serverpage.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%- pageTitle %> 9 | 10 | 11 | 12 | 13 | <%- include('partials/navbar.ejs') %> 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <%- pageTitle %> 11 | 12 | 13 | 14 | <%- include('partials/navbar.ejs') %> 15 | 16 |
17 |

Guild Bot

18 | <% if (user) { %> 19 |
20 | 21 |
22 | <% } %> 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Discord Bot Dashboard 2 | 3 | Web dashboard for [SFSA](https://github.com/charfweh/superfastserverassistant) 4 | ### About 5 | Control your server with the Bot Dashboard, make em multiple roles, channels, voice channels, categories and you tell me. Made for Server admins and owner! 6 | #### Note: 7 | **You can use this Project to make your own dashboard, I'd love to see what you can make out of it** 8 | 9 | This project serves as a starter pack for **Bot+Dashboard**, It'll not be continued for further production, use it for your own project and make something! you'll learn a lot, I'm sure about that. 10 | 11 | I made it for the beginners who got no idea how to start and wondering how in the good world does it work and my answer to that is just get started you'll get there slowly but surely, have fun coding~ 12 | 13 | Please refer to SFSA [Readme](https://github.com/charfweh/superfastserverassistant#readme) for more info. 14 | ### Setup 15 | - Fork em clone em copy em just do it 16 | - Install the dependencies 17 | - Make an application on [Discord Developer](https://discord.com/developers/) and configure ``oauth2`` callback URL/s 18 | - Fuel up the Bot as well under the same application 19 | - Make a new file ``config.json`` and configure the file in accordance to ``config.json.example`` 20 | - Thats pretty much it 21 | - Run it ``nodemon app.js`` 22 | - Aye hit that http://localhost:3000 beautifully and have fun 23 | ### Credits 24 | The project is a cloned and modified version started from [caelinj repository](https://github.com/caelinj/discord.js-dashboard) 25 | -------------------------------------------------------------------------------- /views/serverinfo.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <%- pageTitle %> 10 | 11 | 12 | 13 | 14 | 15 | <%- include('partials/navbar.ejs') %> 16 |
17 | <% for ( g of mutualguilds) {%> 18 |

<%= g.name %> 19 |

21 | <% } %> 22 | <% for ( g of inviteguilds) {%> 23 |

<%= g.name %> 24 | 28 |

29 | 30 | <% } %> 31 | 32 | 33 | -------------------------------------------------------------------------------- /routes/guildroutes.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | // post params 3 | const router = require('express').Router(); 4 | const { clientId, clientSecret, scopes, redirectUri } = require('../config.json'); 5 | const fetch = require('node-fetch'); 6 | const FormData = require('form-data'); 7 | const {userhit,manageguild,checkguild,modifyguild} = require("../bot/webapi_handler.js"); 8 | let id,guildobj,mutualguilds,webuser; 9 | // define the home page route 10 | // middleware that is specific to this router 11 | router.get('/', function (req, res) { 12 | if (!req.session.user) return res.redirect("/authorize") 13 | res_user = req.session.user 14 | res_guild = req.session.guilds 15 | returnobj = checkguild(res_user.id,res_guild) 16 | mutualguilds = returnobj.bot_guilds 17 | inviteguilds = returnobj.invitebot_guilds 18 | res.render("serverinfo",{pageTitle:"Manage Guilds",mutualguilds:mutualguilds,inviteguilds:inviteguilds,user:req.session.user}); 19 | }) 20 | // define the guild id route 21 | 22 | router.get('/:id',(req,res)=>{ 23 | if (!req.session.user) return res.redirect("/authorize") 24 | id = req.params["id"] 25 | guildobj = manageguild(id) 26 | res.render("serverpage",{user:req.session.user,count:guildobj.memberCount, pageTitle:"Edit Guild" , name:guildobj.guildname , iconurl:guildobj.iconurl , owner:guildobj.owner, guildid:guildobj.id}) 27 | }) 28 | 29 | router.post('/:id',(req,res)=>{ 30 | console.log(req.body.channels) 31 | let channels = req.body.channels 32 | let regex = /^[a-zA-Z0-9\-\,]+/gm 33 | let result = channels.match(regex) 34 | webuser = req.session.user 35 | if(result == null) return res.send("malformed argument") 36 | let res_status = modifyguild(result,guildobj.id,webuser) 37 | if(res_status == 'Error') return res.send("Error") 38 | res.send("Success!") 39 | }) 40 | 41 | 42 | 43 | module.exports = router 44 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Transcriptase 2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 3 | 4 | - Reporting a bug 5 | - Discussing the current state of the code 6 | - Submitting a fix 7 | - Proposing new features 8 | - Becoming a maintainer 9 | 10 | ## We Develop with Github 11 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 12 | 13 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 14 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 15 | 16 | 1. Fork the repo and create your branch from `master`. 17 | 2. If you've added code that should be tested, add tests. 18 | 3. If you've changed APIs, update the documentation. 19 | 4. Ensure the test suite passes. 20 | 5. Make sure your code lints. 21 | 6. Issue that pull request! 22 | 23 | ## Any contributions you make will be under the MIT Software License 24 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. 25 | 26 | ## Report bugs using Github's [issues](https://github.com/briandk/transcriptase-atom/issues) 27 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy! 28 | 29 | ## Write bug reports with detail, background, and sample code 30 | 31 | **Great Bug Reports** tend to have: 32 | 33 | - A quick summary and/or background 34 | - Steps to reproduce 35 | - Be specific! 36 | - Give sample code if you can. 37 | - What you expected would happen 38 | - What actually happens 39 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 40 | 41 | People *love* thorough bug reports. I'm not even kidding. 42 | 43 | ## Use a Consistent Coding Style 44 | I'm borrowing these from [Facebook's Guidelines](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 45 | 46 | * 2 spaces for indentation rather than tabs 47 | * You can try running `npm run lint` for style unification 48 | 49 | ## License 50 | By contributing, you agree that your contributions will be licensed under its MIT License. 51 | 52 | ## References 53 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 54 | 55 | This was forked from [this](https://gist.github.com/briandk/3d2e8b3ec8daf5a27a62) 56 | -------------------------------------------------------------------------------- /routes/discord.js: -------------------------------------------------------------------------------- 1 | const router = require('express').Router(); 2 | const { clientId, clientSecret, scopes, redirectUri } = require('../config.json'); 3 | const fetch = require('node-fetch'); 4 | const FormData = require('form-data'); 5 | const {userhit} = require("../bot/webapi_handler.js"); 6 | const forceAuth = (req, res, next) => { 7 | if (!req.session.user) return res.redirect('/authorize') 8 | else return next(); 9 | } 10 | //bot 11 | router.get('/', (req, res) => { 12 | if (req.session.user) return res.redirect('/'); 13 | 14 | const authorizeUrl = `https://discord.com/api/oauth2/authorize?client_id=${clientId}&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauthorize%2Fcallback&response_type=code&scope=identify%20guilds`; 15 | res.redirect(authorizeUrl); 16 | }); 17 | 18 | router.get('/callback', (req, res) => { 19 | if (req.session.user) return res.redirect('/'); 20 | 21 | const accessCode = req.query.code; 22 | if (!accessCode) throw new Error('No access code returned from Discord'); 23 | 24 | const data = new FormData(); 25 | data.append('client_id', clientId); 26 | data.append('client_secret', clientSecret); 27 | data.append('grant_type', 'authorization_code'); 28 | data.append('redirect_uri', redirectUri); 29 | data.append('scope', scopes.join(' ')); 30 | data.append('code', accessCode); 31 | fetch('https://discordapp.com/api/oauth2/token', { 32 | method: 'POST', 33 | body: data 34 | }) 35 | .then(res => res.json()) 36 | .then(response => { 37 | fetch('https://discordapp.com/api/users/@me', { 38 | method: 'GET', 39 | headers: { 40 | authorization: `${response.token_type} ${response.access_token}` 41 | }, 42 | }) 43 | .then(res2 =>res2.json()) 44 | .then(userResponse => { 45 | userResponse.tag = `${userResponse.username}#${userResponse.discriminator}`; 46 | userResponse.avatarURL = userResponse.avatar ? `https://cdn.discordapp.com/avatars/${userResponse.id}/${userResponse.avatar}.png?` : null; 47 | userhit(userResponse) 48 | req.session.user = userResponse; 49 | 50 | }); 51 | fetch('https://discordapp.com/api/users/@me/guilds', { 52 | method: 'GET', 53 | headers: { 54 | authorization: `${response.token_type} ${response.access_token}` 55 | }, 56 | }) 57 | .then(res2 => res2.json()) 58 | .then(gResponse => { 59 | req.session.guilds = gResponse; 60 | res.redirect('/'); 61 | }); 62 | }); 63 | }); 64 | router.get('/logout', forceAuth, (req, res) => { 65 | req.session.destroy((err)=>{ 66 | if(err) console.log("session not destroyed") 67 | console.log("session destroyed") 68 | 69 | }); 70 | res.redirect('/') 71 | }); 72 | module.exports = router; 73 | -------------------------------------------------------------------------------- /bot/webapi_handler.js: -------------------------------------------------------------------------------- 1 | const discord = require("discord.js") 2 | const bot = new discord.Client() 3 | const {token, bot_prefix} = require("../config.json") 4 | bot.on("ready",()=>{ 5 | console.log("im ready") 6 | }) 7 | function userhit(userResponse){ 8 | //this channel id is of the server im in, please replace with channel id of your server 9 | bot.channels.cache.get('730731531428954172').send(`User authorize with ${userResponse.username}#${userResponse.discriminator}`) 10 | } 11 | function checkguild(member_id,guilds){ 12 | owner_guilds = [] 13 | bot_guilds = [] 14 | invitebot_guilds = [] 15 | guilds.forEach((item, i) => { 16 | if(item.owner == true){ 17 | owner_guilds.push({"name":item.name,"id":item.id}) 18 | if(bot.guilds.cache.get(item.id)){ 19 | bot_guilds.push({"name":item.name,"id":item.id}) 20 | } 21 | if(!bot.guilds.cache.get(item.id)){ 22 | invitebot_guilds.push({"name":item.name,"id":item.id}) 23 | } 24 | } 25 | }); 26 | return {bot_guilds,invitebot_guilds} 27 | } 28 | 29 | function manageguild(g_id){ 30 | let guild = bot.guilds.cache.get(g_id) 31 | if(guild){ 32 | let memberCount = guild.memberCount 33 | let guildname = guild.name 34 | let iconurl = guild.iconURL() 35 | let owner = guild.owner.displayName 36 | let id = guild.id 37 | return {memberCount,guildname,iconurl,owner,id} 38 | } 39 | return "You dont share mutual guild with the bot" 40 | } 41 | 42 | //parse the channels from POST request 43 | async function modifyguild(channels, g_id, webuser){ 44 | let c = channels[0].split(',') 45 | editguild = bot.guilds.cache.get(g_id) 46 | if(!editguild.channels.cache.find(c=>c.name == 'dashboard-logs')) return "Error" 47 | else{ 48 | let logs = await editguild.channels.cache.find(c => c.name == 'dashboard-logs') 49 | logs.send(`User initiated edit guild ${webuser.tag}`) 50 | c.forEach((item, i) => { 51 | editguild.channels.create(item,"text").then(()=>{ 52 | console.log("Channel created",item) 53 | }).catch((e)=>{ 54 | editguild.channels.cache.find(c => c.name == 'dashboard-logs').send(`[-] Error: ${e}`) 55 | }) 56 | }); 57 | } 58 | return "OK" 59 | } 60 | 61 | 62 | //setup function for dashboard logging 63 | bot.on("message",async message=>{ 64 | if(message.author == message.author.bot) return; 65 | if(message.content.startsWith(bot_prefix+"setup")){ 66 | await message.channel.send("[OK] starting the setup") 67 | if(message.member.hasPermission('ADMINISTRATOR')){ 68 | await message.guild.channels.create("dashboard-logs","text").then(()=>{ 69 | message.channel.send("[+] Channel created!") 70 | }).catch((e)=>{ 71 | message.channel.send(`[-] Error: ${e}`) 72 | }) 73 | }else return message.channel.send("[-] You do not have correct permission to run this command") 74 | } 75 | }) 76 | 77 | bot.on("guildCreate",async()=>{ 78 | await message.systemChannel.send('Thanks for inviting me in here\n Use ``g!setup`` to start the setup!') 79 | }) 80 | 81 | bot.login(token) 82 | module.exports = {userhit,manageguild,checkguild,modifyguild}; 83 | -------------------------------------------------------------------------------- /static/stylesheet.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,500'); 2 | 3 | body { 4 | background-color: #353536; 5 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2000 1500'%3E%3Cdefs%3E%3CradialGradient id='a' gradientUnits='objectBoundingBox'%3E%3Cstop offset='0' stop-color='%23ffffff'/%3E%3Cstop offset='1' stop-color='%23353536'/%3E%3C/radialGradient%3E%3ClinearGradient id='b' gradientUnits='userSpaceOnUse' x1='0' y1='750' x2='1550' y2='750'%3E%3Cstop offset='0' stop-color='%239a9a9b'/%3E%3Cstop offset='1' stop-color='%23353536'/%3E%3C/linearGradient%3E%3Cpath id='s' fill='url(%23b)' d='M1549.2 51.6c-5.4 99.1-20.2 197.6-44.2 293.6c-24.1 96-57.4 189.4-99.3 278.6c-41.9 89.2-92.4 174.1-150.3 253.3c-58 79.2-123.4 152.6-195.1 219c-71.7 66.4-149.6 125.8-232.2 177.2c-82.7 51.4-170.1 94.7-260.7 129.1c-90.6 34.4-184.4 60-279.5 76.3C192.6 1495 96.1 1502 0 1500c96.1-2.1 191.8-13.3 285.4-33.6c93.6-20.2 185-49.5 272.5-87.2c87.6-37.7 171.3-83.8 249.6-137.3c78.4-53.5 151.5-114.5 217.9-181.7c66.5-67.2 126.4-140.7 178.6-218.9c52.3-78.3 96.9-161.4 133-247.9c36.1-86.5 63.8-176.2 82.6-267.6c18.8-91.4 28.6-184.4 29.6-277.4c0.3-27.6 23.2-48.7 50.8-48.4s49.5 21.8 49.2 49.5c0 0.7 0 1.3-0.1 2L1549.2 51.6z'/%3E%3Cg id='g'%3E%3Cuse href='%23s' transform='scale(0.12) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.2) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.25) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(0.3) rotate(-20)'/%3E%3Cuse href='%23s' transform='scale(0.4) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(0.5) rotate(20)'/%3E%3Cuse href='%23s' transform='scale(0.6) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.7) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.835) rotate(-40)'/%3E%3Cuse href='%23s' transform='scale(0.9) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(1.05) rotate(25)'/%3E%3Cuse href='%23s' transform='scale(1.2) rotate(8)'/%3E%3Cuse href='%23s' transform='scale(1.333) rotate(-60)'/%3E%3Cuse href='%23s' transform='scale(1.45) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(1.6) rotate(10)'/%3E%3C/g%3E%3C/defs%3E%3Cg transform='rotate(0 0 0)'%3E%3Cg transform='rotate(0 0 0)'%3E%3Ccircle fill='url(%23a)' r='3000'/%3E%3Cg opacity='0.5'%3E%3Ccircle fill='url(%23a)' r='2000'/%3E%3Ccircle fill='url(%23a)' r='1800'/%3E%3Ccircle fill='url(%23a)' r='1700'/%3E%3Ccircle fill='url(%23a)' r='1651'/%3E%3Ccircle fill='url(%23a)' r='1450'/%3E%3Ccircle fill='url(%23a)' r='1250'/%3E%3Ccircle fill='url(%23a)' r='1175'/%3E%3Ccircle fill='url(%23a)' r='900'/%3E%3Ccircle fill='url(%23a)' r='750'/%3E%3Ccircle fill='url(%23a)' r='500'/%3E%3Ccircle fill='url(%23a)' r='380'/%3E%3Ccircle fill='url(%23a)' r='250'/%3E%3C/g%3E%3Cg transform='rotate(0 0 0)'%3E%3Cuse href='%23g' transform='rotate(10)'/%3E%3Cuse href='%23g' transform='rotate(120)'/%3E%3Cuse href='%23g' transform='rotate(240)'/%3E%3C/g%3E%3Ccircle fill-opacity='0.1' fill='url(%23a)' r='3000'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); 6 | background-attachment: fixed; 7 | background-size: cover; 8 | } 9 | 10 | .page-content { 11 | padding: 4px 42px; 12 | } 13 | 14 | .page-content h1 { margin-bottom: -10px; } 15 | 16 | h1, h2, h3, h4, h5, h6 { 17 | font-family: 'Roboto', sans-serif; 18 | font-weight: 500; 19 | color: #000000; 20 | } 21 | 22 | p, a { 23 | font-family: 'Roboto', sans-serif; 24 | font-weight: 300; 25 | color: #000000; 26 | text-decoration: none; 27 | } 28 | a:hover{ 29 | color:#000000 ; 30 | text-decoration: none; 31 | } 32 | .navbar { 33 | background: #23272A; 34 | padding: 21px 42px; 35 | } 36 | 37 | .navbar a { 38 | transition: .25s ease; 39 | color: #ffffff; 40 | text-decoration: none; 41 | } 42 | 43 | .navbar a:hover { 44 | color: #7792f3; 45 | } 46 | 47 | .navbar a:not(:last-child) { 48 | margin-right: 12px; 49 | } 50 | 51 | .navbar .right { 52 | float: right; 53 | } 54 | .header1{ 55 | align-content: center; 56 | text-align: center; 57 | color: #ffffff; 58 | font-size: 5rem; 59 | padding-top: 3rem; 60 | font-weight: bold; 61 | letter-spacing: 2px; 62 | } 63 | .mainbody{ 64 | align-content: center; 65 | text-align: center; 66 | padding-top: 3rem; 67 | letter-spacing: 2px; 68 | } 69 | .avatar{ 70 | border-radius: 50%; 71 | height: 30px; 72 | width: 30px; 73 | } 74 | 75 | @import url("https://fonts.googleapis.com/css?family=Fjalla+One&display=swap"); 76 | * { 77 | margin: 0; 78 | padding: 0; 79 | } 80 | .header{ 81 | color:#000000; 82 | font-size: 1.5rem; 83 | padding:1rem; 84 | } 85 | .hreflinks{ 86 | color:"black"; 87 | } 88 | .editguild { 89 | background: #676767; 90 | padding: 3rem 100px; 91 | border: 2px solid black; 92 | box-shadow: 15px 15px 1px #778484, 15px 15px 1px 2px black; 93 | width: 50%; 94 | align-self: center; 95 | margin-left: auto; 96 | margin-right: auto; 97 | } 98 | .l1{ 99 | display: block; 100 | width: 100%; 101 | font-size: 30pt; 102 | font-family: "Fjalla One"; 103 | min-width: 250px; 104 | padding-left: 5px; 105 | outline: none; 106 | color: black; 107 | text-align: center; 108 | } 109 | .l2{ 110 | display: block; 111 | width: 100%; 112 | font-size: 18pt; 113 | font-family: "Fjalla One"; 114 | min-width: 250px; 115 | padding-left: 5px; 116 | outline: none; 117 | color: black; 118 | padding: 1rem; 119 | } 120 | input { 121 | display: block; 122 | width: 100%; 123 | font-size: 14pt; 124 | line-height: 28pt; 125 | font-family: "Fjalla One"; 126 | margin-bottom: 28pt; 127 | border: none; 128 | border-bottom: 5px solid black; 129 | background: #ffffff; 130 | min-width: 250px; 131 | padding-left: 5px; 132 | outline: none; 133 | color: black; 134 | } 135 | 136 | input:focus { 137 | border-bottom: 5px solid #95a4ff; 138 | } 139 | 140 | button { 141 | display: block; 142 | margin: 0 auto; 143 | line-height: 28pt; 144 | padding: 0 20px; 145 | background: #ffffff; 146 | letter-spacing: 2px; 147 | transition: 0.2s all ease-in-out; 148 | outline: none; 149 | border: 1px solid black; 150 | box-shadow: 3px 3px 1px #95a4ff, 3px 3px 1px 1px black; 151 | } 152 | button:hover { 153 | background: black; 154 | color: white; 155 | border: 1px solid black; 156 | } 157 | 158 | ::selection { 159 | background: #ffc8ff; 160 | } 161 | 162 | input:-webkit-autofill, 163 | input:-webkit-autofill:hover, 164 | input:-webkit-autofill:focus { 165 | border-bottom: 5px solid #95a4ff; 166 | -webkit-text-fill-color: #2A293E; 167 | -webkit-box-shadow: 0 0 0px 1000px #f8f4e5 inset; 168 | transition: background-color 5000s ease-in-out 0s; 169 | } 170 | 171 | .manage{ 172 | padding: 0.8rem; 173 | align-items: center; 174 | text-align: center; 175 | } 176 | --------------------------------------------------------------------------------