Compare commits
3 Commits
9066397cd4
...
475690ca2b
Author | SHA1 | Date | |
---|---|---|---|
475690ca2b | |||
03fec1ebd7 | |||
8cd011fc01 |
@ -164,7 +164,7 @@ async function patch(req: Request, res: Response) {
|
||||
data: {
|
||||
userId: value.user_id,
|
||||
paid: value.paid,
|
||||
// !!!!! paidAt: value.paid ? new Date() : undefined
|
||||
paidAt: value.paid ? new Date() : undefined
|
||||
},
|
||||
select: {
|
||||
id: true
|
||||
|
@ -4,6 +4,7 @@ import express from 'express';
|
||||
import dashboard_Route from './dashboard.js';
|
||||
import users from './users.js';
|
||||
import products from './products.js';
|
||||
import report from './report.js';
|
||||
|
||||
// Router base is '/admin'
|
||||
const Router = express.Router({ strict: false });
|
||||
@ -11,6 +12,7 @@ const Router = express.Router({ strict: false });
|
||||
Router.route('/').get(dashboard_Route.get);
|
||||
Router.route('/users').get(users.get);
|
||||
Router.route('/products').get(products.get);
|
||||
Router.route('/report').get(report.get);
|
||||
// Router.route('/user_select').get(user_select_Route.get);
|
||||
// Router.route('/product_select').get(product_select_Route.get);
|
||||
// Router.route('/pay_up').get(pay_up_Route.get);
|
||||
|
7
src/routes/frontend/admin/report.ts
Normal file
7
src/routes/frontend/admin/report.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
|
||||
function get(req: Request, res: Response) {
|
||||
res.render("admin/reports")
|
||||
}
|
||||
|
||||
export default { get };
|
@ -172,7 +172,7 @@ function getApiDescriptionByTable(tableName) {
|
||||
}
|
||||
}
|
||||
|
||||
function returnTableDataByTableName(tableName, search="", orderBy="asc", sort="", take=-1, skip=0) {
|
||||
function returnTableDataByTableName(tableName, search="", orderBy="asc", sort="", take=-1, skip=0, filters=[]) {
|
||||
var orderBy = orderBy.toLowerCase();
|
||||
if(orderBy == "") {
|
||||
orderBy = "asc";
|
||||
@ -187,6 +187,10 @@ function returnTableDataByTableName(tableName, search="", orderBy="asc", sort=""
|
||||
if(skip > 0) {
|
||||
baseString += "&skip=" + skip;
|
||||
}
|
||||
filterKeys = Object.keys(filters);
|
||||
for(var i = 0; i < filterKeys.length; i++) {
|
||||
baseString += "&" + filterKeys[i] + "=" + filters[filterKeys[i]];
|
||||
}
|
||||
|
||||
if (search && search.length > 0) {
|
||||
return _api.get(baseString + '&search=' + search);
|
||||
@ -214,6 +218,7 @@ async function getCountByTable(tableName, search="") {
|
||||
|
||||
|
||||
function _testPageFail(reason) {
|
||||
return;
|
||||
document.getElementById('heroStatus').classList.remove('is-success');
|
||||
document.getElementById('heroStatus').classList.add('is-danger');
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 637 KiB After Width: | Height: | Size: 1.5 MiB |
@ -74,6 +74,9 @@ tables.forEach(async (table) => {
|
||||
refreshTable(table);
|
||||
});
|
||||
});
|
||||
if(table.getAttribute("data-loadmode") == "manual") {
|
||||
return;
|
||||
}
|
||||
refreshTable(table);
|
||||
|
||||
});
|
||||
@ -289,6 +292,7 @@ async function refreshTable(table) {
|
||||
});
|
||||
let order = '';
|
||||
let column = '';
|
||||
let filters = JSON.parse(table.getAttribute('data-filters')) || {};
|
||||
ths.forEach((th) => {
|
||||
if (th.hasAttribute('data-order')) {
|
||||
order = th.getAttribute('data-order');
|
||||
@ -317,7 +321,7 @@ async function refreshTable(table) {
|
||||
if (searchField) {
|
||||
const value = searchField.value;
|
||||
const dbTable = table.getAttribute('data-dataSource');
|
||||
const result = await returnTableDataByTableName(dbTable, value, order, column, take=maxLinesPerPage, skip= start);
|
||||
const result = await returnTableDataByTableName(dbTable, value, order, column, take=maxLinesPerPage, skip=start, filters);
|
||||
const totalResultCount = await getCountByTable(dbTable, value);
|
||||
paginationPassOnPre['dataLength'] = totalResultCount;
|
||||
var magMiddl = managePaginationMiddleware(result, paginationPassOnPre);
|
||||
@ -326,7 +330,7 @@ async function refreshTable(table) {
|
||||
clearTable(table);
|
||||
writeDataToTable(table, data, paginationPassOn);
|
||||
} else {
|
||||
const result = await returnTableDataByTableName(table.getAttribute('data-dataSource'), undefined, order, column, take= maxLinesPerPage, skip= start);
|
||||
const result = await returnTableDataByTableName(table.getAttribute('data-dataSource'), undefined, order, column, take= maxLinesPerPage, skip= start, filters);
|
||||
const resultCount = await getCountByTable(table.getAttribute('data-dataSource'));
|
||||
paginationPassOnPre['dataLength'] = resultCount;
|
||||
var magMiddl = managePaginationMiddleware(result, paginationPassOnPre);
|
||||
@ -511,7 +515,14 @@ function writeDataToTable(table, data, paginationPassOn) {
|
||||
if(header.getAttribute('data-type') == "bool") {
|
||||
td.innerHTML = row[column] ? '<i class="bi bi-check"></i>' : '<i class="bi bi-x"></i>';
|
||||
|
||||
} else {
|
||||
} else if(header.getAttribute('data-type') == "datetime"){
|
||||
if(row[column] == null) {
|
||||
td.innerHTML = "";
|
||||
} else {
|
||||
td.innerHTML = formatTimestamp(row[column]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
td.innerHTML = row[column];
|
||||
}
|
||||
tr.appendChild(td);
|
||||
|
@ -125,7 +125,7 @@ scannerField.addEventListener('keydown', async function(event) {
|
||||
console.log('Barcode scanned:', barcode);
|
||||
scannerField.value = "";
|
||||
// createTemporaryNotification(`Barcode ${barcode} gescannt`, 'is-info');
|
||||
|
||||
waitingForScan = false;
|
||||
|
||||
// Check if barcode is in the database
|
||||
let product = globalData.find(p => p.gtin == barcode);
|
||||
@ -144,7 +144,7 @@ scannerField.addEventListener('keydown', async function(event) {
|
||||
form_gtin.value = barcode;
|
||||
}
|
||||
// modal_stage_2_result.innerHTML = product ? `<i class="bi bi-check"></i> Produkt gefunden: ${product.name}` : `<i class="bi bi-x"></i> Produkt nicht gefunden`;
|
||||
waitingForScan = false;
|
||||
|
||||
|
||||
|
||||
// let product = globalData.find(p => p.gtin == barcode);
|
||||
|
@ -11,6 +11,8 @@ const btn_paynow = document.getElementById("paynow");
|
||||
const btn_confirm = document.getElementById("confirmCheckout");
|
||||
const btn_logout = document.getElementById("logout");
|
||||
|
||||
const table_old = document.getElementById("alltransactions");
|
||||
|
||||
errorIfAnyUndefined([isEmptyAlert, tableDiv, payTable, tableCnt, tableSum, modal_sum])
|
||||
|
||||
// Current user
|
||||
@ -20,6 +22,9 @@ if(cookieUser == undefined) {
|
||||
createTemporaryNotification('Fehler: Nutzer nicht angemeldet.', 'is-danger');
|
||||
window.location.href = '/user_select';
|
||||
}
|
||||
table_old.setAttribute('data-filters', `{"user_id": ${cookieUser}}`);
|
||||
refreshTable(table_old);
|
||||
console.log("Table refreshed");
|
||||
|
||||
let transactionIds = [];
|
||||
|
||||
|
@ -216,7 +216,7 @@ scannerField.addEventListener('keydown', async function(event) {
|
||||
let product = globalData.find(p => p.gtin == barcode);
|
||||
if(product) {
|
||||
let event = new Event('click');
|
||||
createTemporaryNotification(`<i class="bi bi-upc-scan"></i> Barcode scan: GTIN ${barcode} gefunden`, 'is-success');
|
||||
createTemporaryNotification(`<i class="bi bi-upc-scan"></i> Barcode scan: GTIN ${barcode} gefunden`, 'is-success', 2000);
|
||||
document.getElementById(`product_${product.id}`).dispatchEvent(event);
|
||||
} else {
|
||||
createTemporaryNotification( `<i class="bi bi-upc-scan"></i> Barcode scan: GTIN ${barcode} nicht gefunden`, 'is-danger');
|
||||
|
@ -13,7 +13,7 @@
|
||||
<a href="/admin/users" class="button is-large is-fullwidth is-primary">Benutzer</a>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<a href="/admin/reports" class="button is-large is-fullwidth is-primary">Berichte</a>
|
||||
<a href="/admin/report" class="button is-large is-fullwidth is-primary">Berichte</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<button class="js-modal-trigger button" data-target="modal-js-example">
|
||||
Neues Produkt anlegen
|
||||
</button><button class="js-modal-trigger button" data-target="modal-restock" id="btn_restock">
|
||||
Lager nachfüllen
|
||||
Lager nachfüllen / Anpassen
|
||||
</button><br></p>
|
||||
|
||||
<input class="input" type="text" data-searchTargetId="productTable" placeholder="Nach Produkt suchen.." />
|
||||
@ -164,6 +164,8 @@
|
||||
<h2 class="title">Scan erfolgreich - Produktmenge eingeben</h1>
|
||||
<h3 class="subtitle" id="stage-2-amount">Aktuelle Menge: 0</h3>
|
||||
<div class="buttons">
|
||||
<button class="button is-info" onclick="restock(-1)">-1</button>
|
||||
<button class="button is-info" onclick="restock(1)">+1</button>
|
||||
<button class="button is-info" onclick="restock(6)">+6</button>
|
||||
<button class="button is-info" onclick="restock(10)">+10</button>
|
||||
<button class="button is-info" onclick="restock(12)">+12</button>
|
||||
|
36
views/admin/reports.eta
Normal file
36
views/admin/reports.eta
Normal file
@ -0,0 +1,36 @@
|
||||
<%~ include("partials/base_head.eta", {"title": "Dashboard"}) %>
|
||||
<%~ include("partials/nav.eta") %>
|
||||
|
||||
<section class="section container" id="mainSelect">
|
||||
<h1 class="title">Berichte</h1>
|
||||
<!-- Big buttons linking to the different admin pages (Produkte, Benutzer, Bericht) -->
|
||||
<nav class="level">
|
||||
<div class="level-item has-text-centered">
|
||||
<div>
|
||||
<p class="heading">Benutzer</p>
|
||||
<p class="title"><span data-dataSource="user" data-dataAction="COUNT" class="is-skeleton">Load.</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item has-text-centered">
|
||||
<div>
|
||||
<p class="heading">Transaktionen</p>
|
||||
<p class="title"><span data-dataSource="transaction" data-dataAction="COUNT" class="is-skeleton">Load.</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="level-item has-text-centered">
|
||||
<div>
|
||||
<p class="heading">Produkte</p>
|
||||
<p class="title"><span data-dataSource="products" data-dataAction="COUNT" class="is-skeleton">Load.</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="columns is-centered">
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<%~ include("partials/footer.eta") %>
|
||||
<!-- <script src="/static/pages/admin_.js"></script>-->
|
||||
<%~ include("partials/base_foot.eta") %>
|
@ -32,6 +32,28 @@
|
||||
|
||||
<button class="button is-success is-large" id="paynow">Jetzt bezahlen <i class="bi bi-wallet2"></i></button>
|
||||
</div>
|
||||
<details>
|
||||
<summary>Alle Transaktionen</summary>
|
||||
<table class="table is-striped is-fullwidth is-hoverable" data-dataSource="transaction" data-pageSize="10" data-filters='{"user_id":-1}' data-loadmode="manual" id="alltransactions">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-dataCol = "id">Id</th>
|
||||
<th data-dataCol = "total">Name</th>
|
||||
<th data-dataCol = "paid" data-type="bool">Bezahlt</th>
|
||||
<th data-dataCol = "createdAt" data-type="datetime">Ausgestellt am</th>
|
||||
<th data-dataCol = "paidAt" data-type="datetime" data-order="DESC">Bezahlt am</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
<nav class="pagination is-hidden" role="navigation" aria-label="pagination" data-targetTable="alltransactions">
|
||||
<ul class="pagination-list">
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
<!-- Confirmation modal -->
|
||||
@ -56,6 +78,9 @@
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<%~ include("partials/footer.eta") %>
|
||||
<script src="/static/pages/payup.js"></script>
|
||||
<%~ include("partials/base_foot.eta") %>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<!-- Empty sidebar on the right -->
|
||||
<div class="column is-one-quarter">
|
||||
<h2 class="title is-4" >Ausgewählte Produkte</h2>
|
||||
<h2 class="title is-4">Ausgewählte Produkte</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
Loading…
x
Reference in New Issue
Block a user