Added: Errormessage for users incl. hints, reading of of current rfid into user-editor
This commit is contained in:
parent
32e6018415
commit
37f134fd13
@ -1,5 +1,4 @@
|
||||
const server = 'http://192.168.4.22'
|
||||
|
||||
async function restoreSession(reducer = null) {
|
||||
|
||||
let token = localStorage.getItem('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 }
|
||||
export { login, logout, checkAuth, parsedb, fetchdb, createCsvTable, updateUser, deleteUser, createUser, restoreSession, catchRFID }
|
@ -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 (<div className={'textbox'} >
|
||||
<input placeholder=" " disabled={disabled} type={type} value={formdata[id]?formdata[id]:''} id={id} onInput={onChange} maxlength={maxlength} name={`form-${id}`} />
|
||||
<input placeholder=" " disabled={disabled} type={type} value={overridevalue?overridevalue:formdata[id]?formdata[id]:''} id={id} onInput={onChange} maxlength={maxlength} name={`form-${id}`} />
|
||||
<label for={id}>{label}</label>
|
||||
</div>)
|
||||
}
|
||||
|
@ -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
|
15
src/components/warnbox/index.jsx
Normal file
15
src/components/warnbox/index.jsx
Normal file
@ -0,0 +1,15 @@
|
||||
function Warnbox({ title = "Fehler", children }) {
|
||||
return (<div className={'warnbox'} >
|
||||
|
||||
<span className='warnbox__icon'>⚠</span>
|
||||
|
||||
<div className="column">
|
||||
<h3>{title}</h3>
|
||||
{children && <span> {children}</span>}
|
||||
</div>
|
||||
|
||||
</div>)
|
||||
}
|
||||
|
||||
|
||||
export default Warnbox
|
@ -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);
|
||||
@ -79,13 +105,23 @@ function EditUser({ userid }) {
|
||||
<h3>Authentifizierung</h3>
|
||||
<div className='row'>
|
||||
<div className='column'>
|
||||
<TextBox formdata={formdata} formchange={formchange} id="rfid_uid" label="RFID" maxlength={maxlength_rfid} />
|
||||
<TextBox formdata={formdata} formchange={formchange} id="rfid_uid" label="RFID" maxlength={maxlength_rfid} disabled={rfidscan.active} overridevalue={rfidscan.active&&"Scannen..."}/>
|
||||
{<span class="textbox__info"> {formdata["rfid_uid"] ? formdata["rfid_uid"].length : 0} von {maxlength_rfid} Zeichen verwendet.</span>}
|
||||
</div>
|
||||
<div className='column'>
|
||||
<Button onClick={runScan}>{rfidscan.active ? "Abbrechen" : "Scannen"}</Button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className='column'>
|
||||
<TextBox formdata={formdata} formchange={formchange} id="user_pin" label="Pin" maxlength={maxlength_pin} />
|
||||
{<span class="textbox__info"> {formdata["user_pin"] ? formdata["user_pin"].length : 0} von {maxlength_pin} Zeichen verwendet.</span>}
|
||||
</div>
|
||||
<div className='column'>
|
||||
<b>Info</b>
|
||||
<span>Achten Sie darauf, eine PIN <br />nicht mehrfach zu benutzen.</span>
|
||||
</div>
|
||||
</div>
|
||||
<h3>Status</h3>
|
||||
<div className='row'>
|
||||
|
@ -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);
|
||||
}
|
||||
else {
|
||||
set(prev=>({ ...prev, error: "user" }));
|
||||
}
|
||||
set({ username: '', password: '' });
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
@ -35,7 +39,9 @@ function Login() {
|
||||
<div className={'contentbox'} >
|
||||
<h2>Anmeldung</h2>
|
||||
<p >Bitte melden Sie sich mit ihren Nutzerdaten an.</p>
|
||||
{val.error !== null && <span style={'color: red'}>Fehler: Ungültige Anmeldedaten.</span>}
|
||||
|
||||
{val.error ==='login_failed' && <Warnbox title='Anmeldefehler'>Ungültige Anmeldedaten.<br />Bitte überprüfen Sie den eingebenen Benutzernamen und das Passwort.</Warnbox>}
|
||||
{val.error ==='network_connection' && <Warnbox title='Netwerkfehler'>Die Kommunikation mit dem Gerät ist zurzeit nicht möglich.<br />Bitte überprüfen Sie die Netzwerkverbindung.</Warnbox>}
|
||||
<form id="login_form" onSubmit={onSubmit} >
|
||||
<div className='row'>
|
||||
<TextBox maxlength={25} formdata={val} formchange={set} id="username" label="Benutzername" />
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
31
src/style/_warnbox.sass
Normal file
31
src/style/_warnbox.sass
Normal file
@ -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
|
||||
|
@ -6,6 +6,7 @@
|
||||
@use 'footer'
|
||||
@use 'button'
|
||||
@use 'input'
|
||||
@import 'warnbox'
|
||||
*
|
||||
//border: 1px dotted red
|
||||
box-sizing: border-box
|
||||
|
Loading…
x
Reference in New Issue
Block a user