created a simple data store

This commit is contained in:
Jean Jacques Avril 2022-03-06 20:34:15 +01:00
parent 642083bad6
commit ea3b847268
10 changed files with 206 additions and 72 deletions

View File

@ -1,4 +1,4 @@
import { Component, createRef, h } from "preact"; import { Component, h } from "preact";
import { Router } from "preact-router"; import { Router } from "preact-router";
import Header from "./header"; import Header from "./header";
import Login from "../routes/login"; import Login from "../routes/login";
@ -6,9 +6,13 @@ import Profile from "../routes/profile";
import Menu from "./menu"; import Menu from "./menu";
import Users from "../routes/users"; import Users from "../routes/users";
import { useCallback, useState } from "preact/hooks"; import { useCallback, useState } from "preact/hooks";
const menu = createRef(); import { AppData, Provider, Consumer } from '../utils'
class App extends Component { const App = () => {
toggleMenu() { const appdata = AppData();
let session = appdata.get("Session");
//session.sub(forceUpdate);
const toggleMenu = () => {
const [visible, setValue] = useState(false); const [visible, setValue] = useState(false);
const toggle = useCallback(() => { const toggle = useCallback(() => {
setValue(!visible); setValue(!visible);
@ -16,29 +20,24 @@ class App extends Component {
}, [visible]); }, [visible]);
return { visible, toggle }; return { visible, toggle };
} }
authenticateUser() {
const [session, setValue] = useState({ token: null });
const login = (username, password) => {
if (username == "admin" && password == "admin") {
setValue({ ...session, token: "ABCDEFG" });
return true;
}
};
const logout = () => setValue({ ...session, token: null });
const isAuthenticated = () => session.token != null;
return { login, logout, isAuthenticated };
}
render() {
const menu = this.toggleMenu();
const auth = this.authenticateUser(); const menu = toggleMenu();
return ( return (
<Provider appdata={appdata} >
<div id="wrapper"> <div id="wrapper">
<Header menu={menu} auth={auth} /> <Consumer datapath="Session">
{(appdata) => {
console.log(appdata);
}}
</Consumer>
<Header menu={menu} />
<Menu menu={menu} /> <Menu menu={menu} />
{!menu.visible && {!menu.visible &&
(!auth.isAuthenticated() ? ( (!session.data || session.data.username === '' ? (
<Login auth={auth} /> <Login />
) : ( ) : (
<div class="page"> <div class="page">
<Router> <Router>
@ -50,8 +49,9 @@ class App extends Component {
</div> </div>
))} ))}
</div> </div>
</Provider>
); );
}
} }
export default App; export default App;

View File

@ -1,11 +1,14 @@
import { Component, createRef, h } from 'preact'; import { h, forceUpdate } from 'preact';
import { Consumer } from '../../utils'
//import { Link } from 'preact-router/match'; //import { Link } from 'preact-router/match';
const Header = (props) => ( const Header = (props, ctx) => {
console.log(ctx.data)
return (
<header className='header'> <header className='header'>
<div className="container"> <div className="container">
<h1>Login</h1> <h1>Login</h1>
{props.auth.isAuthenticated() && (<div id="hamburger-button" className={`hamburger ${props.menu.visible && 'hamburger-active'}`} {ctx.data && (<div id="hamburger-button" className={`hamburger ${props.menu.visible && 'hamburger-active'}`}
onClick={() => props.menu.toggle()}> onClick={() => props.menu.toggle()}>
<hr /> <hr />
<hr /> <hr />
@ -13,8 +16,8 @@ const Header = (props) => (
</div>)} </div>)}
</div> </div>
</header> </header>
); );
}

View File

@ -1,6 +1,6 @@
import './style/style.sass'; import './style/style.sass';
import App from './components/app'; import App from './components/app';
import { h, render, Component } from "preact" import { h, render } from "preact"
render(<App />, document.body) render(<App />, document.body)
//export default App;

View File

@ -1,33 +1,33 @@
import { Component, h } from 'preact'; import { h } from 'preact';
import { useState } from 'preact/hooks';
import Breadcrumbs from '../../components/breadcrumbs'; import Breadcrumbs from '../../components/breadcrumbs';
class Login extends Component { const Login = (props,ctx) => {
state = { username: '', password: '' }; const [val,set] = useState({ username: '', password: '' });
navigation = ["Login"]; const navigation = ["Login"];
onSubmit = (e) => { const session = ctx.get('Session');
function onSubmit (e) {
e.preventDefault(); e.preventDefault();
console.log(this.state); session.data = val;
this.setState({ username: '', password: '' }); console.log(session.data);
if(!this.props.auth.login(this.state.username,this.state.password)) set({username: '', password: '' });
alert("Wrong login")
} }
render() {
return (<div id="login-screen" class="page"> return (<div id="login-screen" class="page">
<div class="container"> <div class="container">
<Breadcrumbs items={this.navigation} /> <Breadcrumbs items={navigation} />
<form id="login_form" onSubmit={this.onSubmit} > <form id="login_form" onSubmit={onSubmit} >
<p> <p>
Bitte melden Sie sich mit ihren Nutzerdaten an. Bitte melden Sie sich mit ihren Nutzerdaten an.
</p> </p>
<div class="input-box"> <div class="input-box">
<input id="name" type="text" placeholder="Username" onInput={e => this.setState(prev => ({ ...prev, username: e.target.value }))} value={this.state.username} /> <input id="name" type="text" placeholder="Username" onInput={e => set( {...val, username: e.target.value} )} value={val.username} />
<label for="name">Benutzername</label> <label for="name">Benutzername</label>
</div> </div>
<div class="input-box"> <div class="input-box">
<input id="pass" type="password" placeholder="Passwort" onInput={e => this.setState(prev => ({ ...prev, password: e.target.value }))} value={this.state.password} /> <input id="pass" type="password" placeholder="Passwort" onInput={e => set( {...val, password: e.target.value} )} value={val.password} />
<label for="pass">Password</label> <label for="pass">Password</label>
</div> </div>
<input type="submit" value="Submit" /> <input type="submit" value="Submit" />
@ -35,7 +35,7 @@ class Login extends Component {
</form> </form>
</div> </div>
</div>); </div>);
}
} }
export default Login; export default Login;

View File

@ -0,0 +1,10 @@
function Consumer(props, ctx){
this.componentWillMount=()=>{
console.log("Component mounted");
}
if(props.datapath!==undefined)
return props.children(ctx.get(props.datapath));
return props.children(ctx);
}
export default Consumer;

View File

@ -0,0 +1,40 @@
function subscribe (f) {
if ('function' !== typeof (f))
throw new Error("Subscriber needs to be a function.");
this.observers.push(f);
return () => { this.observers.splice(this.observers.indexOf(f), 1) }
}
function getStore(path){
let path_slices = path.split("/");
let current=this;
for(let s of path_slices){
if(!(s in current.tree))
current.tree[s] = new ObservableData();
current = current.tree[s];
}
return current;
}
function ObservableData() {
this.observers = [];
this.tree = {};
this._data = {};
const dispatchChange = () => {
this.observers.map(o => o());
}
return {
tree:this.tree,
sub: subscribe.bind(this),
get: getStore.bind(this),
get data() {
return this._data;
},
set data(val) {
this._data = val;
dispatchChange();
},
}
}
export default ObservableData;

View File

@ -0,0 +1,14 @@
function Provider(props) {
if (this.root !== undefined) props.appdata = this.root;
if (!this.getChildContext && props.appdata !== undefined) {
this.getChildContext = () => props.appdata;
this.shouldComponentUpdate = function (_props) {
if (this.props.appdata !== _props.appdata) {
return true;
}
}
}
return props.children;
}
export default Provider;

View File

@ -0,0 +1,22 @@
import ObservableData from './ObservableData'
import Provider from './Provider'
import Consumer from './Consumer'
let instance = null;
function AppData() {
if(instance===null){
console.log("New AppData created")
const root = new ObservableData();
root.get("affe1234/123");
instance = {
data: root.data,
get: root.get,
Provider: Provider.bind(this),
Consumer: Consumer.bind(this),
}
}
return instance;
}
export default AppData;

View File

@ -0,0 +1,40 @@
import {createContext} from 'preact';
class Session {
static instance=null;
observers = [];
static getInstance(){
if(this.instance==null)
this.instance = new Session();
return this.instance;
}
constructor(){
console.log("new Instance of Session manager created");
this.state={token:null,expiry:null,name:null}
}
observe(o){
this.observers.push(o);
}
get Context(){
return createContext(this);
}
setState(updated){
this.state = {...this.state,...updated}
this.observers.map(o=>o.forceUpdate());
console.log(this.state);
}
Login(username, password) {
if (username == "admin" && password == "admin")
{ this.setState({token:"TEST",expiry: new Date(Date.now() + 60000*60),name:username});
return true;
}
return false;
}
Logout = () => this.setState({token:null,expiry:null,name:null});
get isAuthenticated(){
return this.state.token!=null
}
}
export default ()=> Session.getInstance();

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

@ -0,0 +1,5 @@
import AppData from './appdata'
import oldSession from './appdata/oldSession';
import Provider from './appdata/Provider';
import Consumer from './appdata/Consumer';
export {AppData, Provider, Consumer, oldSession};