Frontend stuff
This commit is contained in:
parent
611a4a0ead
commit
45cd5b10e6
@ -1,25 +1,19 @@
|
||||
import express from 'express';
|
||||
import config from '../../handlers/config.js';
|
||||
|
||||
// Route imports
|
||||
import dashboardRoute from './dashboard.js';
|
||||
import testRoute from './test.js';
|
||||
import contactRoute from './contact.js';
|
||||
// import itemsRoute from './items.js';
|
||||
// import manage_routes from './manage/index.js';
|
||||
import screensaver_Route from './screensaver.js';
|
||||
import user_select_Route from './user_select.js';
|
||||
import product_select_Route from './product_select.js';
|
||||
import test_Route from './test.js';
|
||||
|
||||
// Router base is '/'
|
||||
const Router = express.Router({ strict: false });
|
||||
|
||||
// Router.route('/test').get(testRoute.get);
|
||||
// Router.route('/items').get(itemsRoute.get);
|
||||
Router.route('/').get(screensaver_Route.get);
|
||||
Router.route('/user_select').get(user_select_Route.get);
|
||||
Router.route('/product_select').get(product_select_Route.get);
|
||||
|
||||
// Router.route('/:id(\\w{8})').get(skuRoute.get);
|
||||
// Router.route('/s/:id').get(skuRouteDash.get);
|
||||
|
||||
// Router.use('/manage', manage_routes);
|
||||
|
||||
Router.route('/').get(dashboardRoute.get);
|
||||
Router.route('/dbTest').get(testRoute.get);
|
||||
Router.route('/contact').get(contactRoute.get);
|
||||
config.global.devmode && Router.route('/test').get(test_Route.get);
|
||||
|
||||
export default Router;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
|
||||
function get(req: Request, res: Response) {
|
||||
res.render("lockscreen", { message: "Hello world from eta!" })
|
||||
res.render("product_select")
|
||||
}
|
||||
|
||||
export default { get };
|
@ -1,7 +1,7 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
|
||||
function get(req: Request, res: Response) {
|
||||
res.render("contacts")
|
||||
res.render("screensaver")
|
||||
}
|
||||
|
||||
export default { get };
|
7
src/routes/frontend/user_select.ts
Normal file
7
src/routes/frontend/user_select.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
|
||||
function get(req: Request, res: Response) {
|
||||
res.render("user_select")
|
||||
}
|
||||
|
||||
export default { get };
|
@ -32,6 +32,9 @@ let _api = {
|
||||
if (typeof result === 'number') {
|
||||
return result;
|
||||
}
|
||||
if (typeof result === 'boolean') {
|
||||
return result;
|
||||
}
|
||||
console.error('Invalid JSON response');
|
||||
_testPageFail('Invalid JSON response');
|
||||
return;
|
||||
|
@ -1,3 +1,7 @@
|
||||
body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
hidden {
|
||||
display: none;
|
||||
}
|
@ -618,3 +618,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
(document.querySelectorAll('.notification .delete') || []).forEach(($delete) => {
|
||||
const $notification = $delete.parentNode;
|
||||
|
||||
$delete.addEventListener('click', () => {
|
||||
$notification.parentNode.removeChild($notification);
|
||||
});
|
||||
});
|
||||
});
|
17
static/pages/product_select.js
Normal file
17
static/pages/product_select.js
Normal file
@ -0,0 +1,17 @@
|
||||
console.log('product_select.js loaded');
|
||||
|
||||
// Get containers
|
||||
let mainSelectionDiv = document.getElementById('mainSelect');
|
||||
|
||||
const baseStruct = document.getElementById("baseStruct");
|
||||
|
||||
let globalData;
|
||||
|
||||
// On load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
let data = await returnTableDataByTableName('product');
|
||||
console.info(`Found ${data.count} products`);
|
||||
const result = data.result;
|
||||
globalData = result;
|
||||
|
||||
});
|
134
static/pages/user_select.js
Normal file
134
static/pages/user_select.js
Normal file
@ -0,0 +1,134 @@
|
||||
console.log('user_select.js loaded');
|
||||
|
||||
// Get containers
|
||||
let mainSelectionDiv = document.getElementById('mainSelect');
|
||||
let pinPadModal = document.getElementById('pinPadModal');
|
||||
let numpad = document.getElementById('numpad');
|
||||
|
||||
let pinInput1 = document.getElementById('pinInput1');
|
||||
let pinInput2 = document.getElementById('pinInput2');
|
||||
let pinInput3 = document.getElementById('pinInput3');
|
||||
let pinInput4 = document.getElementById('pinInput4');
|
||||
|
||||
let pinError = document.getElementById('pinError');
|
||||
|
||||
let currentUser = null;
|
||||
|
||||
// Attach event listeners to all numpad buttons
|
||||
let numpadButtons = numpad.getElementsByTagName('button');
|
||||
for(let i = 0; i < numpadButtons.length; i++) {
|
||||
let button = numpadButtons[i];
|
||||
button.addEventListener('click', handleNumberClick);
|
||||
}
|
||||
|
||||
// On keyboard input for pinInputX jump to next input field
|
||||
pinInput1.addEventListener('input', function() {
|
||||
if(pinInput1.value) {
|
||||
pinInput2.focus();
|
||||
// Update pinValue
|
||||
pinValue = pinInput1.value;
|
||||
}
|
||||
});
|
||||
pinInput2.addEventListener('input', function() {
|
||||
if(pinInput2.value) {
|
||||
pinInput3.focus();
|
||||
pinValue = pinInput1.value + pinInput2.value;
|
||||
}
|
||||
}
|
||||
);
|
||||
pinInput3.addEventListener('input', function() {
|
||||
if(pinInput3.value) {
|
||||
pinInput4.focus();
|
||||
pinValue = pinInput1.value + pinInput2.value + pinInput3.value;
|
||||
}
|
||||
});
|
||||
|
||||
pinInput4.addEventListener('input', function() {
|
||||
if(pinInput4.value) {
|
||||
pinValue = pinInput1.value + pinInput2.value + pinInput3.value + pinInput4.value;
|
||||
validatePin();
|
||||
}
|
||||
});
|
||||
|
||||
let baseStruct = document.getElementById("baseStruct");
|
||||
|
||||
let globalData;
|
||||
|
||||
let pinValue = "";
|
||||
|
||||
// On load
|
||||
document.addEventListener('DOMContentLoaded', async function() {
|
||||
let data = await returnTableDataByTableName('user');
|
||||
console.info(`Found ${data.count} users`);
|
||||
const result = data.result;
|
||||
globalData = result;
|
||||
|
||||
for(let i = 0; i < result.length; i++) {
|
||||
let user = result[i];
|
||||
let userDiv = baseStruct.cloneNode(true);
|
||||
userDiv.id = `user_${user.id}`;
|
||||
userDiv.innerHTML = user.name;
|
||||
userDiv.addEventListener('click', handleUserClick);
|
||||
|
||||
mainSelectionDiv.appendChild(userDiv);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handleUserClick(e) {
|
||||
let userDiv = e.target;
|
||||
let userId = userDiv.id.split('_')[1];
|
||||
console.log(`Clicked on user with id ${userId}`);
|
||||
let user = globalData.find(u => u.id == userId);
|
||||
currentUser = user;
|
||||
if(user.code) {
|
||||
pinPadModal.classList.add('is-active');
|
||||
// Automatically focus on the first input field
|
||||
pinInput1.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function validatePin() {
|
||||
let pin = pinValue;
|
||||
let userId = currentUser.id;
|
||||
console.log(`Validating pin ${pinValue} for user ${userId}`);
|
||||
_api.get("/user/codecheck?code=" + pinValue + "&id=" + userId).then((response) => {
|
||||
if(response) {
|
||||
console.log("Pin is correct");
|
||||
pinPadModal.classList.remove('is-active');
|
||||
window.location.href = `/product_select?user=${userId}`;
|
||||
} else {
|
||||
console.log("Pin is incorrect");
|
||||
pinValue = "";
|
||||
updatePinFields();
|
||||
pinError.classList.remove('is-hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleNumberClick(e) {
|
||||
let number = e.target.innerHTML;
|
||||
if(number == '<i class="bi bi-backspace-fill"></i>' || e.target.classList.contains('bi-backspace-fill')) {
|
||||
pinValue = pinValue.slice(0, -1);
|
||||
updatePinFields();
|
||||
return;
|
||||
}
|
||||
if(number == '<i class="bi bi-check"></i>' || e.target.classList.contains('bi-check')) {
|
||||
validatePin();
|
||||
return;
|
||||
}
|
||||
if(pinValue.length >= 4) {
|
||||
return;
|
||||
}
|
||||
pinValue += number;
|
||||
updatePinFields();
|
||||
}
|
||||
|
||||
function updatePinFields() {
|
||||
let pin = pinValue;
|
||||
pinInput1.value = pin[0] || "";
|
||||
pinInput2.value = pin[1] || "";
|
||||
pinInput3.value = pin[2] || "";
|
||||
pinInput4.value = pin[3] || "";
|
||||
}
|
||||
|
@ -1,119 +0,0 @@
|
||||
<%~ include("partials/base_head.eta", {"title": "Kontakte"}) %>
|
||||
<%~ include("partials/nav.eta") %>
|
||||
|
||||
<section class="hero is-primary" id="heroStatus">
|
||||
<div class="hero-body">
|
||||
<p class="title" data-tK="start-hero-header-welcome">Kontaktverwaltung</p>
|
||||
<p class="subtitle" data-tK="start-hero-header-subtitle-default" id="heroExplainer">Erklärungstext</p>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section">
|
||||
<nav class="level">
|
||||
<div class="level-item has-text-centered">
|
||||
<div>
|
||||
<p class="heading">Kontakte</p>
|
||||
<p class="title"><span data-dataSource="AlertContacts" data-dataAction="COUNT" class="is-skeleton">Load.</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item has-text-centered">
|
||||
<div>
|
||||
<p class="heading"><button class="js-modal-trigger button" data-target="modal-js-example">
|
||||
Neuen Konakt anlegen
|
||||
</button></p>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
|
||||
<!-- TODO: Mark required fields as required; add handling for validation -->
|
||||
<div id="modal-js-example" class="modal">
|
||||
<div class="modal-background"></div>
|
||||
|
||||
<div class="modal-content">
|
||||
<div class="box entryPhase is-hidden">
|
||||
<h2 class="title">Neuer Kontakt</h1>
|
||||
|
||||
<i class="bi bi-arrow-clockwise title"></i>
|
||||
</div>
|
||||
<div class="box entryPhase">
|
||||
|
||||
<form data-targetTable="AlertContacts">
|
||||
<h2 class="title">Neuer Kontakt</h1>
|
||||
<div class="field">
|
||||
<label class="label">Name</label>
|
||||
<div class="control has-icons-left">
|
||||
<input class="input" type="text" placeholder="John Doe" value="" name="name">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="bi bi-file-earmark-person-fill"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Telefonummer</label>
|
||||
<div class="control has-icons-left">
|
||||
<input class="input" type="text" placeholder="+49 1234 5678912" value="" name="phone">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="bi bi-telephone-fill"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Anmerkung</label>
|
||||
<div class="control has-icons-left">
|
||||
<input class="input" type="text" placeholder="" value="" name="comment">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="bi bi-chat-fill"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<input type="submit" class="button is-link" value="Save" data-actionBtn="save">
|
||||
</div>
|
||||
<!--<div class="control">
|
||||
<button type="button" class="button is-link is-light" data-actionBtn="cancel">Cancel</button>
|
||||
</div>-->
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="modal-close is-large" aria-label="close"></button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<section class="section">
|
||||
<h1 class="title" data-tK="start-recent-header">Kontaktübersicht</h1>
|
||||
<input class="input" type="text" data-searchTargetId="contactTable" placeholder="Search..." />
|
||||
<table class="table is-striped is-fullwidth is-hoverable" data-dataSource="AlertContacts" id="contactTable" data-pageSize="5">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-dataCol = "id"><abbr title="Position">Pos</abbr></th>
|
||||
<th data-dataCol = "name">Name</th>
|
||||
<th data-dataCol = "phone">Telefonnummer</th>
|
||||
<th data-dataCol = "comment">Kommentar</th>
|
||||
<th data-fnc="actions" data-actions="edit,delete">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
<nav class="pagination is-hidden" role="navigation" aria-label="pagination" data-targetTable="contactTable">
|
||||
<ul class="pagination-list">
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<%~ include("partials/footer.eta") %>
|
||||
<%~ include("partials/base_foot.eta") %>
|
@ -1,5 +1,5 @@
|
||||
<%~ include("partials/base_head.eta", {"title": "Dashboard"}) %>
|
||||
<%~ include("partials/nav.eta") %>
|
||||
<!--<%~ include("partials/nav.eta") %>-->
|
||||
|
||||
<section class="hero is-primary">
|
||||
<div class="hero-body">
|
||||
|
@ -1,4 +1,2 @@
|
||||
<script src="/static/apiWrapper.js"></script>
|
||||
<script src="/static/pageDriver.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,3 +7,5 @@
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="/static/apiWrapper.js"></script>
|
||||
<script src="/static/pageDriver.js"></script>
|
@ -18,9 +18,11 @@
|
||||
|
||||
<div id="navbarBasicExample" class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
<a class="navbar-item" href="/">Home</a>
|
||||
<a class="navbar-item" href="/dbTest">API Integration <span class="tag is-info">Dev</span></a>
|
||||
<a class="navbar-item" href="/contact">Kontakte <span class="tag is-primary">Neu!</span></a>
|
||||
<a class="navbar-item" href="/">Screensaver</a>
|
||||
<a class="navbar-item" href="/user_select">user_select</a>
|
||||
<a class="navbar-item" href="/product_select">product_select</a>
|
||||
<a class="navbar-item" href="/test">Test <span class="tag is-info">Dev</span></a>
|
||||
|
||||
<!--<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="navbar-link">More</a>
|
||||
<div class="navbar-dropdown">
|
||||
|
38
views/product_select.eta
Normal file
38
views/product_select.eta
Normal file
@ -0,0 +1,38 @@
|
||||
<%~ include("partials/base_head.eta", {"title": "Dashboard"}) %>
|
||||
<%~ include("partials/nav.eta") %>
|
||||
|
||||
<section class="section">
|
||||
<div class="container columns" id="mainSelect">
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hidden>
|
||||
<!-- Base Button -->
|
||||
<div class="column" id="baseStruct">
|
||||
<div class="card" >
|
||||
<div class="card-image">
|
||||
<figure class="image is-4by3">
|
||||
<img
|
||||
src="https://bulma.io/assets/images/placeholders/1280x960.png"
|
||||
alt="Placeholder image"
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="title is-4">CocaCola lol</p>
|
||||
<p class="subtitle is-6">0123456789</p>
|
||||
|
||||
</div>
|
||||
<footer class="card-footer">
|
||||
<p class="card-footer-item">
|
||||
<span> 9.99€ </span>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</hidden>
|
||||
|
||||
<%~ include("partials/footer.eta") %>
|
||||
<script src="/static/pages/product_select.js"></script>
|
||||
<%~ include("partials/base_foot.eta") %>
|
97
views/user_select.eta
Normal file
97
views/user_select.eta
Normal file
@ -0,0 +1,97 @@
|
||||
<%~ include("partials/base_head.eta", {"title": "Dashboard"}) %>
|
||||
<%~ include("partials/nav.eta") %>
|
||||
|
||||
<section class="section buttons container" id="mainSelect">
|
||||
|
||||
</section>
|
||||
<hidden>
|
||||
<!-- Base Button -->
|
||||
<button class="button is-link is-large m-2" id="baseStruct">Username</button>
|
||||
</hidden>
|
||||
<div class="modal" id="pinPadModal">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Bitte PIN eingeben</p>
|
||||
<div class="notification is-danger is-hidden" id="pinError">
|
||||
<button class="delete"></button>
|
||||
Ein fehlerhafter PIN wurde eingegeben.
|
||||
</div>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<!--
|
||||
<input class="input" type="password" placeholder="1234" id="pinInput" maxlength="4" />
|
||||
-->
|
||||
|
||||
<!-- Use 4 fields for the pin, similar to a 2FA fields -->
|
||||
<div class="field has-addons is-centered">
|
||||
<div class="control">
|
||||
<input class="input is-large has-text-centered" type="password" placeholder="1" id="pinInput1" maxlength="1" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<input class="input is-large has-text-centered" type="password" placeholder="2" id="pinInput2" maxlength="1" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<input class="input is-large has-text-centered" type="password" placeholder="3" id="pinInput3" maxlength="1" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<input class="input is-large has-text-centered" type="password" placeholder="4" id="pinInput4" maxlength="1" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section buttons container is-centered are-centered" id="numpad">
|
||||
<!-- Num pad with 3 keys per row -->
|
||||
<div class="columns is-grouped">
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">1</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">2</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">3</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-grouped">
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">4</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">5</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">6</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-grouped">
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">7</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">8</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">9</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-grouped">
|
||||
<div class="column">
|
||||
<button class="button is-link is-large m-2">0</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-warning is-large m-2"><i class="bi bi-backspace-fill"></i></button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="button is-success is-large m-2"><i class="bi bi-check"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<button class="modal-close is-large" aria-label="close"></button>
|
||||
</div>
|
||||
|
||||
<%~ include("partials/footer.eta") %>
|
||||
<script src="/static/pages/user_select.js"></script>
|
||||
<%~ include("partials/base_foot.eta") %>
|
Loading…
x
Reference in New Issue
Block a user