current state

This commit is contained in:
Leon Meier 2023-05-04 20:21:10 +02:00
parent d1d717a988
commit 95ec75b8d7
20 changed files with 255 additions and 137 deletions

View File

@ -7,7 +7,9 @@
"/darkreader/darkreader.js", "/darkreader/darkreader.js",
"/bootstrap-icons/font/fonts/bootstrap-icons.woff2", "/bootstrap-icons/font/fonts/bootstrap-icons.woff2",
"/bootstrap/dist/css/bootstrap.min.css.map", "/bootstrap/dist/css/bootstrap.min.css.map",
"/@popperjs/core/dist/umd/popper.min.js" "/@popperjs/core/dist/umd/popper.min.js",
"/@popperjs/core/dist/umd/popper.min.js.map",
"/bootstrap/dist/js/bootstrap.bundle.min.js.map"
], ],
"debugMode": false "debugMode": false
} }

View File

@ -0,0 +1,29 @@
<%~ E.includeFile("partials/head.eta.html", {"title": "Dashboard"}) %> <%~ E.includeFile("partials/controls.eta.html", {"active": "AllItems"}) %>
<h1>All items</h1>
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">SKU</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<% it.items.forEach(function(user){ %>
<tr>
<th scope="row"><%= user.id %></th>
<td><%= user.name %></td>
<td><span class="badge text-bg-success"><%= user.status %></span></td>
<td><%= user.SKU %></td>
<td><a href="#" class="btn btn-primary">Edit</a></td>
</tr>
<% }) %>
</tbody>
</table>
</div>
<%~ E.includeFile("partials/controlsFoot.eta.html") %> <%~ E.includeFile("partials/foot.eta.html") %>

View File

@ -0,0 +1,54 @@
<%~ E.includeFile("partials/head.eta.html", {"title": "Dashboard"}) %> <%~ E.includeFile("partials/controls.eta.html", {"active": "Dashboard"}) %>
<h1>Good evening, ${user}</h1>
<div class="container text-center">
<div class="row">
<div class="card col m-2">
<div class="card-body">
<h5 class="card-title">+10</h5>
<p class="card-text">New Stock</p>
</div>
</div>
<div class="card col m-2">
<div class="card-body">
<h5 class="card-title"><%= it.stats.total %></h5>
<p class="card-text">Items in total</p>
</div>
</div>
<div class="card col m-2">
<div class="card-body">
<h5 class="card-title">Everything ok</h5>
<p class="card-text">Instance Status</p>
</div>
</div>
</div>
</div>
<div class="alert alert-light" role="alert">A new version is available. <a href="#" class="alert-link">Click here to update</a></div>
<h2>Recent items</h2>
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">SKU</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<% it.recents.forEach(function(user){ %>
<tr>
<th scope="row"><%= user.id %></th>
<td><%= user.name %></td>
<td><span class="badge text-bg-success"><%= user.status %></span></td>
<td><%= user.SKU %></td>
<td><a href="#" class="btn btn-primary">Edit</a></td>
</tr>
<% }) %>
</tbody>
</table>
</div>
<%~ E.includeFile("partials/controlsFoot.eta.html") %> <%~ E.includeFile("partials/foot.eta.html") %>

View File

@ -1,62 +0,0 @@
<%~ E.includeFile("partials/head.eta.html", {"title": "Bootstrap Demo Page"}) %>
<%~ E.includeFile("partials/controls.eta.html", {"active": "Orders"}) %>
<h1>
Good evening, ${user}
</h1>
<div class="container text-center">
<div class="row">
<div class="card col m-2">
<div class="card-body">
<h5 class="card-title">+10</h5>
<p class="card-text">New Stock</p>
</div>
</div>
<div class="card col m-2">
<div class="card-body">
<h5 class="card-title"><%= it.stats.total %></h5>
<p class="card-text">Items in total</p>
</div>
</div>
<div class="card col m-2">
<div class="card-body">
<h5 class="card-title">Everything ok</h5>
<p class="card-text">Instance Status</p>
</div>
</div>
</div>
</div>
<div class="alert alert-light" role="alert">
A new version is available. <a href="#" class="alert-link">Click here to update</a>
</div>
<h2>Recent items</h2>
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">SKU</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<% it.recents.forEach(function(user){ %>
<tr>
<th scope="row"><%= user.id %></th>
<td><%= user.name %></td>
<td><span class="badge text-bg-success"><%= user.status %></span></td>
<td><%= user.SKU %></td>
<td><a href="#" class="btn btn-primary">Edit</a></td>
</tr>
<% }) %>
</tbody>
</table>
</div>
<%~ E.includeFile("partials/controlsFoot.eta.html") %>
<%~ E.includeFile("partials/foot.eta.html") %>

View File

