usereditor, userlist ctx

This commit is contained in:
Jean Jacques Avril 2022-03-09 22:26:31 +01:00
parent 54bcf8aa68
commit 154366c20e
11 changed files with 175 additions and 87 deletions

View File

@ -9,7 +9,7 @@ function checkAuth(token){
return token==='DUMMYTOKEN';
}
function fetchdb(token){
async function fetchdb(token){
//fetch(`${server}/api/userdb`).then()
let xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", `${server}/api/userdb`, false ); // false for synchronous request
@ -22,8 +22,8 @@ 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' });
let [uid, first_name, last_name, rfid_uid, user_pin, active] = l.split([';']);
users.push({ line, uid, first_name, last_name, rfid_uid, user_pin, enabled: active[0]==='1' });
});
return users;

View File

@ -1,15 +1,15 @@
import { h } from "preact";
import { Link } from "preact-router";
const Pageselector = (props) => {
var items = [];
if(!isNaN(props.start)&&!isNaN(props.end)&&!isNaN(props.current))
for(var i=props.start; i<=props.end; i++){
items.push(<li><a {...(i==props.current?{className:'active'}:{})} href="#">{i}</a></li>);
items.push(<li><Link {...(i==props.current?{className:'active'}:{})} href={`/users/${i}`} value={i} >{i}</Link></li>);
}
items.push(<li><a href="#">&gt;</a></li>);
//items.push(<li><a href="" >&gt;</a></li>);
return (
<div class="page-nav-bar">
<ul>

View File

@ -1,17 +1,16 @@
import { h } from "preact";
import { Router, route } from "preact-router";
import { useReducer } from "preact/hooks";
import { Header, Menu } from "./index.js";
import { menuReducer, sessionReducer } from "../store/reducers";
import { useEffect, useReducer } from "preact/hooks";
import { Home, Users, Login, Logout, System } from "../route";
import { AppStateProvider } from "../store/AppState";
import { Home, Users, EditUser, Login, Logout, System } from "../route";
import { AppStateProvider, UserTableProvider, menuReducer, sessionReducer, userTableReducer } from "../store";
function App() {
// useReducer
const menu = useReducer(menuReducer, false);
const session = useReducer(sessionReducer, { active: true });
useEffect(()=>{
console.log("Use cookies here");
});
const [usertable, userreducer] = useReducer(userTableReducer, []);
this.menu_items = [
{ text: "Übersicht", path: "/" },
{ text: "Benutzer", path: "/users" },
@ -33,15 +32,17 @@ function App() {
<div class="page">
<Menu items={this.menu_items} />
{!menu[0] &&
<UserTableProvider value={{ usertable, userreducer }} >
<Router onChange={this.handleRoute}>
<Home path="/" user="me" />
<Login path="login" />
<System path="/system" />
<Logout path="/logout" />
<Users path="/users" />
<Users path="/users/:pageid?" />
<EditUser path="/edituser/:userid" />
<div class="container" default>Error 404</div>
</Router>
</UserTableProvider>
}
</div>
<footer>

View File

@ -1,19 +1,10 @@
import { h } from "preact";
import { useState } from "preact/hooks";
function UserList({userlist}) {
const [list, setuserlist] = useState(userlist);
function UserList({userlist,editUser, deleteUser, start, end}) {
const deleteUser=(user)=>{
let temp = [...list];
temp.splice(temp.indexOf(user),1);
setuserlist(temp);
}
const editUser=(user)=>{
alert(`edit: ${user.uid}`);
}
const displayUser=(user)=>{
return (
<div key={`user${user.line}`} class="user-list-item" >
@ -34,7 +25,7 @@ function UserList({userlist}) {
return (
<>
{list&&list.map((user)=>displayUser(user))}
{userlist&&(start!==undefined&&end?userlist.slice(start,end).map((user)=>displayUser(user)):userlist.map((user)=>displayUser(user)))}
</>
);

View File

@ -1,36 +1,37 @@
import {h} from 'preact';
function EditUser(){
import { useContext, useState } from 'preact/hooks';
import { route } from 'preact-router';
import { UserTable } from "../../store";
function EditUser({userid}){
const { usertable, userreducer } = useContext(UserTable);
let user = usertable.find(u=>u.uid===userid)
const [formdata, formchange] = useState(user?user:{});
const onChange=(e)=>{
console.log(e);
if(e.target.type==='checkbox')
formchange({...formdata, [e.target.id]:e.target.checked})
else
formchange({...formdata, [e.target.id]:e.target.value})
}
const onSubmit=(e)=>{
e.preventDefault();
userreducer({type:'update', user: formdata})
route('/users');
}
const Input = ({id, type='text', label, disabled})=>(<div><label for={id}>{label}</label><input disabled={disabled} type={type} checked={type=='checkbox'&&formdata[id]?'on':''} value={formdata[id]} id={id} onChange={onChange} name={`edit-${id}`} /></div>)
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>
<form onSubmit={onSubmit}>
<Input id="uid" label="UserID" />
<Input id="first_name" label="Vorname" />
<Input id="last_name" label="NachName" />
<Input id="rfid_uid" label="RFID" />
<Input id="user_pin" label="Pin" />
<Input id="enabled" type={'checkbox'} label="Vorname" />
<input type={'submit'}>Speichern</input>
</form>
</div>
)
}
export default EditUser;

View File

@ -1,7 +1,8 @@
import Home from "./home"
import Users from './users'
import EditUser from "./edituser"
import Profile from "./profile"
import Login from "./login"
import Logout from './logout'
import System from './system'
export {Home, Users, Profile, Login, Logout, System }
export {Home, Users, EditUser, Profile, Login, Logout, System }

View File

@ -1,16 +1,65 @@
import { h } from "preact";
import UserList from "../../components/userlist";
import {Pageselector, Breadcrumbs} from "../../components";
import api, {parsedb} from '../../api'
function Users() {
console.log(parsedb)
import { UserList, Pageselector, Breadcrumbs } from "../../components";
import api from '../../api'
import { route } from 'preact-router';
import { useContext, useEffect, useState } from "preact/hooks";
import { UserTable } from "../../store";
function Users({pageid}) {
const [viewstate, setview] = useState({limit:100, page:1, pages:null})
const { usertable, userreducer } = useContext(UserTable)
const setPage = (e)=>{
e.preventDefault();
console.log(e)
let page = e.target.text;
setview({...viewstate, page})
}
if (usertable.length === 0)
api.fetchdb().then(imported => {
let action = { type: 'import', imported };
userreducer(action);
});
useEffect(() => {
if (usertable.length === 0)
api.fetchdb().then(imported => {
let action = { type: 'import', imported };
userreducer(action);
})
});
useEffect(()=>{
setview({...viewstate,pages:Math.ceil(usertable.length/viewstate.limit)});
console.log("New View effect")
},[usertable])
useEffect(()=>{
if(pageid&&!isNaN(pageid))
setview({...viewstate, page: pageid})
},[pageid])
const deleteUser = (user) => {
let action = {
type: 'delete',
user
}
userreducer(action)
}
const calculateView=()=>{
let start=viewstate.limit*(viewstate.page-1);
let end=viewstate.limit*(viewstate.page);
return {start, end}
}
const editUser = (user) => {
route(`/edituser/${user.uid}`);
}
const navigation = ["Users"];
console.log(viewstate);
//
return (
<div class="container">
<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} />
<UserList {...calculateView()} userlist={usertable} deleteUser={deleteUser} editUser={editUser} />
<Pageselector start={1} end={viewstate.pages} current={viewstate.page} setPage={setPage} />
</div>
);

View File

@ -1,6 +1,5 @@
import { createContext } from "preact";
const AppState = createContext({});
export const AppStateProvider = AppState.Provider;
const AppStateProvider = AppState.Provider;
export default AppState;
export {AppStateProvider};

8
src/store/UserTable.js Normal file
View File

@ -0,0 +1,8 @@
import { createContext } from "preact";
export function CreateUserTable(){
const usercontext = createContext();
return usercontext;
}
const UserTable = CreateUserTable();
export default UserTable.Provider;
export {UserTable}

5
src/store/index.js Normal file
View File

@ -0,0 +1,5 @@
import AppState, {AppStateProvider} from "./AppState";
import UserTableProvider,{UserTable} from './UserTable';
import {menuReducer, sessionReducer, userTableReducer} from './reducers';
export default AppState;
export {AppStateProvider, UserTableProvider, UserTable, menuReducer, sessionReducer, userTableReducer}

View File

@ -14,3 +14,36 @@ export const sessionReducer = (state, action) => {
default: throw new Error("action type unknown to session reducer");
}
}
export const userTableReducer = (state, action) => {
let user = action.user;
switch (action.type) {
case 'create': return [...state, { line: state.length, ...user }]
case 'delete': {
let newstate = [];
let newindex = 0;
state.forEach((u, i) => {
if (user.uid && u.uid !== user.uid|| user.line && i !== user.line )
newstate.push({ ...u, line: newindex++ })
return newstate;
}, []);
return newstate;
}
case 'update': {
let newstate = [];
state.forEach((u, i) => {
if (user.uid && u.uid === user.uid || user.line && i === user.line)
newstate.push(user);
else
newstate.push(u);
});
return [...newstate]
}
case 'import':
return action.imported;
case 'reset':
return [];
default:
throw new Error("action type unknown to usertable reducer");
}
}