Commit 6ad46e77 authored by Stephen's avatar Stephen 💯
Browse files

Add all of HTML to the admin panel

parent f61a131c
# Building An Admin Panel
Now that you have completed the previous
[Hello World](https://kado.org/guide/hello-world/),
[Make a Simple Website](https://kado.org/guide/make-simple-website/) and
[Database Work Flows](https://kado.org/guide/database-work-flow/) guides, It is
important to note that all the guides combine together into a single project
we will be moving on to building an admin panel.The first step we will be doing
is creating a route folder and within that route folder we will create a
admin.js file and you will use the following code: `Admin.js`.
```js
'use strict'
const fs = require('kado/lib/FileSystem')
class Admin {
static register (app) {
const route = new Admin(fs.path.join(__dirname, '../view/admin'))
app.get('/admin/', route.index())
app.get('/admin/login/', route.login())
app.post('/admin/login/', route.login())
app.get('/admin/logout/', route.logout())
}
```
The code above uses `fs(filesystem)` require in order to get the
`(‘kado/lib/FileSystem’)` then we use the class function to call the admin object.
Then we use static register to acquire the app. The next line
const route = new Admin makes an instance of our route object, then placing
`fs.path.join` method to create and join the path in a string. Lastly, we use
the `_dirname` variable to tell us the absolute path of the directory containing
the executing file, then using app.get() for matching and handling a specific
route when requested.
Beneath the code above you’ll be using the following code: `Admin.js`.
```js
index () {
return (req, res) => {
if (!req.session.get('staff')) {
return res.render('admin/error', { error: 'Must be logged in' })
}
req.locals._pageTitle = 'Home'
res.render('admin/home')
}
}
```
The above code is for creating an index and in that we use return to get our
request and response. Then using `if(!req.session.get(‘staff’)) {` when we
successfully get the session we will return and render a response
`(‘admin/error’, { error: ‘Must be logged in’ })`. On the last two lines the
`pageTitle` is set and we render the page using `res.render(‘admin/home’)`.
Next, we will add a login method to handle displaying and authenticating staff
members. Adding on to Admin.js: `Admin.js`.
```js
login () {
return (req, res) => {
if (req.body.email) {
req.session.set('staff', { email: req.body.email })
res.statusCode = 302
let referer = req.headers.referer || '/admin/'
if (referer.match(/\/admin\/login\/$/)) referer = '/admin/'
res.setHeader('Location', referer)
return res.end()
}
req.locals._pageTitle = 'Login'
res.render('admin/login')
}
}
```
We will use `login()` and by doing so we are creating the login. Under that we
will return the `req` and `res`, then using `if(req.body.email)` we will get the
email body and next we will set the session so that it's for staff and get back
the email body and respond the `StatusCode 302`. The next line we use referer
the headers is the `‘/admin/’` and then match the referer with the admin and
login and then get the `setHeader(‘location’, referer)`.
Finally place this section of code to handle staff logging out of the system:
`Admin.js`.
```js
logout () {
return (req, res) => {
req.session.set('staff', undefined)
res.statusCode = 302
res.setHeader('Location', '/admin/login/')
return res.end()
}
}
}
```
This will create the logout feature. The next line of code we route the function
and set the session for staff and its undefined because it has been declared but
not assigned a value. Then we get the `statusCode` and that will be `302` and
the set the header and end it.
Then you will use the following code to represent the current module and exports
as a module: `Admin.js`.
```js
module.exports = Admin
```
Now that we have completed the admin.js we will be creating a `Help.js` file
and with in the Help.js file we will be using the following code: `Help.js`.
```js
'use strict'
const Assert = require('kado/lib/Assert')
const fs = require('kado/lib/FileSystem')
const HelpModel = require('../model/HelpModel')
const Module = require('kado/lib/Module')
const Route = require('../lib/Route')
class Help extends Module {
constructor () {
super()
this.app = null
this.name = 'help'
this.title = 'Help'
this.description = 'Manage help articles'
}
```
The code above we use Assert, fs, HelpModel, Module and Route to require and
connect the listed folder and files. Next we use the class Help extends module
to create the child class of another class, then we use the constructor()
function that initializes an object, then using the super class to call the
constructor to access the parent properties and methods which will be the
this.app, .name, .title, and .description.
The next section of code we will use the following: `Help.js`.
```js
list () {
return async (req, res) => {
const db = this.db.getEngine()
const query = HelpModel.list()
const rv = await Route.listRoute(db, query)
req.locals._pagetitle = 'List Help Articles'
res.render('admin/help/list', { rows: rv[0], fields: rv[1] })
}
}
```
The above code we will create a `list()` and we are doing that because we can use
this to store multiple pieces of information at once, such as a list of records
in the database or a list of contents. On the next line we use the return async
function to create a promise that will be resolved with the returned value.
Then we use const db to get the database engine and `HelpModel` is used to obtain
a list query from the model to pass that query to the database engine, then we
set the page title with `req.locals_pageTitle`, then we pass the return values
from the database to the template for rendering.
Use the following for the the next section of code: `Help.js`.
```js
listAction () {
return async (req, res) => {
const db = this.db.getEngine()
const query = HelpModel.delete()
const rv = await Route.listActionRoute(db, query, req.body)
if (rv.deleted) res.setHeader('X-Deleted', rv.deleted)
res.redirect('/admin/help/')
}
}
```
Now we will be using the list action method which will be similar to the
previous code we used. We are now using the list action method and the
difference is that we are using the delete method and that will use the
delete query. The next line we are getting the route to the listAction to go to
the db, query and `req.body`. The next line we are saying if the variable is
deleted we get the setHeader response and redirect to `(‘/admin/help’)`.
Moving on to the next section of code you will be using is the following:
`Help.js`.
```js
create () {
return (req, res) => {
req.locals._pagetitle = 'Create Help Article'
res.render('admin/help/create')
}
}
```
The next line we use `create()` so that we use the object to set the page title
and use the create Help article and then render the `(‘admin/help/create’)`.
Under the above code you will now be using the following: `Help.js`.
```js
edit () {
return async (req, res) => {
const db = this.db.getEngine()
const query = HelpModel.byId(req.query.get('id'))
const rv = await db.execute(query.toString(), query.toArray())
Assert.isType('Array', rv[0])
const help = new HelpModel(rv[0].shift())
res.render('admin/help/edit', { help: help })
}
}
```
Now we will be using the `edit()` in order to edit the db, query and rv. First
we get the database engine. Then we call the query to the `HelpModel.byid` to
get the id query, next we execute the database query to a string and an array.
The next line we have `Assert.isType` which will get us the array and get the
new `HelpModel` value. Lase we rent the `(‘admin/help/edit’, { help: help })`.
Use the following to create the `save()`: `Help.js`.
```js
save () {
return async (req, res) => {
const db = this.db.getEngine()
const id = req.body.id || 0
await Route.saveRoute(db, HelpModel, id, req.body)
res.redirect('/admin/help/')
}
}
```
The next part of code is the save which pretty much has a lot of the similar
code except this one will save the route for our db, HelpModel, id, and
req.body.
The next section of code you will use the following: `Help.js`.
```js
admin (app) {
this.app = app
this.db = this.app.database.getEngine('mysql')
app.get('/admin/help/', this.list())
app.get('/admin/help/create/', this.create())
app.get('/admin/help/edit/', this.edit())
app.post('/admin/help/', this.listAction())
app.post('/admin/help/save/', this.save())
}
```
With this part of code we have the `admin()` and that will initiate the app and
get the database engine and connect the following using the app.get.
Now we will be using the following code for the next section: `Help.js`.
```js
main (app) {
// need routes
app.get('/help/', (req, res) => {
res.render(fs.path.join(__dirname, '/view/help.html'))
})
}
}
```
The code above will have the `main(app)` and you will use app.get for
`(‘/help/’, (req, res)` and render the filesystem and join the path to the
`(_dirname, ‘/view/help/html’))`.
Finally the last part of code we have is the last part you will need for the
same reason as we talked about above: `Help.js`.
```js
Help.HelpModel = HelpModel
Help.Model = Help.HelpModel
module.exports = Help
```
## HTML
Now that you have set up the js side of things we are going to get on to be
setting up the HTML structure. It's important to have HTML because without it
you will not be able to make changes to the back-end of your website with your
admin panel. So without further ado lets get started. The first step you will
need to do is go to your project root and create a new folder and name it view,
in that view folder you will create another folder called admin. This for all
of your HTML files that you will be using to make changes to admin panel. The
first file you will want to create is the login.html and use the following code:
`admin.html`.
```html
{{>admin/header}}
<div class="container login-container" style="width: 600px; margin: auto;">
<h3><span class="burstload-icon-lg"></span> Administrator Login</h3>
<form action="{{{_uri.login}}}" method="post">
<div class="form-group">
<label for="email">Email Address</label>
<input type="text" name="email" class="form-control" id="email" value="" placeholder="Email Address">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" id="password" value="" placeholder="password">
</div>
<button type="submit" name="login" class="btn btn-success container"><span class="fa fa-lock"></span> Login</button>
</form>
</div>
{{>admin/footer}}
```
The code above will create a back-end login for the admin page so that you can
use it as an administrator and use your email and password.
The next step we will be creating another file within the admin folder and this
one will be called the home.html `admin.html`.
```html
{{>admin/header}}
<div class="container">
<h1>Welcome to the Admin Panel</h1>
<p>This is one sweet dashboard!</p>
</div>
{{>admin/footer}}
```
This is your landing page. This is a blank page where you will get started.
Next we will create a file inside of the admin folder and it will be called your
header.html and in this file we will be using the following code: `admin.js`.
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=0">
{{#_pageTitle}}
<title>{{_pageTitle}} - {{_appTitle}}</title>
{{/_pageTitle}}
{{^_pageTitle}}
<title>{{_appTitle}}</title>
{{/_pageTitle}}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<a class="navbar-brand" href="/"><span class="nav-hover"> Admin</span></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/admin/"><span class="nav-hover">Dashboard</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/admin/help/"><span class="nav-hover">Help</span></a>
</li>
</ul>
</div>
<span>&nbsp;&nbsp;&nbsp;</span>
<a href="/admin/logout/" class="btn btn-subscribe"><span class="fa fa-file-upload"></span> Logout</a>
</nav>
```
The code above will establish the header of your page.
This is the footer.html, the following code is used so that you can create the
bottom of your page. `admin.js`.
```html
{{#_dev}}
<%&_pageProfile.HTML%>
{{/_dev}}
{{>js}}
</body>
</html>
```
The next file you will be creating is also in your admin folder and will be your
error.html file, this will allow you to set up a place to create for your error
message. Use the following code. `admin.js`,
`admin.js`.
```html
{{>admin/header}}
<main role="main" class="container">
<h1>An Error has Occurred</h1>
{{error}}
<br /><br />
</main>
{{>admin/footer}}
```
The last file you will need to add in your admin folder is your js.html file and
this will run a client side JavaScript code on your webpage. the following code
looks like this: `admin.html`.
```html
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script type="text/javascript" src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script type="text/javascript" src="/js/explode.js"></script>
<script type="text/javascript" src="/js/FadeIn.js"></script>
<script async defer src="//www.google.com/recaptcha/api.js" type="text/javascript"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-67843687-7"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-67843687-7');
</script>
```
\ No newline at end of file
......@@ -2,16 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="keywords" content="cloud hosting, cloud hosting, file storage, file download, file upload, video streaming">
<meta name="description" content="Cloud Hosting, Cloud Hosting, File Storage, Video Streaming, File and Folder Sharing, made possible by Burstload">
<meta name="author" content="BurstLoad">
<meta property="og:site_name" content="BurstLoad">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="/css/burstload.css">
{{#_css}}
<link rel="stylesheet" type="text/css" href="{{{uri}}}">
{{/_css}}
{{#_pageTitle}}
<title>{{_pageTitle}} - {{_appTitle}}</title>
{{/_pageTitle}}
......@@ -21,7 +12,7 @@
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<a class="navbar-brand" href="/"><span class="burstload-icon-lg"></span><span class="nav-hover"> Admin</span></a>
<a class="navbar-brand" href="/"><span class="nav-hover"> Admin</span></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
......@@ -30,9 +21,6 @@
<li class="nav-item active">
<a class="nav-link" href="/admin/"><span class="nav-hover">Dashboard</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/admin/user/"><span class="nav-hover">Users</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/admin/help/"><span class="nav-hover">Help</span></a>
</li>
......
......@@ -2,18 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="keywords" content="cloud hosting, cloud hosting, file storage, file download, file upload, video streaming">
<meta name="description" content="Cloud Hosting, Cloud Hosting, File Storage, Video Streaming, File and Folder Sharing, made possible by Burstload">
<meta name="author" content="BurstLoad">
<meta property="og:site_name" content="BurstLoad">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=0">
{{#_bootstrap}}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
{{/_bootstrap}}
<link rel="stylesheet" href="/css/burstload.css">
{{#_css}}
<link rel="stylesheet" type="text/css" href="{{{uri}}}">
{{/_css}}
{{#_pageTitle}}
<title>{{_pageTitle}} - {{_appTitle}}</title>
{{/_pageTitle}}
......@@ -23,39 +12,21 @@
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<a class="navbar-brand" href="/"><span class="burstload-icon-lg"></span><span class="nav-hover"> Admin</span></a>
<a class="navbar-brand" href="/"><span class="nav-hover"> Admin</span></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/"><span class="nav-hover">Home</span></a>
<a class="nav-link" href="/admin/"><span class="nav-hover">Dashboard</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/admin/"><span class="nav-hover">Admin</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/business-admin/"><span class="nav-hover">Business Admin</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/features/"><span class="nav-hover">Features</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/about/"><span class="nav-hover">About</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/news/"><span class="nav-hover">News</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/help/"><span class="nav-hover">Help</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/contact-us/"><span class="nav-hover">Contact Us</span></a>
<a class="nav-link" href="/admin/help/"><span class="nav-hover">Help</span></a>
</li>
</ul>
</div>
<a href="/login/" class="btn btn-success"><span class="fa fa-user"></span> My Account</a>
<span>&nbsp;&nbsp;&nbsp;</span>
<a href="/order/" class="btn btn-subscribe"><span class="fa fa-file-upload"></span> Order Now</a>
<a href="/admin/logout/" class="btn btn-subscribe"><span class="fa fa-file-upload"></span> Logout</a>
</nav>
{{>header}}
<div class="container login-container">
<h3>Login to Burstload <span class="burstload-icon-lg"></span></h3>
<form action="{{{_uri.login}}}" method="post">
<div class="form-group">
<label for="email">Email Address</label>
<input type="text" name="email" class="form-control" id="email" value="" placeholder="Email Address">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" id="password" value="" placeholder="password">
</div>
<button type="submit" name="login" class="btn btn-success container"><span class="fa fa-lock"></span> Login</button>
</form>
<div>Forgot Password? <a href="{{{_uri.user.forgot_password}}}">Reset Password</a></div>
<div>Dont have an account? <a href="{{{_uri.order}}}">Create One</a></div>
<div>Just need help? <a href="{{{_uri.contact}}}">Contact Us</a></div>
</div>
{{>footer}}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment