Implemented v1 admin dashboard

This commit is contained in:
Logan Cusano
2023-08-04 23:21:35 -04:00
parent 76c4d002a0
commit 880f1ccb01
5 changed files with 136 additions and 130 deletions

View File

@@ -82,6 +82,7 @@ a {
position: relative;
margin-bottom: 30px;
box-shadow: 0 0.46875rem 2.1875rem rgba(90, 97, 105, 0.1), 0 0.9375rem 1.40625rem rgba(90, 97, 105, 0.1), 0 0.25rem 0.53125rem rgba(90, 97, 105, 0.12), 0 0.125rem 0.1875rem rgba(90, 97, 105, 0.1);
min-height: 85%;
}
.info-card .card-statistic .card-icon-large .bi {

View File

@@ -1,12 +1,25 @@
var express = require('express');
var router = express.Router();
const { getAllNodes, getNodeInfoFromId } = require("../utilities/mysqlHandler");
const { getAllNodes, getNodeInfoFromId, getAllConnections } = require("../utilities/mysqlHandler");
const { filterPresetsAvailable } = require("../utilities/utils");
/* GET home page. */
router.get('/', (req, res) => {
//var sources = libCore.getSources();
return res.render('index', {'page': 'index'});
router.get('/', async (req, res) => {
var nodes = await new Promise((recordResolve, recordReject) => {
getAllNodes((nodeRows) => {
recordResolve(nodeRows);
});
});
var connections = await getAllConnections();
var presets = await new Promise((recordResolve, recordReject) => {
getAllNodes((nodeRows) => {
recordResolve(filterPresetsAvailable(nodeRows));
});
});
//var sources = libCore.getSources();
return res.render('index', { 'page': 'index', 'nodes': nodes, 'connections': connections, 'presets': presets });
});
/* GET node controller page. */
@@ -15,10 +28,10 @@ router.get('/controller', async (req, res) => {
getAllNodes((nodeRows) => {
recordResolve(nodeRows);
});
});
});
//var sources = libCore.getSources();
return res.render('controller', {'nodes' : nodes, 'page': 'controller'});
return res.render('controller', { 'nodes': nodes, 'page': 'controller' });
});
/* GET individual node page. */
@@ -26,7 +39,7 @@ router.get('/node/:id', async (req, res) => {
var node = await getNodeInfoFromId(req.params.id);
//var sources = libCore.getSources();
return res.render('node', {'node' : node, 'page': 'node'});
return res.render('node', { 'node': node, 'page': 'node' });
});
module.exports = router;

View File

