save before switch back to hooks
This commit is contained in:
parent
ea3b847268
commit
d990c46a02
@ -1,17 +1,14 @@
|
||||
import { Component, h } from "preact";
|
||||
import { Router } from "preact-router";
|
||||
import { Router, route } from "preact-router";
|
||||
import Header from "./header";
|
||||
import Login from "../routes/login";
|
||||
import Profile from "../routes/profile";
|
||||
import Menu from "./menu";
|
||||
import Users from "../routes/users";
|
||||
import { useCallback, useState } from "preact/hooks";
|
||||
import { AppData, Provider, Consumer } from '../utils'
|
||||
const App = () => {
|
||||
const appdata = AppData();
|
||||
let session = appdata.get("Session");
|
||||
//session.sub(forceUpdate);
|
||||
const toggleMenu = () => {
|
||||
import { AppData, Provider, Consumer } from '../utils';
|
||||
import { Home, Users, Profile, Login, Logout } from "../route";
|
||||
class App extends Component {
|
||||
appdata = AppData();
|
||||
session = this.appdata.get("Session");
|
||||
toggleMenu = () => {
|
||||
|
||||
const [visible, setValue] = useState(false);
|
||||
const toggle = useCallback(() => {
|
||||
@ -20,37 +17,68 @@ const App = () => {
|
||||
}, [visible]);
|
||||
return { visible, toggle };
|
||||
}
|
||||
componentWillUnmount() {
|
||||
//this.sub();
|
||||
}
|
||||
menu_items = [
|
||||
{ text: "Übersicht", path: "/" },
|
||||
{ text: "Benutzer", path: "/users" },
|
||||
{ text: "System", path: "/system" },
|
||||
{ text: "Profil", path: "/profile" },
|
||||
{ text: "Abmelden", path: "/logout" }
|
||||
]
|
||||
handleRoute = async e => {
|
||||
const isAuthed = this.session.actions.isAuth();
|
||||
switch (e.url) {
|
||||
default:
|
||||
if (!isAuthed) route('/login', true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
render() {
|
||||
let menu = this.toggleMenu();
|
||||
let session = this.session;
|
||||
session.addAction("isAuth", () => { return session.data && session.data.username !== '' })
|
||||
console.log(session.actions);
|
||||
this.sub = session.sub(() => this.forceUpdate());
|
||||
return (
|
||||
|
||||
<Provider appdata={this.appdata} >
|
||||
<div id="wrapper">
|
||||
<Consumer datapath="Session">
|
||||
{(appdata) => {
|
||||
console.log(appdata);
|
||||
}}
|
||||
</Consumer>
|
||||
<Header menu={menu} />
|
||||
<div class="page">
|
||||
<Menu menu={menu} items={this.menu_items} />
|
||||
{!menu.visible &&
|
||||
|
||||
|
||||
const menu = toggleMenu();
|
||||
return (
|
||||
|
||||
<Provider appdata={appdata} >
|
||||
<div id="wrapper">
|
||||
<Consumer datapath="Session">
|
||||
{(appdata) => {
|
||||
console.log(appdata);
|
||||
}}
|
||||
</Consumer>
|
||||
<Header menu={menu} />
|
||||
<Menu menu={menu} />
|
||||
{!menu.visible &&
|
||||
(!session.data || session.data.username === '' ? (
|
||||
<Login />
|
||||
) : (
|
||||
<div class="page">
|
||||
<Router>
|
||||
<Profile path="/test/" user="me" />
|
||||
<Router onChange={this.handleRoute}>
|
||||
<Home path="/" user="me" />
|
||||
<Login path="login" />
|
||||
<Profile path="/profile/:user" />
|
||||
<Logout path="/logout" />
|
||||
<Users path="/users" />
|
||||
<div class="container" default>Error 404</div>
|
||||
</Router>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
}
|
||||
</div>
|
||||
<footer>
|
||||
<div className="container" style={'text-align: center; align-items: center'}>
|
||||
<span>© Jean Jacques Avril 2022 </span>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { h, forceUpdate } from 'preact';
|
||||
import { Consumer } from '../../utils'
|
||||
//import { Link } from 'preact-router/match';
|
||||
|
||||
const Header = (props, ctx) => {
|
||||
console.log(ctx.data)
|
||||
const session = ctx.get('Session');
|
||||
return (
|
||||
<header className='header'>
|
||||
<div className="container">
|
||||
<h1>Login</h1>
|
||||
{ctx.data && (<div id="hamburger-button" className={`hamburger ${props.menu.visible && 'hamburger-active'}`}
|
||||
{session.actions.isAuth() && (<div id="hamburger-button" className={`hamburger ${props.menu.visible && 'hamburger-active'}`}
|
||||
onClick={() => props.menu.toggle()}>
|
||||
<hr />
|
||||
<hr />
|
||||
|
9
src/components/index.js
Normal file
9
src/components/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
import App from "./app";
|
||||
import Breadcrumbs from "./breadcrumbs";
|
||||
import Pageselector from "./Pageselector";
|
||||
import Header from "./header";
|
||||
import UserList from "./userlist";
|
||||
import Menu from "./menu";
|
||||
|
||||
export {App, Breadcrumbs, Pageselector, Header, UserList, Menu}
|
||||
export default App
|
@ -17,13 +17,14 @@ class Menu extends Component {
|
||||
e.preventDefault();
|
||||
this.props.menu.toggle();
|
||||
}
|
||||
render(props, state) {
|
||||
render(props) {
|
||||
if(props.items)
|
||||
this.menu_items = props.items;
|
||||
if (props.menu.visible)
|
||||
return (
|
||||
<div class="container" >
|
||||
<nav className='menu' >
|
||||
<ul>
|
||||
<li><Link href="/test" >Test</Link></li>
|
||||
{this.menu_items.map((element, i) => (<li key={i}><Link href={element.path} onClick={this.onClick} >{element.text}</Link></li>))}
|
||||
</ul>
|
||||
</nav>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import './style/style.sass';
|
||||
import App from './components/app';
|
||||
import App from './components';
|
||||
import { h, render } from "preact"
|
||||
|
||||
render(<App />, document.body)
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { h } from 'preact';
|
||||
import style from './style.css';
|
||||
|
||||
const Home = () => (
|
||||
<div class={style.home}>
|
||||
function Home() {return(
|
||||
<div class="container">
|
||||
<h1>Home</h1>
|
||||
<p>This is the Home component.</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
export default Home;
|
6
src/route/index.js
Normal file
6
src/route/index.js
Normal file
@ -0,0 +1,6 @@
|
||||
import Home from "./home"
|
||||
import Users from './users'
|
||||
import Profile from "./profile"
|
||||
import Login from "./login"
|
||||
import Logout from './logout'
|
||||
export {Home, Users, Profile, Login, Logout }
|
@ -1,40 +1,48 @@
|
||||
import { h } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import { route } from 'preact-router';
|
||||
|
||||
import Breadcrumbs from '../../components/breadcrumbs';
|
||||
|
||||
const Login = (props,ctx) => {
|
||||
const [val,set] = useState({ username: '', password: '' });
|
||||
function Login(props, ctx) {
|
||||
const [val, set] = useState({ username: '', password: '', error: null });
|
||||
const navigation = ["Login"];
|
||||
const session = ctx.get('Session');
|
||||
function onSubmit (e) {
|
||||
function onSubmit(e) {
|
||||
e.preventDefault();
|
||||
session.data = val;
|
||||
console.log(session.data);
|
||||
set({username: '', password: '' });
|
||||
//sucess
|
||||
if (val.username === 'admin') {
|
||||
session.data = val;
|
||||
route('/', true);
|
||||
}
|
||||
else {
|
||||
set({ ...val, error: "user" });
|
||||
}
|
||||
set({ username: '', password: '' });
|
||||
}
|
||||
|
||||
return (<div id="login-screen" class="page">
|
||||
return (
|
||||
<div class="container">
|
||||
<Breadcrumbs items={navigation} />
|
||||
|
||||
<form id="login_form" onSubmit={onSubmit} >
|
||||
<p>
|
||||
<p >
|
||||
Bitte melden Sie sich mit ihren Nutzerdaten an.
|
||||
|
||||
</p>
|
||||
{val.error !== null && <span style={'color: red'}>Fehler: Ungültige Anmeldedaten.</span>}
|
||||
<div class="input-box">
|
||||
<input id="name" type="text" placeholder="Username" onInput={e => set( {...val, username: e.target.value} )} value={val.username} />
|
||||
<input id="name" type="text" placeholder="Username" onInput={e => set({ ...val, username: e.target.value })} value={val.username} />
|
||||
<label for="name">Benutzername</label>
|
||||
</div>
|
||||
<div class="input-box">
|
||||
<input id="pass" type="password" placeholder="Passwort" onInput={e => set( {...val, password: e.target.value} )} value={val.password} />
|
||||
<input id="pass" type="password" placeholder="Passwort" onInput={e => set({ ...val, password: e.target.value })} value={val.password} />
|
||||
<label for="pass">Password</label>
|
||||
</div>
|
||||
<input type="submit" value="Submit" />
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>);
|
||||
);
|
||||
|
||||
}
|
||||
|
30
src/route/logout/index.jsx
Normal file
30
src/route/logout/index.jsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { h } from 'preact';
|
||||
import { Link } from 'preact-router';
|
||||
|
||||
import { Breadcrumbs } from '../../components';
|
||||
|
||||
function Logout (props, ctx) {
|
||||
const navigation = ["Logout"];
|
||||
const session = ctx.get('Session');
|
||||
this.shouldComponentUpdate = function(){
|
||||
console.log('functional component vs closures');
|
||||
}
|
||||
if (session.actions.isAuth()) {
|
||||
session.data = { username: '', password: '' };
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="container">
|
||||
<Breadcrumbs items={navigation} />
|
||||
|
||||
<p>
|
||||
Erfolgreich abgemeldet.
|
||||
<Link href="/login">Erneut Anmelden</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default Logout;
|
@ -1,5 +1,5 @@
|
||||
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
|
||||
@ -13,17 +13,19 @@ const Profile = ({ user }) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div class={style.profile}>
|
||||
<h1>Profile: {user}</h1>
|
||||
<p>This is the user profile for a user named { user }.</p>
|
||||
<div className='container'>
|
||||
<div class={style.profile}>
|
||||
<h1>Profile: {user}</h1>
|
||||
<p>This is the user profile for a user named {user}.</p>
|
||||
|
||||
<div>Current time: {new Date(time).toLocaleString()}</div>
|
||||
<div>Current time: {new Date(time).toLocaleString()}</div>
|
||||
|
||||
<p>
|
||||
<button onClick={() => setCount((count) => count + 1)}>Click Me</button>
|
||||
{' '}
|
||||
Clicked {count} times.
|
||||
</p>
|
||||
<p>
|
||||
<button onClick={() => setCount((count) => count + 1)}>Click Me</button>
|
||||
{' '}
|
||||
Clicked {count} times.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
0
src/route/system/index.jsx
Normal file
0
src/route/system/index.jsx
Normal file
@ -1,5 +0,0 @@
|
||||
.home {
|
||||
padding: 56px 20px;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
@mixin breadcrumbs
|
||||
padding: 1em 0
|
||||
padding-top: 1rem
|
||||
ul
|
||||
display: flex
|
||||
background: #eee
|
||||
box-shadow: inset 0 0 .3em #ccc, 0 0 .5em #ddd
|
||||
padding: .3em
|
||||
margin: 0
|
||||
border: 0.05em solid #fff
|
||||
border-radius: .3em
|
||||
list-style-type: none
|
||||
|
9
src/style/_footer.sass
Normal file
9
src/style/_footer.sass
Normal file
@ -0,0 +1,9 @@
|
||||
@mixin footer
|
||||
display: block
|
||||
background: #bbb
|
||||
text-shadow: 0 0 .2em #34d
|
||||
color: white
|
||||
flex-shrink: 0
|
||||
padding: 0.5rem 0
|
||||
margin-top: 1rem
|
||||
width: 100%
|
@ -16,6 +16,9 @@
|
||||
//text-shadow: 0 0 .2em #000
|
||||
width: 100%
|
||||
//background: #ccc
|
||||
&:hover
|
||||
background: #bbb
|
||||
color: #333
|
||||
&::after
|
||||
top: 100%
|
||||
left: 0
|
||||
|
@ -3,18 +3,19 @@
|
||||
@use 'login'
|
||||
@use 'breadcrumbs'
|
||||
@use 'pageselector'
|
||||
@use 'footer'
|
||||
*
|
||||
//border: red 1px dotted
|
||||
|
||||
box-sizing: border-box
|
||||
html
|
||||
font-family: Helvetica, sans-serif
|
||||
font-size: 16px
|
||||
height: 100%
|
||||
body
|
||||
|
||||
margin: 0
|
||||
padding: 0
|
||||
background-color: white
|
||||
//min-height: 100vh
|
||||
height: 100%
|
||||
width: 100%
|
||||
#wrapper
|
||||
display: flex
|
||||
@ -22,12 +23,14 @@ body
|
||||
justify-content: flex-start
|
||||
align-items: stretch
|
||||
min-height: 100%
|
||||
//margin-bottom: -2rem
|
||||
width: 100%
|
||||
.header
|
||||
z-index: 100
|
||||
position: fixed
|
||||
top: 0em
|
||||
width: 100%
|
||||
height: 4em
|
||||
height: 4rem
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: flex-end
|
||||
@ -54,7 +57,9 @@ body
|
||||
display: flex
|
||||
background: white
|
||||
width: 100%
|
||||
padding-top: 6em
|
||||
flex: 1
|
||||
margin-top: 4rem
|
||||
|
||||
.menu
|
||||
@include menu.nav
|
||||
|
||||
@ -124,3 +129,6 @@ body
|
||||
.btn-edit
|
||||
@include button()
|
||||
background-image: url("../assets/icons/edit-icon3.svg")
|
||||
|
||||
footer
|
||||
@include footer.footer
|
@ -16,15 +16,20 @@ function getStore(path){
|
||||
}
|
||||
return current;
|
||||
}
|
||||
function addAction(name, f){
|
||||
this._actions[name] = f.bind(this._data);
|
||||
}
|
||||
function ObservableData() {
|
||||
this.observers = [];
|
||||
this.tree = {};
|
||||
this._data = {};
|
||||
this._actions = {};
|
||||
const dispatchChange = () => {
|
||||
this.observers.map(o => o());
|
||||
}
|
||||
return {
|
||||
tree:this.tree,
|
||||
addAction: addAction.bind(this),
|
||||
sub: subscribe.bind(this),
|
||||
get: getStore.bind(this),
|
||||
get data() {
|
||||
@ -34,7 +39,8 @@ function ObservableData() {
|
||||
this._data = val;
|
||||
dispatchChange();
|
||||
},
|
||||
|
||||
actions: this._actions,
|
||||
|
||||
}
|
||||
}
|
||||
export default ObservableData;
|
0
src/utils/appdata/actions.js
Normal file
0
src/utils/appdata/actions.js
Normal file
0
src/utils/appdata/createAppData.js
Normal file
0
src/utils/appdata/createAppData.js
Normal file
Loading…
x
Reference in New Issue
Block a user