added api csv parser

This commit is contained in:
Jean Jacques Avril 2022-03-08 21:38:23 +01:00
parent 68501897e4
commit 54bcf8aa68
15 changed files with 3291 additions and 2182 deletions

5220
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,8 @@
"serve": "sirv build --port 8080 --cors --single", "serve": "sirv build --port 8080 --cors --single",
"dev": "preact watch", "dev": "preact watch",
"lint": "eslint src", "lint": "eslint src",
"test": "jest" "test": "jest",
"buildmin": "preact build --no-sw --no-esm --no-prerender"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "preact", "extends": "preact",

View File

@ -1 +1 @@
[{"timestamp":1646751614979,"files":[{"filename":"bundle.2a54a.css","previous":0,"size":1709,"diff":1709},{"filename":"bundle.*****.esm.js","previous":0,"size":9856,"diff":9856},{"filename":"polyfills.*****.esm.js","previous":0,"size":2187,"diff":2187},{"filename":"sw.js","previous":0,"size":10599,"diff":10599},{"filename":"sw-esm.js","previous":0,"size":10603,"diff":10603},{"filename":"bundle.1a7a6.js","previous":0,"size":11947,"diff":11947},{"filename":"polyfills.058fb.js","previous":0,"size":2288,"diff":2288},{"filename":"index.html","previous":0,"size":536,"diff":536},{"filename":"200.html","previous":0,"size":536,"diff":536}]}] [{"timestamp":1646755354217,"files":[{"filename":"bundle.*****.esm.js","previous":9839,"size":0,"diff":-9839},{"filename":"polyfills.*****.esm.js","previous":2187,"size":0,"diff":-2187},{"filename":"sw.js","previous":10597,"size":0,"diff":-10597},{"filename":"sw-esm.js","previous":10603,"size":0,"diff":-10603},{"filename":"polyfills.058fb.js","previous":2288,"size":0,"diff":-2288},{"filename":"index.html","previous":521,"size":487,"diff":-34},{"filename":"200.html","previous":521,"size":0,"diff":-521},{"filename":"bundle.45d14.css","previous":1691,"size":1691,"diff":0},{"filename":"bundle.caa2d.js","previous":12219,"size":0,"diff":-12219},{"filename":"bundle.*****.js","previous":0,"size":12153,"diff":12153},{"filename":"polyfills.*****.js","previous":0,"size":2288,"diff":2288}]},{"timestamp":1646755194517,"files":[{"filename":"bundle.2a54a.css","previous":1709,"size":0,"diff":-1709},{"filename":"bundle.*****.esm.js","previous":9842,"size":9839,"diff":-3},{"filename":"polyfills.*****.esm.js","previous":2187,"size":2187,"diff":0},{"filename":"sw.js","previous":10595,"size":10597,"diff":2},{"filename":"sw-esm.js","previous":10600,"size":10603,"diff":3},{"filename":"polyfills.058fb.js","previous":2288,"size":2288,"diff":0},{"filename":"index.html","previous":536,"size":521,"diff":-15},{"filename":"200.html","previous":536,"size":521,"diff":-15},{"filename":"bundle.3030b.js","previous":12224,"size":0,"diff":-12224},{"filename":"bundle.45d14.css","previous":0,"size":1691,"diff":1691},{"filename":"bundle.caa2d.js","previous":0,"size":12219,"diff":12219}]},{"timestamp":1646755054393,"files":[{"filename":"bundle.2a54a.css","previous":1709,"size":1709,"diff":0},{"filename":"bundle.*****.esm.js","previous":9856,"size":9842,"diff":-14},{"filename":"polyfills.*****.esm.js","previous":2187,"size":2187,"diff":0},{"filename":"sw.js","previous":10599,"size":10595,"diff":-4},{"filename":"sw-esm.js","previous":10603,"size":10600,"diff":-3},{"filename":"bundle.1a7a6.js","previous":11947,"size":0,"diff":-11947},{"filename":"polyfills.058fb.js","previous":2288,"size":2288,"diff":0},{"filename":"index.html","previous":536,"size":536,"diff":0},{"filename":"200.html","previous":536,"size":536,"diff":0},{"filename":"bundle.3030b.js","previous":0,"size":12224,"diff":12224}]},{"timestamp":1646751614979,"files":[{"filename":"bundle.2a54a.css","previous":0,"size":1709,"diff":1709},{"filename":"bundle.*****.esm.js","previous":0,"size":9856,"diff":9856},{"filename":"polyfills.*****.esm.js","previous":0,"size":2187,"diff":2187},{"filename":"sw.js","previous":0,"size":10599,"diff":10599},{"filename":"sw-esm.js","previous":0,"size":10603,"diff":10603},{"filename":"bundle.1a7a6.js","previous":0,"size":11947,"diff":11947},{"filename":"polyfills.058fb.js","previous":0,"size":2288,"diff":2288},{"filename":"index.html","previous":0,"size":536,"diff":536},{"filename":"200.html","previous":0,"size":536,"diff":536}]}]