@@ -1,133 +1,64 @@
<%- include('partials/htmlHead.ejs', {'page': page}) %>
<div class="container">
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-4 mt-2">
<%- include('partials/valueChip.ejs', {
'title': 'Nodes in the Network',
'bgColor': "orange-dark",
'value': nodes.length,
'progressPercent': false,
'icon': 'server'
}) %>
<%- include('partials/valueChip.ejs', {
'title': 'Nodes Online',
'bgColor': "green",
'value': nodes.filter(node => node.online).length,
'progressPercent': false,
'icon': 'cpu-fill'
}) %>
<%- include('partials/valueChip.ejs', {
'title': 'Nodes with Discord Connections',
'bgColor': "blue-dark",
'value': connections.length,
'progressPercent': false,
'icon': 'gear-wide-connected'
}) %>
</div>
<div class="my-4">
<p><h3><b>Current Connections</b></h3></p>
</div>
<hr>
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-4">
<div class="col-xl-3 col-lg-6">
<div class="info-card l-bg-cherry">
<div class="card-statistic p-4">
<div class="card-icon card-icon-large"><i class="bi bi-cart"></i></div>
<div class="mb-4">
<h5 class="card-title mb-0">New Orders</h5>
</div>
<div class="row align-items-center mb-2 d-flex">
<div class="col-8">
<h2 class="d-flex align-items-center mb-0">
3,243
</h2>
</div>
<div class="col-4 text-right">
<span>12.5% <i class="fa fa-arrow-up"></i></span>
</div>
</div>
<div class="progress mt-1 " data-height="8" style="height: 8px;">
<div class="progress-bar l-bg-cyan" role="progressbar" data-width="25%" aria-valuenow="25"
aria-valuemin="0" aria-valuemax="100" style="width: 25%;"></div>
</div>
</div>
</div>
</div>
<% for(const conn of connections) { %>
<%- include('partials/connectionCard.ejs', {'connection': conn}) %>
<%}%>
</div>
<div class="col-xl-3 col-lg-6">
<div class="info-card l-bg-blue-dark">
<div class="card-statistic p-4">
<div class="card-icon card-icon-large"><i class="bi bi-cart"></i></div>
<div class="mb-4">
<h5 class="card-title mb-0">New Orders</h5>
</div>
<div class="row align-items-center mb-2 d-flex">
<div class="col-8">
<h2 class="d-flex align-items-center mb-0">
3,243
</h2>
</div>
<div class="col-4 text-right">
<span>12.5% <i class="fa fa-arrow-up"></i></span>
</div>
</div>
<div class="progress mt-1 " data-height="8" style="height: 8px;">
<div class="progress-bar l-bg-cyan" role="progressbar" data-width="25%" aria-valuenow="25"
aria-valuemin="0" aria-valuemax="100" style="width: 25%;"></div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-sm-6">
<div class="card node-card">
<div class="card-body">
<div class="dropdown float-end">
<a class="text-muted dropdown-toggle font-size-16" href="#" role="button"
data-bs-toggle="dropdown" aria-haspopup="true"><i
class="bx bx-dots-horizontal-rounded"></i></a>
<div class="dropdown-menu dropdown-menu-end"><a class="dropdown-item" href="#">Edit</a><a
class="dropdown-item" href="#">Action</a><a class="dropdown-item"
href="#">Remove</a></div>
</div>
<div class="d-flex align-items-center">
<div><img src="https://bootdey.com/img/Content/avatar/avatar1.png" alt=""
class="avatar-md rounded-circle img-thumbnail" /></div>
<div class="flex-1 ms-3">
<h5 class="font-size-16 mb-1"><a href="#" class="text-dark">Phyllis Gatlin</a></h5>
<span class="badge badge-soft-success mb-0">Full Stack Developer</span>
</div>
</div>
<div class="mt-3 pt-1">
<p class="text-muted mb-0"><i
class="mdi mdi-phone font-size-15 align-middle pe-2 text-primary"></i> 070 2860 5375
</p>
<p class="text-muted mb-0 mt-2"><i
class="mdi mdi-email font-size-15 align-middle pe-2 text-primary"></i>
PhyllisGatlin@spy.com</p>
<p class="text-muted mb-0 mt-2"><i
class="mdi mdi-google-maps font-size-15 align-middle pe-2 text-primary"></i> 52
Ilchester MYBSTER 9WX</p>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-sm-6">
<div class="card node-card">
<div class="card-body">
<div class="dropdown float-end">
<a class="text-muted dropdown-toggle font-size-16" href="#" role="button"
data-bs-toggle="dropdown" aria-haspopup="true"><i
class="bx bx-dots-horizontal-rounded"></i></a>
<div class="dropdown-menu dropdown-menu-end"><a class="dropdown-item" href="#">Edit</a><a
class="dropdown-item" href="#">Action</a><a class="dropdown-item"
href="#">Remove</a></div>
</div>
<div class="d-flex align-items-center">
<div><img src="https://bootdey.com/img/Content/avatar/avatar5.png" alt=""
class="avatar-md rounded-circle img-thumbnail" /></div>
<div class="flex-1 ms-3">
<h5 class="font-size-16 mb-1"><a href="#" class="text-dark">Diana Owens</a></h5>
<span class="badge badge-soft-danger mb-0">UI/UX Designer</span>
</div>
</div>
<div class="mt-3 pt-1">
<p class="text-muted mb-0"><i
class="mdi mdi-phone font-size-15 align-middle pe-2 text-primary"></i> 087 6321 3235
</p>
<p class="text-muted mb-0 mt-2"><i
class="mdi mdi-email font-size-15 align-middle pe-2 text-primary"></i>
DianaOwens@spy.com</p>
<p class="text-muted mb-0 mt-2"><i
class="mdi mdi-google-maps font-size-15 align-middle pe-2 text-primary"></i> 52
Ilchester MYBSTER 9WX</p>
</div>
<div class="d-flex gap-2 pt-4">
<button type="button" class="btn btn-soft-primary btn-sm w-50"><i
class="bx bx-user me-1"></i> Profile</button>
<button type="button" class="btn btn-primary btn-sm w-50"><i
class="bx bx-message-square-dots me-1"></i> Contact</button>
</div>
</div>
</div>
</div>
<div class="my-4">
<p><h3><b>Online Nodes</b></h3></p>
</div>
<hr>
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-4">
<% for(const node of nodes.filter(node => node.online)) { %>
<%- include('partials/nodeCard.ejs', {'node': node}) %>
<%}%>
</div>
<div class="my-4">
<p><h3><b>Offline Nodes</b></h3></p>
</div>
<hr>
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-4">
<% for(const node of nodes.filter(node => node.online == false)) { %>
<%- include('partials/nodeCard.ejs', {'node': node}) %>
<%}%>
</div>
</div>
<%- include('partials/bodyEnd.ejs') %>
<%- include('partials/htmlFooter.ejs') %>

