created pages for images, networks, and volumes

This commit is contained in:
lllllllillllllillll 2023-12-17 12:28:58 -08:00
parent 385e2e80ee
commit 9a065a8883
12 changed files with 804 additions and 63 deletions

View file

@ -1,7 +1,7 @@
# DweebUI
DweebUI is a simple Docker web interface created using Javascript, Node.JS, and Express.
Pre-Pre-Pre-Pre-Pre Alpha v0.09 ( :fire: Experimental. Don't install on any servers you care about :fire: )
v0.09
[![GitHub Stars](https://img.shields.io/github/stars/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll)
[![GitHub Activity](https://img.shields.io/github/commit-activity/y/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll)
@ -9,10 +9,6 @@ Pre-Pre-Pre-Pre-Pre Alpha v0.09 ( :fire: Experimental. Don't install on any serv
[![GitHub License](https://img.shields.io/github/license/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll/DweebUI/blob/main/LICENSE)
* This is a personal project that I decided to share. I'm sure it has plenty of bugs and mistakes.
* I haven't used Github very much and I'm still new to Javascript.
* I probably should have waited a lot longer to share this :|
<a href="https://raw.githubusercontent.com//lllllllillllllillll/DweebUI/main/screenshots/dashboard.png"><img src="https://raw.githubusercontent.com/lllllllillllllillll/DweebUI/main/screenshots/dashboard.png" width="50%"/></a>
<a href="https://raw.githubusercontent.com/lllllllillllllillll/DweebUI/main/screenshots/apps.png"><img src="https://raw.githubusercontent.com/lllllllillllllillll/DweebUI/main/screenshots/apps.png" width="50%"/></a>
@ -100,4 +96,6 @@ sudo ./setup.sh
* Icons from Walkxcode with some renames and additions: https://github.com/walkxcode/dashboard-icons
## Supporters
## Supporters
* MM (Patreon)

7
app.js
View file

@ -9,7 +9,7 @@ const PORT = process.env.PORT || 8000;
const routes = require("./routes");
// Functions and variables
const { serverStats, containerList, containerStats, containerAction, containerLogs, hiddenContainers } = require('./functions/system');
const { serverStats, containerList, containerStats, containerAction, containerLogs, hiddenContainers, dockerImages, dockerVolumes, dockerNetworks } = require('./functions/system');
let sentList, clicked;
app.locals.site_list = '';
@ -58,6 +58,11 @@ io.on('connection', (socket) => {
if (sentList != null) { socket.emit('cards', sentList); }
if((app.locals.install != '') && (app.locals.install != null)){ socket.emit('install', app.locals.install); }
console.log(`Imags: ${dockerImages()}`);
console.log(`Volumes: ${dockerVolumes()}`);
console.log(`Networks: ${dockerNetworks()}`);
// Send server metrics
let ServerStats = setInterval(async () => {
socket.emit('metrics', await serverStats());

54
controllers/images.js Normal file
View file

@ -0,0 +1,54 @@
const User = require('../database/UserModel');
exports.Users = async function(req, res) {
if (req.session.role == "admin") {
// Get the user.
let user = await User.findOne({ where: { UUID: req.session.UUID }});
let user_list = `
<tr>
<th><input class="form-check-input" type="checkbox"></th>
<th>ID</th>
<th>Avatar</th>
<th>Name</th>
<th>Username</th>
<th>Email</th>
<th>UUID</th>
<th>Role</th>
<th>Status</th>
<th>Actions</th>
</tr>`
let users = await User.findAll();
users.forEach((account) => {
full_name = account.first_name + ' ' + account.last_name;
user_info = `
<tr>
<td><input class="form-check-input" type="checkbox"></td>
<td>${user.id}</td>
<td><span class="avatar me-2">${account.avatar}</span></td>
<td>${full_name}</td>
<td>${account.username}</td>
<td>${account.email}</td>
<td>${account.UUID}</td>
<td>${account.role}</td>
<td><span class="badge badge-outline text-green">Active</span></td>
<td><a href="#" class="btn">Edit</a></td>
</tr>`
user_list += user_info;
});
// Render the home page
res.render("pages/users", {
name: user.first_name + ' ' + user.last_name,
role: user.role,
avatar: user.avatar,
isLoggedIn: true,
user_list: user_list
});
} else {
// Redirect to the login page
res.redirect("/login");
}
}

54
controllers/networks.js Normal file
View file

@ -0,0 +1,54 @@
const User = require('../database/UserModel');
exports.Users = async function(req, res) {
if (req.session.role == "admin") {
// Get the user.
let user = await User.findOne({ where: { UUID: req.session.UUID }});
let user_list = `
<tr>
<th><input class="form-check-input" type="checkbox"></th>
<th>ID</th>
<th>Avatar</th>
<th>Name</th>
<th>Username</th>
<th>Email</th>
<th>UUID</th>
<th>Role</th>
<th>Status</th>
<th>Actions</th>
</tr>`
let users = await User.findAll();
users.forEach((account) => {
full_name = account.first_name + ' ' + account.last_name;
user_info = `
<tr>
<td><input class="form-check-input" type="checkbox"></td>
<td>${user.id}</td>
<td><span class="avatar me-2">${account.avatar}</span></td>
<td>${full_name}</td>
<td>${account.username}</td>
<td>${account.email}</td>
<td>${account.UUID}</td>
<td>${account.role}</td>
<td><span class="badge badge-outline text-green">Active</span></td>
<td><a href="#" class="btn">Edit</a></td>
</tr>`
user_list += user_info;
});
// Render the home page
res.render("pages/users", {
name: user.first_name + ' ' + user.last_name,
role: user.role,
avatar: user.avatar,
isLoggedIn: true,
user_list: user_list
});
} else {
// Redirect to the login page
res.redirect("/login");
}
}

54
controllers/volumes.js Normal file
View file

@ -0,0 +1,54 @@
const User = require('../database/UserModel');
exports.Users = async function(req, res) {
if (req.session.role == "admin") {
// Get the user.
let user = await User.findOne({ where: { UUID: req.session.UUID }});
let user_list = `
<tr>
<th><input class="form-check-input" type="checkbox"></th>
<th>ID</th>
<th>Avatar</th>
<th>Name</th>
<th>Username</th>
<th>Email</th>
<th>UUID</th>
<th>Role</th>
<th>Status</th>
<th>Actions</th>
</tr>`
let users = await User.findAll();
users.forEach((account) => {
full_name = account.first_name + ' ' + account.last_name;
user_info = `
<tr>
<td><input class="form-check-input" type="checkbox"></td>
<td>${user.id}</td>
<td><span class="avatar me-2">${account.avatar}</span></td>
<td>${full_name}</td>
<td>${account.username}</td>
<td>${account.email}</td>
<td>${account.UUID}</td>
<td>${account.role}</td>
<td><span class="badge badge-outline text-green">Active</span></td>
<td><a href="#" class="btn">Edit</a></td>
</tr>`
user_list += user_info;
});
// Render the home page
res.render("pages/users", {
name: user.first_name + ' ' + user.last_name,
role: user.role,
avatar: user.avatar,
isLoggedIn: true,
user_list: user_list
});
} else {
// Redirect to the login page
res.redirect("/login");
}
}

View file

@ -312,4 +312,80 @@ module.exports.containerLogs = function (data) {
});
});
});
};
};
module.exports.dockerImages = async function () {
let image_list = '';
const data = await docker.listImages();
return data;
// for (const image of data) {
// let imageVersion = image.RepoTags[0].split('/');
// let service = imageVersion[imageVersion.length - 1].split(':')[0];
// let image_info = {
// name: image.RepoTags[0],
// service: service,
// id: image.Id,
// size: image.Size,
// style: "Compact"
// }
// let dockerCard = dashCard(image_info);
// image_list += dockerCard;
// }
// return image_list;
}
module.exports.dockerVolumes = async function () {
let volume_list = '';
const data = await docker.listVolumes();
return data;
// for (const volume of data.Volumes) {
// let volume_info = {
// name: volume.Name,
// style: "Compact"
// }
// let dockerCard = dashCard(volume_info);
// volume_list += dockerCard;
// }
// return volume_list;
}
module.exports.dockerNetworks = async function () {
let network_list = '';
const data = await docker.listNetworks();
return data;
// for (const network of data) {
// let network_info = {
// name: network.Name,
// style: "Compact"
// }
// let dockerCard = dashCard(network_info);
// network_list += dockerCard;
// }
// return network_list;
}

View file

@ -5,6 +5,10 @@ const { Dashboard, AddSite, RemoveSite, RefreshSites, DisableSite, EnableSite }
const { Login, processLogin, Logout, Register, processRegister } = require("../controllers/auth");
const { Apps, searchApps, Install, Uninstall } = require("../controllers/apps");
const { Images } = require("../controllers/images");
const { Volumes } = require("../controllers/volumes");
const { Networks } = require("../controllers/networks");
const { Users } = require("../controllers/users");
const { Account } = require("../controllers/account");
const { Settings } = require("../controllers/settings");
@ -12,10 +16,7 @@ const { Settings } = require("../controllers/settings");
// Authentication middleware
const authenticate = (req, res, next) => {
if (req.session && req.session.user) {
console.log("User:", req.session.user);
console.log("UUID:", req.session.UUID);
console.log("Role:", req.session.role);
console.log("Page:", req.originalUrl);
console.log(`User ${req.session.user} [${req.session.role} : ${req.session.UUID}] accessed ${req.originalUrl}`)
next();
} else {
res.redirect("/login");
@ -30,6 +31,8 @@ router.get("/refreshsites", authenticate, RefreshSites);
router.post("/disablesite", authenticate, DisableSite);
router.post("/enablesite", authenticate, EnableSite);
router.get("/images", authenticate, Images);
// Auth
router.get("/login", Login);
router.post("/login", processLogin);

366
views/pages/images.ejs Normal file
View file

@ -0,0 +1,366 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Images</title>
<link href="/css/tabler.min.css?1685973381" rel="stylesheet"/>
<link href="/css/demo.min.css?1685973381" rel="stylesheet"/>
<style>
@import url('https://rsms.me/inter/inter.css');
:root {
--tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
}
body {
font-feature-settings: "cv03", "cv04", "cv11";
}
</style>
</head>
<body >
<script src="/js/demo-theme.min.js?1685973381"></script>
<div class="page">
<%- include('../partials/navbar.ejs') %>
<div class="page-wrapper">
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<h2 class="page-title">
Users
</h2>
</div>
</div>
</div>
</div>
<div class="page-body">
<div class="container-xl">
<div class="card">
<div class="card-body">
<div id="table-default" class="table-responsive">
<table class="table">
<thead>
<tr>
<th><button class="table-sort" data-sort="sort-name">Name</button></th>
<th><button class="table-sort" data-sort="sort-city">City</button></th>
<th><button class="table-sort" data-sort="sort-type">Type</button></th>
<th><button class="table-sort" data-sort="sort-score">Score</button></th>
<th><button class="table-sort" data-sort="sort-date">Date</button></th>
<th><button class="table-sort" data-sort="sort-quantity">Quantity</button></th>
<th><button class="table-sort" data-sort="sort-progress">Progress</button></th>
</tr>
</thead>
<tbody class="table-tbody"><tr>
<td class="sort-name">Steel Vengeance</td>
<td class="sort-city">Cedar Point, United States</td>
<td class="sort-type">RMC Hybrid</td>
<td class="sort-score">100,0%</td>
<td class="sort-date" data-date="1628122643">August 05, 2021</td>
<td class="sort-quantity">74</td>
<td class="sort-progress" data-progress="30">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">30%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 30%" role="progressbar" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100" aria-label="30% Complete">
<span class="visually-hidden">30% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Fury 325</td>
<td class="sort-city">Carowinds, United States</td>
<td class="sort-type">B&amp;M Giga, Hyper, Steel</td>
<td class="sort-score">99,3%</td>
<td class="sort-date" data-date="1546344668">January 01, 2019</td>
<td class="sort-quantity">49</td>
<td class="sort-progress" data-progress="48">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">48%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 48%" role="progressbar" aria-valuenow="48" aria-valuemin="0" aria-valuemax="100" aria-label="48% Complete">
<span class="visually-hidden">48% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Wildfire</td>
<td class="sort-city">Kolmården Sweden</td>
<td class="sort-type">RMC Twister, Wooden, Terrain</td>
<td class="sort-score">99,3%</td>
<td class="sort-date" data-date="1545977105">December 28, 2018</td>
<td class="sort-quantity">8</td>
<td class="sort-progress" data-progress="9">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">9%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 9%" role="progressbar" aria-valuenow="9" aria-valuemin="0" aria-valuemax="100" aria-label="9% Complete">
<span class="visually-hidden">9% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Lightning Rod</td>
<td class="sort-city">Dollywood, United States</td>
<td class="sort-type">RMC Wooden</td>
<td class="sort-score">99,1%</td>
<td class="sort-date" data-date="1605096500">November 11, 2020</td>
<td class="sort-quantity">104</td>
<td class="sort-progress" data-progress="98">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">98%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 98%" role="progressbar" aria-valuenow="98" aria-valuemin="0" aria-valuemax="100" aria-label="98% Complete">
<span class="visually-hidden">98% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Maverick</td>
<td class="sort-city">Cedar Point, United States</td>
<td class="sort-type">Intamin Rocket, Steel</td>
<td class="sort-score">99,1%</td>
<td class="sort-date" data-date="1636929477">November 14, 2021</td>
<td class="sort-quantity">86</td>
<td class="sort-progress" data-progress="46">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">46%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 46%" role="progressbar" aria-valuenow="46" aria-valuemin="0" aria-valuemax="100" aria-label="46% Complete">
<span class="visually-hidden">46% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">El Toro</td>
<td class="sort-city">Six Flags Great Adventure, United States</td>
<td class="sort-type">Intamin Twister, Wooden</td>
<td class="sort-score">99,0%</td>
<td class="sort-date" data-date="1613007167">February 11, 2021</td>
<td class="sort-quantity">130</td>
<td class="sort-progress" data-progress="29">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">29%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 29%" role="progressbar" aria-valuenow="29" aria-valuemin="0" aria-valuemax="100" aria-label="29% Complete">
<span class="visually-hidden">29% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Twisted Colossus</td>
<td class="sort-city">Six Flags Magic Mountain, United States</td>
<td class="sort-type">RMC Hybrid</td>
<td class="sort-score">98,9%</td>
<td class="sort-date" data-date="1572695602">November 02, 2019</td>
<td class="sort-quantity">30</td>
<td class="sort-progress" data-progress="57">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">57%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 57%" role="progressbar" aria-valuenow="57" aria-valuemin="0" aria-valuemax="100" aria-label="57% Complete">
<span class="visually-hidden">57% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Eejanaika new</td>
<td class="sort-city">Fuji-Q Highland, Japan</td>
<td class="sort-type">S&amp;S Power 4th Dimension, Steel</td>
<td class="sort-score">98,6%</td>
<td class="sort-date" data-date="1615765992">March 14, 2021</td>
<td class="sort-quantity">162</td>
<td class="sort-progress" data-progress="91">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">91%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 91%" role="progressbar" aria-valuenow="91" aria-valuemin="0" aria-valuemax="100" aria-label="91% Complete">
<span class="visually-hidden">91% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Wicked Cyclone</td>
<td class="sort-city">Six Flags New England, United States</td>
<td class="sort-type">RMC Hybrid</td>
<td class="sort-score">98,2%</td>
<td class="sort-date" data-date="1570144735">October 03, 2019</td>
<td class="sort-quantity">174</td>
<td class="sort-progress" data-progress="3">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">3%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 3%" role="progressbar" aria-valuenow="3" aria-valuemin="0" aria-valuemax="100" aria-label="3% Complete">
<span class="visually-hidden">3% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Shambhala</td>
<td class="sort-city">Port Aventura, Spain</td>
<td class="sort-type">B&amp;M Hyper, Steel</td>
<td class="sort-score">98,2%</td>
<td class="sort-date" data-date="1536285945">September 07, 2018</td>
<td class="sort-quantity">111</td>
<td class="sort-progress" data-progress="24">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">24%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 24%" role="progressbar" aria-valuenow="24" aria-valuemin="0" aria-valuemax="100" aria-label="24% Complete">
<span class="visually-hidden">24% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Taron</td>
<td class="sort-city">Phantasialand, Germany</td>
<td class="sort-type">Intamin Sit Down, Steel</td>
<td class="sort-score">98,2%</td>
<td class="sort-date" data-date="1543072573">November 24, 2018</td>
<td class="sort-quantity">130</td>
<td class="sort-progress" data-progress="48">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">48%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 48%" role="progressbar" aria-valuenow="48" aria-valuemin="0" aria-valuemax="100" aria-label="48% Complete">
<span class="visually-hidden">48% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Expedition Ge Force</td>
<td class="sort-city">Holiday Park, Germany</td>
<td class="sort-type">Intamin Megacoaster, Steel</td>
<td class="sort-score">98,2%</td>
<td class="sort-date" data-date="1562384190">July 06, 2019</td>
<td class="sort-quantity">157</td>
<td class="sort-progress" data-progress="57">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">57%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 57%" role="progressbar" aria-valuenow="57" aria-valuemin="0" aria-valuemax="100" aria-label="57% Complete">
<span class="visually-hidden">57% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Storm Chaser</td>
<td class="sort-city">Kentucky Kingdom, United States</td>
<td class="sort-type">RMC Steel</td>
<td class="sort-score">97,9%</td>
<td class="sort-date" data-date="1567543123">September 03, 2019</td>
<td class="sort-quantity">43</td>
<td class="sort-progress" data-progress="42">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">42%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 42%" role="progressbar" aria-valuenow="42" aria-valuemin="0" aria-valuemax="100" aria-label="42% Complete">
<span class="visually-hidden">42% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Helix</td>
<td class="sort-city">Liseberg, Sweden</td>
<td class="sort-type">Mack Looper, Steel, Terrain</td>
<td class="sort-score">97,9%</td>
<td class="sort-date" data-date="1524703250">April 26, 2018</td>
<td class="sort-quantity">151</td>
<td class="sort-progress" data-progress="54">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">54%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 54%" role="progressbar" aria-valuenow="54" aria-valuemin="0" aria-valuemax="100" aria-label="54% Complete">
<span class="visually-hidden">54% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr><tr>
<td class="sort-name">Outlaw Run</td>
<td class="sort-city">Silver Dollar City, United States</td>
<td class="sort-type">RMC Hybrid</td>
<td class="sort-score">96,6%</td>
<td class="sort-date" data-date="1559333540">May 31, 2019</td>
<td class="sort-quantity">131</td>
<td class="sort-progress" data-progress="64">
<div class="row align-items-center">
<div class="col-12 col-lg-auto">64%</div>
<div class="col">
<div class="progress" style="width: 5rem">
<div class="progress-bar" style="width: 64%" role="progressbar" aria-valuenow="64" aria-valuemin="0" aria-valuemax="100" aria-label="64% Complete">
<span class="visually-hidden">64% Complete</span>
</div>
</div>
</div>
</div>
</td>
</tr></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<%- include('../partials/footer.ejs') %>
</div>
</div>
<!-- Libs JS -->
<!-- Tabler Core -->
<script src="/js/tabler.min.js?1685973381" defer></script>
<script src="/js/demo.min.js?1685973381" defer></script>
</body>
</html>

71
views/pages/networks.ejs Normal file
View file

@ -0,0 +1,71 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Users</title>
<link href="/css/tabler.min.css?1685973381" rel="stylesheet"/>
<link href="/css/demo.min.css?1685973381" rel="stylesheet"/>
<style>
@import url('https://rsms.me/inter/inter.css');
:root {
--tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
}
body {
font-feature-settings: "cv03", "cv04", "cv11";
}
</style>
</head>
<body >
<script src="/js/demo-theme.min.js?1685973381"></script>
<div class="page">
<%- include('../partials/navbar.ejs') %>
<div class="page-wrapper">
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<h2 class="page-title">
Users
</h2>
</div>
</div>
</div>
</div>
<div class="page-body">
<div class="container-xl">
<div class="row row-cards">
<div class="col-12">
<div class="card">
<div class="table-responsive">
<table class="table table-vcenter table-mobile-md card-table">
<tbody>
<%- user_list %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<%- include('../partials/footer.ejs') %>
</div>
</div>
<!-- Libs JS -->
<!-- Tabler Core -->
<script src="/js/tabler.min.js?1685973381" defer></script>
<script src="/js/demo.min.js?1685973381" defer></script>
</body>
</html>

View file

@ -1,19 +1,10 @@
<!doctype html>
<!--
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
* @version 1.0.0-beta19
* @link https://tabler.io
* Copyright 2018-2023 The Tabler Authors
* Copyright 2018-2023 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
-->
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Users</title>
<!-- CSS files -->
<link href="/css/tabler.min.css?1685973381" rel="stylesheet"/>
<link href="/css/demo.min.css?1685973381" rel="stylesheet"/>
<style>
@ -29,12 +20,12 @@
<body >
<script src="/js/demo-theme.min.js?1685973381"></script>
<div class="page">
<!-- Navbar -->
<%- include('../partials/navbar.ejs') %>
<div class="page-wrapper">
<!-- Page header -->
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
@ -46,12 +37,11 @@
</div>
</div>
</div>
<!-- Page body -->
<div class="page-body">
<div class="container-xl">
<div class="row row-cards">
<div class="col-12">
<div class="card">
<div class="table-responsive">

71
views/pages/volumes.ejs Normal file
View file

@ -0,0 +1,71 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Users</title>
<link href="/css/tabler.min.css?1685973381" rel="stylesheet"/>
<link href="/css/demo.min.css?1685973381" rel="stylesheet"/>
<style>
@import url('https://rsms.me/inter/inter.css');
:root {
--tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
}
body {
font-feature-settings: "cv03", "cv04", "cv11";
}
</style>
</head>
<body >
<script src="/js/demo-theme.min.js?1685973381"></script>
<div class="page">
<%- include('../partials/navbar.ejs') %>
<div class="page-wrapper">
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<h2 class="page-title">
Users
</h2>
</div>
</div>
</div>
</div>
<div class="page-body">
<div class="container-xl">
<div class="row row-cards">
<div class="col-12">
<div class="card">
<div class="table-responsive">
<table class="table table-vcenter table-mobile-md card-table">
<tbody>
<%- user_list %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<%- include('../partials/footer.ejs') %>
</div>
</div>
<!-- Libs JS -->
<!-- Tabler Core -->
<script src="/js/tabler.min.js?1685973381" defer></script>
<script src="/js/demo.min.js?1685973381" defer></script>
</body>
</html>

View file

@ -184,6 +184,42 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from https://tabler-icons.io/i/user -->
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-augmented-reality" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 8v-2a2 2 0 0 1 2 -2h2" /><path d="M4 16v2a2 2 0 0 0 2 2h2" /><path d="M16 4h2a2 2 0 0 1 2 2v2" /><path d="M16 20h2a2 2 0 0 0 2 -2v-2" /><path d="M12 12.5l4 -2.5" /><path d="M8 10l4 2.5v4.5l4 -2.5v-4.5l-4 -2.5z" /><path d="M8 10v4.5l4 2.5" /></svg>
</span>
<span class="nav-link-title">
Images
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span
class="nav-link-icon d-md-none d-lg-inline-block">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-database" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 6m-8 0a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"></path> <path d="M4 6v6a8 3 0 0 0 16 0v-6"></path> <path d="M4 12v6a8 3 0 0 0 16 0v-6"></path></svg>
</span>
<span class="nav-link-title">
Volumes
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from https://tabler-icons.io/i/user -->
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-world" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" /><path d="M3.6 9h16.8" /><path d="M3.6 15h16.8" /><path d="M11.5 3a17 17 0 0 0 0 18" /><path d="M12.5 3a17 17 0 0 1 0 18" /></svg>
</span>
<span class="nav-link-title">
Networks
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/apps">
<span
@ -208,43 +244,6 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from https://tabler-icons.io/i/user -->
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-world" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" /><path d="M3.6 9h16.8" /><path d="M3.6 15h16.8" /><path d="M11.5 3a17 17 0 0 0 0 18" /><path d="M12.5 3a17 17 0 0 1 0 18" /></svg>
</span>
<span class="nav-link-title">
Networks
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from https://tabler-icons.io/i/user -->
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-augmented-reality" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 8v-2a2 2 0 0 1 2 -2h2" /><path d="M4 16v2a2 2 0 0 0 2 2h2" /><path d="M16 4h2a2 2 0 0 1 2 2v2" /><path d="M16 20h2a2 2 0 0 0 2 -2v-2" /><path d="M12 12.5l4 -2.5" /><path d="M8 10l4 2.5v4.5l4 -2.5v-4.5l-4 -2.5z" /><path d="M8 10v4.5l4 2.5" /></svg>
</span>
<span class="nav-link-title">
Images
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span
class="nav-link-icon d-md-none d-lg-inline-block">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-database" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 6m-8 0a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"></path> <path d="M4 6v6a8 3 0 0 0 16 0v-6"></path> <path d="M4 12v6a8 3 0 0 0 16 0v-6"></path></svg>
</span>
<span class="nav-link-title">
Volumes
</span>
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#navbar-help" data-bs-toggle="dropdown"