@ -0,0 +1,8 @@
<%~ E.includeFile("../partials/head.eta.html", {"title": "Error 404"}) %> <%~ E.includeFile("../partials/controls.eta.html", {"active": "error_404"}) %>
<div class="text-center">
<i class="bi bi-bug-fill " style="font-size: 5rem"></i>
<p class="mt-2 mb-0 fs-4">The thing you were looking for cannot be found</p>
</div>
<%~ E.includeFile("../partials/controlsFoot.eta.html") %> <%~ E.includeFile("../partials/foot.eta.html") %>

View File

@ -0,0 +1,15 @@
<%~ E.includeFile("../partials/head.eta.html", {"title": "Error - Database failure"}) %>
<div class="text-center">
<i class="bi bi-database-fill-slash" style="font-size: 5rem"></i>
<p class="mt-2 mb-0">There seems to be an error with the database</p>
<p>
<a class="btn btn-primary" data-bs-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample"> Get the error </a>
</p>
<div class="collapse" id="collapseExample">
<div class="card card-body">
<pre><code><%= error %></code></pre>
</div>
</div>
</div>
<%~ E.includeFile("../partials/foot.eta.html") %>

View File

@ -1,5 +1,5 @@
<%~ E.includeFile("../partials/head.eta.html", {"title": "Bootstrap Demo Page" }) %> <%~ E.includeFile("../partials/head.eta.html", {"title": "Importer - CSV" }) %>
<%~ E.includeFile("../partials/controls.eta.html", {"active": "Orders" }) %> <%~ E.includeFile("../partials/controls.eta.html", {"active": "CSV_import" }) %>
<h1>Import A CSV File</h1> <h1>Import A CSV File</h1>
Upload a CSV file to import into the database. The CSV file must have the following columns: Upload a CSV file to import into the database. The CSV file must have the following columns:

View File

@ -1,6 +0,0 @@
<%~ E.includeFile("partials/head.eta.html", {"title": "Bootstrap Demo Page"}) %>
<%~ E.includeFile("partials/controls.eta.html") %>
<div class="alert alert-primary" role="alert">A simple primary alert—check it out!</div>
<%~ E.includeFile("partials/foot.eta.html") %>

View File

@ -10,57 +10,90 @@
aria-label="Toggle navigation"> aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<input class="form-control form-control-dark w-100 bg-secondary" type="text" placeholder="Search" aria-label="Search" id="SearchBox" /> <input class="form-control form-control-dark w-100 bg-secondary" type="text" placeholder="Search" aria-label="Search" id="SearchBox" />
<div class="autocomplete-items bg-secondary w-75 border-primary me-5 p-2" id="autocomplete-items" style="left: 16.7%">
</div>
<div class="navbar-nav"> <div class="navbar-nav">
<div class="nav-item text-nowrap"> <div class="nav-item text-nowrap">
<a class="nav-link px-3" href="#">Sign out</a> <a class="nav-link px-3" id="logoutButton">Sign out</a>
</div> </div>
</div> </div>
</header> </header>
<div class="toast-container position-fixed bottom-0 end-0 p-3 ">
<div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<small>Just now</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="toastText">
The button you just pressed is very useless.
</div>
</div>
</div>
<script>
let texti = 0;
alltexts = ["Nope, still useless", "Stop pressing me!", "There are NO USERS!", "Please stop.", "PLEASE!"];
const toastLiveExample = document.getElementById('liveToast')
const logoutButton = document.getElementById('logoutButton')
logoutButton.addEventListener('click', () => {
toastFunction();
texti++;
if(texti >= alltexts.length) texti = 0;
})
function toastFunction() {
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastBootstrap.show()
setTimeout(function(){ toastBootstrap.hide(); document.getElementById("toastText").innerHTML = alltexts[texti] }, 3000);
}
</script>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse"> <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
<div class="position-sticky pt-3"> <div class="position-sticky pt-3">
<ul class="nav flex-column"> <ul class="nav flex-column">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" aria-current="page" href="#"> Dashboard </a> <a class="nav-link <%= it.active == 'Dashboard' ? 'active' : ''%>" aria-current="page" href="/"> <i class="bi bi-house"></i> Dashboard </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Orders </a> <a class="nav-link <%= it.active == 'AllItems' ? 'active' : ''%>"" href="/allItems"> <i class="bi bi-list-ul"></i> All Items </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Products </a> <a class="nav-link <%= it.active == 'placeholder' ? 'active' : ''%>"" href="#"> Products </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Customers </a> <a class="nav-link <%= it.active == 'placeholder' ? 'active' : ''%>"" href="#"> Customers </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Reports </a> <a class="nav-link <%= it.active == 'placeholder' ? 'active' : ''%>"" href="#"> Reports </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Integrations </a> <a class="nav-link <%= it.active == 'placeholder' ? 'active' : ''%>"" href="#"> Integrations </a>
</li> </li>
</ul> </ul>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted"> <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Saved reports</span> <span>Importer</span>
<a class="link-secondary" href="#" aria-label="Add a new report"> </a> <a class="link-secondary" href="#" aria-label="Add a new report"> </a>
</h6> </h6>
<ul class="nav flex-column mb-2"> <ul class="nav flex-column mb-2">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Current month </a> <a class="nav-link <%= it.active == 'CSV_import' ? 'active' : ''%>" href="/import/csv"><i class="bi bi-filetype-csv"></i> CSV Import </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#"> Last quarter </a> <a class="nav-link <%= it.active == 'json_import' ? 'active' : ''%>" href="/import/json"> <i class="bi bi-filetype-json"></i>JSON Import </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#"> Social engagement </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#"> Year-end sale </a>
</li> </li>
</ul> </ul>
</div> </div>
</nav> </nav>
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4"> <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4" style="min-height: 100%;">