33
src/api/index.js Normal file
View File

@ -0,0 +1,33 @@
const server = 'http://192.168.4.22'
function login(username,password){
return 'DUMMYTOKEN';
}
function logout(){
return 'DUMMYTOKEN';
}
function checkAuth(token){
return token==='DUMMYTOKEN';
}
function fetchdb(token){
//fetch(`${server}/api/userdb`).then()
let xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", `${server}/api/userdb`, false ); // false for synchronous request
xmlHttp.send( null );
return parsedb(xmlHttp.responseText);
}
function parsedb(raw){
let lines = raw.split('\n');
let users = [];
lines.map((l,line)=>{
let [uid, first_name, last_name, rfid_uid, user_pin, enabled] = l.split(';');
users.push({ line, uid, first_name, last_name, rfid_uid, user_pin, enabled: enabled === '1' });
});
return users;
}
const publicfunctions = {login, logout, checkAuth, parsedb, fetchdb};
export default {...publicfunctions}
export {login, logout, checkAuth, parsedb}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,19 +1,21 @@
import { h } from "preact"; import { h } from "preact";
import { Router, route } from "preact-router"; import { Router, route } from "preact-router";
import {Header, Menu} from "./"; import {Header, Menu} from "./index.js";
import { menuReducer, sessionReducer } from "../store/reducers"; import { menuReducer, sessionReducer } from "../store/reducers";
import { useReducer } from "preact/hooks"; import { useEffect, useReducer } from "preact/hooks";
import { Home, Users, Profile, Login, Logout } from "../route"; import { Home, Users, Login, Logout, System } from "../route";
import { AppStateProvider } from "../store/AppState"; import { AppStateProvider } from "../store/AppState";
function App() { function App() {
// useReducer // useReducer
const menu = useReducer(menuReducer, false); const menu = useReducer(menuReducer, false);
const session = useReducer(sessionReducer, {active: true}); const session = useReducer(sessionReducer, {active: true});
useEffect(()=>{
console.log("Use cookies here");
});
this.menu_items = [ this.menu_items = [
{ text: "Übersicht", path: "/" }, { text: "Übersicht", path: "/" },
{ text: "Benutzer", path: "/users" }, { text: "Benutzer", path: "/users" },
{ text: "System", path: "/system" }, { text: "System", path: "/system" },
{ text: "Profil", path: "/profile" },
{ text: "Abmelden", path: "/logout" } { text: "Abmelden", path: "/logout" }
] ]
this.handleRoute = async e => { this.handleRoute = async e => {
@ -35,7 +37,7 @@ function App() {
<Router onChange={this.handleRoute}> <Router onChange={this.handleRoute}>
<Home path="/" user="me" /> <Home path="/" user="me" />
<Login path="login" /> <Login path="login" />
<Profile path="/profile" /> <System path="/system" />
<Logout path="/logout" /> <Logout path="/logout" />
<Users path="/users" /> <Users path="/users" />
<div class="container" default>Error 404</div> <div class="container" default>Error 404</div>

View File

@ -1,9 +1,9 @@
import {h} from 'preact'; import {h} from 'preact';
const Breadcrumbs = (props) =>{ if(props.items) return( const Breadcrumbs = ({items}) =>{ if(items) return(
<div class="breadcrumb"> <div class="breadcrumb">
<ul> <ul>
{props.items.map((text,i)=><li key={i}><a href="#">{text}</a> </li>)} {items.map((text,i)=><li key={i}><a href="#">{text}</a></li>)}
</ul> </ul>
</div> </div>
)} )}

View File

@ -4,33 +4,21 @@ import { useContext } from 'preact/hooks';
import AppState from '../../store/AppState'; import AppState from '../../store/AppState';
function Menu({ items }) { function Menu({ items }) {
let [menu_shown, toggle_menu] = useContext(AppState).menu; let [menu_shown, toggle_menu] = useContext(AppState).menu;
let menu_items = [ if (!items) return;
{ text: "Übersicht", path: "/" },
{ text: "Benutzer", path: "/users" },
{ text: "System", path: "/system" },
{ text: "Backup", path: "/backup" },
{ text: "Abmelden", path: "/logout" }
]
const onClick = (e) => { const onClick = (e) => {
e.preventDefault(); e.preventDefault();
toggle_menu('hide'); toggle_menu('hide');
} }
if (items)
menu_items = items;
if (menu_shown) if (menu_shown)
return ( return (
<div class="container" > <div class="container" >
<nav className='menu' > <nav className='menu' >
<ul> <ul>
{menu_items.map((element, i) => (<li key={i}><Link href={element.path} onClick={onClick} >{element.text}</Link></li>))} {items.map((element, i) => (<li key={i}><Link href={element.path} onClick={onClick} >{element.text}</Link></li>))}
</ul> </ul>
</nav> </nav>
</div>) </div>);
} }
export default Menu; export default Menu;

View File

@ -1,40 +1,42 @@
import { Component } from "preact"; import { h } from "preact";
import { useState } from "preact/hooks";
class UserList extends Component { function UserList({userlist}) {
const [list, setuserlist] = useState(userlist);
const deleteUser=(user)=>{
deleteUser(user){ let temp = [...list];
alert(`delete: ${user.uid}`); temp.splice(temp.indexOf(user),1);
setuserlist(temp);
} }
editUser(user){ const editUser=(user)=>{
alert(`edit: ${user.uid}`); alert(`edit: ${user.uid}`);
} }
displayUser(user,key){ const displayUser=(user)=>{
return ( return (
<div key={key} class="user-list-item"> <div key={`user${user.line}`} class="user-list-item">
<div class="user-attributes"> <div class="user-attributes">
<span><b>UID:</b> {user.uid}</span> <span>(<b>Aktiv</b>)</span><br /> <span><b>UID:</b> {user.uid}</span> <span>(<b>{user.enabled?'Aktiv':'Inaktiv'}</b>)</span><br />
<span><b>Vorname:</b> {user.first_name}</span><br /> <span><b>Vorname:</b> {user.first_name}</span><br />
<span><b>Nachname:</b> {user.last_name}</span><br /> <span><b>Nachname:</b> {user.last_name}</span><br />
<span><b>RFID:</b> {user.rfid}</span> <span><b>RFID:</b> {user.rfid_uid}</span>
<span><b>PIN:</b> {user.pin}</span> <span><b>PIN:</b> {user.user_pin}</span>
</div> </div>
<div class="btn-group"> <div class="btn-group">
<button class="btn-trash" onClick={()=>this.deleteUser(user)}>Löschen</button> <button class="btn-trash" onClick={()=>deleteUser(user)}>Löschen</button>
<button class="btn-edit" onClick={()=>this.editUser(user)}>Bearbeiten</button> <button class="btn-edit" onClick={()=>editUser(user)}>Bearbeiten</button>
</div> </div>
</div>); </div>);
} }
state = {};
render() {
return ( return (
<> <>
{this.props.userlist&&this.props.userlist.map((user,i)=>this.displayUser(user,i))} {list&&list.map((user)=>displayUser(user))}
</> </>
); );
}
} }
export default UserList export default UserList

View File

@ -0,0 +1,36 @@
import {h} from 'preact';
function EditUser(){
return(
<div className='container'>
<h1>Benutzer Bearbeiten</h1>
<form>
<div>
<label>ID</label>
<input />
</div>
<div>
<label>Vorname</label>
<input />
</div>
<div>
<label>Nachname</label>
<input />
</div>
<div>
<label>RFID</label>
<input />
</div>
<div>
<label>Pin</label>
<input />
</div>
<div>
<label>Aktiv</label>
<input type={'checkbox'} />
</div>
<input type={'submit'}>Speichern</input>
</form>
</div>
)
}

View File

@ -3,4 +3,5 @@ import Users from './users'
import Profile from "./profile" import Profile from "./profile"
import Login from "./login" import Login from "./login"
import Logout from './logout' import Logout from './logout'
export {Home, Users, Profile, Login, Logout } import System from './system'
export {Home, Users, Profile, Login, Logout, System }

View File

@ -1,6 +1,5 @@
import { h } from 'preact'; import { h } from 'preact';
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import style from './style.css';
// Note: `user` comes from the URL, courtesy of our router // Note: `user` comes from the URL, courtesy of our router
const Profile = ({ user }) => { const Profile = ({ user }) => {
@ -14,7 +13,7 @@ const Profile = ({ user }) => {
return ( return (
<div className='container'> <div className='container'>
<div class={style.profile}> <div >
<h1>Profile: {user}</h1> <h1>Profile: {user}</h1>
<p>This is the user profile for a user named {user}.</p> <p>This is the user profile for a user named {user}.</p>

View File

@ -1,5 +0,0 @@
.profile {
padding: 56px 20px;
min-height: 100%;
width: 100%;
}

View File

@ -0,0 +1,47 @@
import { h } from 'preact';
function System() {
return (
<div className='container'>
<h1>System</h1>
<h2>WiFi Setup</h2>
<hr />
<form>
<div>
<label>SSID</label>
<input type="text" placeholder='Wifi network name' />
</div>
<div>
<label>SSID</label>
<input type="text" placeholder='Wifi network name' />
</div>
</form>
<h2>Admin User</h2>
<hr />
<form>
<div>
<label>SSID</label>
<input type="text" placeholder='Wifi network name' />
</div>
<div>
<label>SSID</label>
<input type="text" placeholder='Wifi network name' />
</div>
</form>
<h2>Datenbank Backup</h2><hr />
<div>
<form>
<h3>Backup einspielen</h3>
<input type={'file'} />
<input type={'submit'} value={'Hochladen'} />
</form>
<h3>Backup herunterladen</h3>
<button>Download</button>
</div>
</div>)
}
export default System

View File

@ -1,24 +1,19 @@
import { Component } from "preact"; import { h } from "preact";
import UserList from "../../components/userlist"; import UserList from "../../components/userlist";
import Pageselector from "../../components/Pageselector"; import {Pageselector, Breadcrumbs} from "../../components";
class Users extends Component { import api, {parsedb} from '../../api'
shouldComponentUpdate() { function Users() {
return false console.log(parsedb)
} const navigation = ["Users"];
userlist = [
{ uid: 1234, first_name: 'Max', last_name: 'Muster', rfid: 'D3A2E35E', pin: 1234 },
{ uid: 12341, first_name: 'Max1', last_name: 'Muster', rfid: 'D3A2E35E', pin: 1234 },
{ uid: 12342, first_name: 'Max2', last_name: 'Muster', rfid: 'D3A2E35E', pin: 1234 },
];
render() {
return ( return (
<div class="container"> <div class="container">
<UserList userlist={this.userlist} /> <Breadcrumbs items={navigation} />
<div>Suche: <input type={'text'} /><button>Hinzufügen</button> Limit: <select><optgroup label={'Anzahl'}><option>10</option><option>25</option><option>50</option><option>100</option></optgroup><option>Alle</option></select></div>
<UserList userlist={api.fetchdb()} />
<Pageselector start={1} end={9} current={2} /> <Pageselector start={1} end={9} current={2} />
</div> </div>
); );
}
} }
export default Users; export default Users;