From 37f134fd138f03c9f09ae1f65d3fbdd96396dd32 Mon Sep 17 00:00:00 2001 From: Jean Jacques Avril Date: Tue, 15 Mar 2022 21:13:40 +0100 Subject: [PATCH] Added: Errormessage for users incl. hints, reading of of current rfid into user-editor --- src/api/index.js | 40 ++++++++++++++++------- src/components/controls/input.jsx | 4 +-- src/components/index.js | 4 +-- src/components/warnbox/index.jsx | 15 +++++++++ src/route/edituser/index.js | 54 +++++++++++++++++++++++++------ src/route/login/index.jsx | 24 ++++++++------ src/style/_button.sass | 12 +++++-- src/style/_input.sass | 10 ++++-- src/style/_warnbox.sass | 31 ++++++++++++++++++ src/style/style.sass | 1 + 10 files changed, 156 insertions(+), 39 deletions(-) create mode 100644 src/components/warnbox/index.jsx create mode 100644 src/style/_warnbox.sass diff --git a/src/api/index.js b/src/api/index.js index 41ad9d3..896f758 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -1,16 +1,15 @@ const server = 'http://192.168.4.22' - -async function restoreSession(reducer=null) { +async function restoreSession(reducer = null) { let token = localStorage.getItem('token'); let username = localStorage.getItem('username'); - console.log({type:'start', token, username}); - let active = token!==null && username!==null && await checkAuth(token); - if(active&&reducer!==null){ - reducer({type:'start', token, username}); - console.log({type:'start', token, username}); + console.log({ type: 'start', token, username }); + let active = token !== null && username !== null && await checkAuth(token); + if (active && reducer !== null) { + reducer({ type: 'start', token, username }); + console.log({ type: 'start', token, username }); } - return (active ? { active: true, token, username } : {active:false}); + return (active ? { active: true, token, username } : { active: false }); } async function storeSession(username, token) { token = await token; @@ -24,7 +23,19 @@ async function login(username, password) { formData.append('username', username) formData.append('password', password); formData.append('action', 'login'); - const resp = fetch(`${server}/api/auth`, { method: 'POST', mode: 'cors', body: formData }).then(resp => storeSession(username, resp.text())); + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), 1500); + const resp = fetch(`${server}/api/auth`, { signal: controller.signal, method: 'POST', mode: 'cors', body: formData }) + .then(resp => { + if (resp.ok) return storeSession(username, resp.text()) + else if(resp.status===401) return 'login_failed'; + else throw new Error(resp.error); + }) + .catch((error) => { + console.log('Error is:', error); + return 'network_error'; + }) + ; return resp; } async function logout(token) { @@ -87,8 +98,13 @@ function parsedb(raw) { users.push({ line, uid, first_name, last_name, rfid_uid, user_pin, enabled: enabled[0] === '1' }); }); return users; - } -const publicfunctions = { login, logout, checkAuth, parsedb, fetchdb, createCsvTable, updateUser, deleteUser, createUser,restoreSession }; + +async function catchRFID(token){ + const resp = await fetch(`${server}/api/rfid`, { method: 'GET', mode: 'cors', headers: { Authentification: token } }) + .then(resp => resp.json()); + return resp; +} +const publicfunctions = { login, logout, checkAuth, parsedb, fetchdb, createCsvTable, updateUser, deleteUser, createUser, restoreSession, catchRFID }; export default { ...publicfunctions } -export { login, logout, checkAuth, parsedb, fetchdb, createCsvTable, updateUser, deleteUser, createUser, restoreSession } \ No newline at end of file +export { login, logout, checkAuth, parsedb, fetchdb, createCsvTable, updateUser, deleteUser, createUser, restoreSession, catchRFID } \ No newline at end of file diff --git a/src/components/controls/input.jsx b/src/components/controls/input.jsx index 75045b5..4172d60 100644 --- a/src/components/controls/input.jsx +++ b/src/components/controls/input.jsx @@ -1,9 +1,9 @@ import { h } from 'preact' -function TextBox({ id, type = 'text', label, disabled, formdata, formchange, maxlength }) { +function TextBox({ id, type = 'text', label, disabled, formdata, formchange, maxlength, overridevalue }) { let onChange = (e) => formchange({ ...formdata, [e.target.id]: e.target.value }); return (
- +
) } diff --git a/src/components/index.js b/src/components/index.js index 6eb97cc..752fd77 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -4,6 +4,6 @@ import Pageselector from "./Pageselector"; import Header from "./header"; import UserList from "./userlist"; import Menu from "./menu"; - -export {App, Breadcrumbs, Pageselector, Header, UserList, Menu} +import Warnbox from "./warnbox"; +export {App, Breadcrumbs, Pageselector, Header, UserList, Menu, Warnbox} export default App \ No newline at end of file diff --git a/src/components/warnbox/index.jsx b/src/components/warnbox/index.jsx new file mode 100644 index 0000000..dc89ac9 --- /dev/null +++ b/src/components/warnbox/index.jsx @@ -0,0 +1,15 @@ +function Warnbox({ title = "Fehler", children }) { + return (
+ + + +
+

{title}

+ {children && {children}} +
+ +
) +} + + +export default Warnbox \ No newline at end of file diff --git a/src/route/edituser/index.js b/src/route/edituser/index.js index 7b39acd..6aa77ba 100644 --- a/src/route/edituser/index.js +++ b/src/route/edituser/index.js @@ -1,5 +1,5 @@ import { h } from 'preact'; -import { useContext, useEffect, useState } from 'preact/hooks'; +import { useContext, useEffect, useState, useCallback } from 'preact/hooks'; import { route } from 'preact-router'; import AppState, { UserTable } from "../../store"; import api from '../../api' @@ -8,12 +8,28 @@ import { CheckBox, Button, TextBox } from '../../components/controls'; function EditUser({ userid }) { let [sessiondata,] = useContext(AppState).session; const { usertable, userreducer } = useContext(UserTable); - const [formdata, formchange] = useState({}); + const [rfidscan, setscan] = useState({active:false, rfidscaninterval:null}); + let rfidscaninterval = null; let maxlength_uid = 10; let maxlength_name = 25; let maxlength_pin = 10; let maxlength_rfid = 8; + useEffect(() => { + if (rfidscan.rfidscaninterval === null && rfidscan.active) { + rfidscan.rfidscaninterval = setInterval(() => { + api.catchRFID(sessiondata.token).then(result => { + if (result.rfid_uid) { + formchange(old => ({ ...old, rfid_uid: result.rfid_uid })) + setscan(p => ({...p,active:false})) + } + }).catch(() => { setscan(p => ({...p,active:false})) }); + }, 1000); + } else if (rfidscan.rfidscaninterval !== null && !rfidscan.active) { + clearInterval(rfidscan.rfidscaninterval); + setscan(p => ({...p,rfidscaninterval:null})); + } + }, [rfidscan]); useEffect(() => { let user = userid !== undefined ? usertable.find(u => u.uid === userid) : undefined; if (user !== undefined) { @@ -28,6 +44,16 @@ function EditUser({ userid }) { let user = userid !== undefined ? usertable.find(u => u.uid === userid) : undefined; formchange(user !== undefined ? user : {}); } + + const runScan = (e) => { + e.preventDefault(); + setscan(p => ({...p,active:!p.active})); + } + + + + + const onSubmit = (e) => { e.preventDefault(); let idcount = uidCount(usertable, formdata); @@ -49,7 +75,7 @@ function EditUser({ userid }) { } return (
- +

{formdata.line != undefined ? "Benutzer Bearbeiten" : "Neuer Benutzer"}

@@ -57,7 +83,7 @@ function EditUser({ userid }) {
- { {formdata["uid"]?formdata["uid"].length:0} von {maxlength_uid} Zeichen verwendet.} + { {formdata["uid"] ? formdata["uid"].length : 0} von {maxlength_uid} Zeichen verwendet.}
Info @@ -69,22 +95,32 @@ function EditUser({ userid }) {
- { {formdata["first_name"] ?formdata["first_name"].length:0} von {maxlength_name} Zeichen verwendet.} + { {formdata["first_name"] ? formdata["first_name"].length : 0} von {maxlength_name} Zeichen verwendet.}
- { {formdata["last_name"]?formdata["last_name"].length:0} von {maxlength_name} Zeichen verwendet.} + { {formdata["last_name"] ? formdata["last_name"].length : 0} von {maxlength_name} Zeichen verwendet.}

Authentifizierung

- - { {formdata["rfid_uid"]?formdata["rfid_uid"].length:0} von {maxlength_rfid} Zeichen verwendet.} + + { {formdata["rfid_uid"] ? formdata["rfid_uid"].length : 0} von {maxlength_rfid} Zeichen verwendet.}
+
+ +
+ +
+
- { {formdata["user_pin"] ?formdata["user_pin"].length:0} von {maxlength_pin} Zeichen verwendet.} + { {formdata["user_pin"] ? formdata["user_pin"].length : 0} von {maxlength_pin} Zeichen verwendet.} +
+
+ Info + Achten Sie darauf, eine PIN
nicht mehrfach zu benutzen.

Status

diff --git a/src/route/login/index.jsx b/src/route/login/index.jsx index 43cff7b..793dcaa 100644 --- a/src/route/login/index.jsx +++ b/src/route/login/index.jsx @@ -2,7 +2,7 @@ import { h } from 'preact'; import { route } from 'preact-router'; import { useContext, useState } from 'preact/hooks'; import AppState from '../../store/AppState'; -import Breadcrumbs from '../../components/breadcrumbs'; +import {Breadcrumbs, Warnbox} from '../../components'; import { CheckBox, Button, TextBox } from '../../components/controls'; import api from '../../api' function Login() { @@ -13,19 +13,23 @@ function Login() { route('/', true); function onSubmit(e) { e.preventDefault(); - api.login(val.username, val.password).then(token => { - if (token != 'failed!') { + api.login(val.username, val.password).then(result => { + if(result == 'login_failed'){ + set(prev=>({ ...prev, error: "login_failed",password: '' })); + } + else if(result=='network_error') + set(prev=>({ ...prev, error: "network_connection" })); + else { + console.log(typeof(result)) let newsession = { type: 'start', username: val.username, - token + token: result } setsession(newsession); + set({ username: '', password: '' }); } - else { - set(prev=>({ ...prev, error: "user" })); - } - set({ username: '', password: '' }); + }) } @@ -35,7 +39,9 @@ function Login() {

Anmeldung

Bitte melden Sie sich mit ihren Nutzerdaten an.

- {val.error !== null && Fehler: Ungültige Anmeldedaten.} + + {val.error ==='login_failed' && Ungültige Anmeldedaten.
Bitte überprüfen Sie den eingebenen Benutzernamen und das Passwort.
} + {val.error ==='network_connection' && Die Kommunikation mit dem Gerät ist zurzeit nicht möglich.
Bitte überprüfen Sie die Netzwerkverbindung.
}
diff --git a/src/style/_button.sass b/src/style/_button.sass index a1ce4ff..0a3633a 100644 --- a/src/style/_button.sass +++ b/src/style/_button.sass @@ -1,19 +1,25 @@ @mixin default z-index: 1 - margin: 1em + margin: 0 padding: 0.5em text-align: center - display: inline-block + display: block + width: auto position: relative color: #333 font-weight: bold text-decoration: none border: solid 1px #999 border-radius: .2rem + min-width: 100% + overflow: hidden + &--disabled + color: #999 + button display: block background: none - width: 100% + min-width: 100% border: none border-radius: none font-size: 2em diff --git a/src/style/_input.sass b/src/style/_input.sass index 69bfde4..5b0c589 100644 --- a/src/style/_input.sass +++ b/src/style/_input.sass @@ -1,9 +1,10 @@ @mixin textfield margin: 0 1em - width: 100% + min-width: 100% position: relative display: block margin: 0 + overflow: hidden background: #fafafa border-radius: .3em border-bottom: 1px solid #ccc @@ -12,7 +13,7 @@ input display: block background: none - width: 100% + min-width: 100% border-radius: none outline: none border: none @@ -23,19 +24,24 @@ position: absolute top: 0.15em left: 0.25em + right: 0 font-size: .7em cursor: text transition: 250ms all + text-overflow: ellipsis &::placeholder color: transparent &:placeholder-shown + label + text-overflow: ellipsis color: grey position: absolute padding: .7em top: 0em left: 0em + right: 0 + bottom: 0 font-size: 1em &__info color: #ccc diff --git a/src/style/_warnbox.sass b/src/style/_warnbox.sass new file mode 100644 index 0000000..97661b9 --- /dev/null +++ b/src/style/_warnbox.sass @@ -0,0 +1,31 @@ +.warnbox + display: flex + flex-direction: row + //flex-wrap: wrap + background: #ffc964 + box-shadow: 0 0 1em #ffc964 + border-radius: .3em + border: 1px solid #fff + align-items: stretch + justify-content: stretch + padding: .3em + &__icon + font-size: 2em + line-height: 0.5em + //width: 2em + border-right: 1px solid #fff + color: #fff + font-weight: bold + text-shadow: 0 0 .2em #fff + padding: .25em + margin: 0 + display: flex + justify-content: center + align-items: center + //align-self: flex-start + h3 + margin: .3em + color: #fff + div span + margin-left: 1em + \ No newline at end of file diff --git a/src/style/style.sass b/src/style/style.sass index fb34afb..138b942 100644 --- a/src/style/style.sass +++ b/src/style/style.sass @@ -6,6 +6,7 @@ @use 'footer' @use 'button' @use 'input' +@import 'warnbox' * //border: 1px dotted red box-sizing: border-box