View File

@ -6,7 +6,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AssetFlow - <%= it.title %></title> <title>AssetFlow - <%= it.title %></title>
<meta name="description" content="A simple HTML5 Template for new projects." />
<meta name="author" content="[Project-Name-Here]" /> <meta name="author" content="[Project-Name-Here]" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />

View File

@ -1,7 +1,7 @@
<%~ E.includeFile("head.eta.html", {"title": "Item Info"}) %> <%~ E.includeFile("partials/head.eta.html", {"title": "Item Info"}) %>
<div class="ui raised very padded text container segment"> <div class="text-center">
<h2 class="ui header"><%= it.name %></h2> <h2><%= it.name %></h2>
<p><strong>Category:</strong> <%= it.category%></p> <p><strong>Category:</strong> <%= it.category%></p>
<p><strong>Amount:</strong> <%= it.Amount %></p> <p><strong>Amount:</strong> <%= it.Amount %></p>
<p><strong>SKU:</strong> <%= it.SKU %></p> <p><strong>SKU:</strong> <%= it.SKU %></p>
@ -9,4 +9,4 @@
</div> </div>
<%~ E.includeFile("foot.eta.html") %> <%~ E.includeFile("partials/foot.eta.html") %>

View File

@ -43,13 +43,19 @@ export const prisma = new PrismaClient({
}); });
export const app = express(); export const app = express();
app.engine("html", eta.renderFile) app.set('x-powered-by', false);
app.set('strict routing', true);
app.engine('html', eta.renderFile);
app.use(fileUpload()); app.use(fileUpload());
// Configure static https://expressjs.com/de/starter/static-files.html // Configure static https://expressjs.com/de/starter/static-files.html
// app.use('/static', express.static('public')); // app.use('/static', express.static('public'));
app.use(express.static(__path + '/static'));
routes(app); app.use(express.static(__path + '/static'));
/* app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
}); */
//routes(app);
app.use(routes);
app.listen(config.global.http_port, config.global.http_listen_address, () => { app.listen(config.global.http_port, config.global.http_listen_address, () => {
log.web.info(`Listening at http://${config.global.http_listen_address}:${config.global.http_port}`); log.web.info(`Listening at http://${config.global.http_listen_address}:${config.global.http_port}`);

View File

@ -0,0 +1,28 @@
import express, { Request, Response } from 'express';
import { prisma, __path } from '../../index.js';
export default (req: Request, res: Response) => {
// TODO: Fix it? Express behaves like fucking shit with routers and /. Do not ask about it or touch it. EVER! (But if you can fix it a PR is welcome!)
if (req.originalUrl !== '/') {
res.status(404).render(__path + '/src/frontend/errors/404.eta.html', { url: req.originalUrl });
} else {
prisma.item
.findMany({
orderBy: {
updatedAt: 'desc'
},
// Limit to 10 items
take: 10
})
.then((items) => {
// Count amount of total items
prisma.item.count().then((count) => {
res.render(__path + '/src/frontend/dashboard.eta.html', { recents: items, stats: { total: count } });
});
})
.catch((err) => {
console.error(err);
res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
});
}
};

View File

@ -1,18 +0,0 @@
import express, { Request, Response } from 'express';
import { prisma, __path } from '../../index.js';
export default (req: Request, res: Response) => {
prisma.item.findMany({
orderBy: {
updatedAt: 'desc'
},
// Limit to 10 items
take: 10
}).then((items) => {
// Count amount of total items
prisma.item.count().then((count) => {
res.render(__path + '/src/frontend/demopage.eta.html', { recents: items, stats: { total: count } });
});
});
// res.render(__path + '/src/frontend/demopage.eta.html');
};

View File

@ -36,8 +36,6 @@ export default (req: Request, res: Response) => {
values.forEach((value) => { values.forEach((value) => {
categories.delete(value.name); categories.delete(value.name);
}); });
// Log categories
log.web.debug(categories);
const categoryPromises: PrismaPromise<Category>[] = []; const categoryPromises: PrismaPromise<Category>[] = [];
categories.forEach((category: string) => { categories.forEach((category: string) => {
@ -71,8 +69,6 @@ export default (req: Request, res: Response) => {
} }
}); });
listOfPromises.push(promise); listOfPromises.push(promise);
} }
Promise.all(listOfPromises).then((values) => { Promise.all(listOfPromises).then((values) => {
console.log(values); console.log(values);

View File

@ -3,16 +3,18 @@ import express from 'express';
// Route imports // Route imports
import skuRoute from './:id.js'; import skuRoute from './:id.js';
import testRoute from './test.js'; import testRoute from './test.js';
import etaTestRoute from './etaTest.js'; import dashboardRoute from './dashboard.js';
import csvImportRoute from './import/csvImport.js'; import csvImportRoute from './import/csvImport.js';
import listAllItems from './listAllItems.js';
// Router base is '/' // Router base is '/'
const Router = express.Router(); const Router = express.Router({ strict: false });
Router.use('/etaTest', etaTestRoute);
Router.use('/:id(\\w{8})', skuRoute);
Router.use('/test', testRoute); Router.use('/test', testRoute);
Router.use('/allItems', listAllItems)
Router.use('/import/csv', csvImportRoute); Router.use('/import/csv', csvImportRoute);
Router.use('/:id(\\w{8})', skuRoute);
Router.use('/', dashboardRoute);
export default Router; export default Router;

View File

@ -0,0 +1,15 @@
import express, { Request, Response } from 'express';
import { prisma, __path } from '../../index.js';
export default (req: Request, res: Response) => {
prisma.item
.findMany({})
.then((items) => {
// Count amount of total items
res.render(__path + '/src/frontend/allItems.eta.html', { items: items });
})
.catch((err) => {
console.error(err);
res.status(500).render(__path + '/src/frontend/errors/dbError.eta.html', { error: err });
});
};

View File

@ -1,4 +1,4 @@
import { Express } from 'express'; import express, { Express } from 'express';
// Route imports // Route imports
import frontend_routes from './frontend/index.js'; import frontend_routes from './frontend/index.js';
@ -6,9 +6,11 @@ import static_routes from './static/index.js';
import api_routes from './api/index.js'; import api_routes from './api/index.js';
import dev_routes from './dev/index.js'; import dev_routes from './dev/index.js';
export default (app: Express) => { const Router = express.Router({ strict: false });
app.use('/', frontend_routes);
app.use('/static', static_routes); Router.use('/static', static_routes);
app.use('/api', api_routes); Router.use('/api', api_routes);
app.use('/dev', dev_routes); // This is just for development. ToDo: Add check if we are in devmode. Router.use('/dev', dev_routes); // This is just for development. ToDo: Add check if we are in devmode.
}; Router.use('/', frontend_routes);
export default Router;

View File

@ -2,12 +2,6 @@ body {
font-size: 0.875rem; font-size: 0.875rem;
} }
.feather {
width: 16px;
height: 16px;
vertical-align: text-bottom;
}
/* /*
* Sidebar * Sidebar
*/ */
@ -98,3 +92,11 @@ body {
border-color: transparent; border-color: transparent;
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
} }
.autocomplete-items {
position: absolute;
z-index: 99;
top: 100%;
left: 0;
right: 0;
}

View File

@ -1,11 +1,24 @@
document.getElementById("SearchBox").addEventListener("keyup", handleSearchChange); document.getElementById("SearchBox").addEventListener("keyup", handleSearchChange);
const autocompleteBox = document.getElementById("autocomplete-items");
autocompleteBox.style.display = "none";
function handleSearchChange(e) { function handleSearchChange(e) {
console.log(e.target.value); console.log(e.target.value);
// Check if known prefix is used (either > or #) // Check if known prefix is used (either > or #)
if(e.target.value != "" ) {
autocompleteBox.style.display = "block";
autocompleteBox.innerHTML = "Search results will show up here soon <br> Trust me <br> Results";
} else {
autocompleteBox.style.display = "none";
}
if (e.target.value[0] == ">") { if (e.target.value[0] == ">") {
// Search for commands autocompleteBox.innerHTML = "Start typing to search for commands <br> >goto items";
if(e.target.value == ">goto items") {
autocompleteBox.innerHTML = "<a href='/allItems'>Goto Items</a>";
}
} else if (e.target.value[0] == "#") { } else if (e.target.value[0] == "#") {
// Search for SKU // Search for SKU
autocompleteBox.innerHTML = "Start typing to search for items by SKU";
} else { } else {
// Search for name // Search for name
} }