View File

@@ -0,0 +1,29 @@
<div class="col-xl-3 col-sm-6">
<div class="card node-card">
<div class="card-body">
<div class="dropdown float-end">
<a class="text-muted dropdown-toggle font-size-16" href="#" role="button" data-bs-toggle="dropdown"
aria-haspopup="true">
<i class="bx bx-dots-horizontal-rounded"></i>
</a>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item node-action">Edit</a>
<a class="dropdown-item node-action" onclick="">Send Heartbeat</a>
</div>
</div>
<div class="d-flex align-items-center">
<div class="flex-1 ms-3">
<h5 class="font-size-16 mb-1"><a class="text-dark">
<%= connection.clientObject.name%>
</a></h5>
</div>
</div>
<div class="mt-3 pt-1">
<p class="text-muted mb-0">
<i class="bi bi-cpu-fill font-size-15 align-middle pe-2 text-primary"></i>
Node ID: <a href="/node/<%= connection.node.id %>"><%= connection.node.id %></a>
</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,32 @@
<div class="col-xl-3 col-lg-6">
<div class="info-card l-bg-<%=bgColor%>">
<div class="card-statistic p-4">
<div class="card-icon card-icon-large"><i class="bi bi-<%=icon%>"></i></div>
<div class="mb-4">
<h5 class="card-title mb-0">
<%=title%>
</h5>
</div>
<div class="row align-items-center mb-2 d-flex">
<div class="col-8">
<h2 class="d-flex align-items-center mb-0">
<%=value%>
</h2>
</div>
<% if (progressPercent) {%>
<div class="col-4 text-right">
<span>
<%=progressPercent%>%<i class="fa fa-arrow-up"></i>
</span>
</div>
<%}%>
</div>
<% if (progressPercent) {%>
<div class="progress mt-1 " data-height="8" style="height: 8px;">
<div class="progress-bar l-bg-cyan" role="progressbar" data-width="<%=progressPercent%>%" aria-valuenow="<%=progressPercent%>"
aria-valuemin="0" aria-valuemax="100" style="width: <%=progressPercent%>%;"></div>
</div>
<%}%>
</div>
</div>
</div>