diff --git a/src/components/app.js b/src/components/app.js index 11e895d..7a38213 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -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 ( + +
+ + {(appdata) => { + console.log(appdata); + }} + +
+
+ + {!menu.visible && - - const menu = toggleMenu(); - return ( - - -
- - {(appdata) => { - console.log(appdata); - }} - -
- - {!menu.visible && - (!session.data || session.data.username === '' ? ( - - ) : ( -
- - + + + +
Error 404
-
- ))} -
-
- ); + + } +
+ +
+ +
+ ); + } + + } diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx index c5777af..62904c9 100644 --- a/src/components/header/index.jsx +++ b/src/components/header/index.jsx @@ -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 (

Login

- {ctx.data && (
props.menu.toggle()}>

diff --git a/src/components/index.js b/src/components/index.js new file mode 100644 index 0000000..6eb97cc --- /dev/null +++ b/src/components/index.js @@ -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 \ No newline at end of file diff --git a/src/components/menu/index.jsx b/src/components/menu/index.jsx index db415de..ac4135a 100644 --- a/src/components/menu/index.jsx +++ b/src/components/menu/index.jsx @@ -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 (
diff --git a/src/index.js b/src/index.js index 3ff9b5d..fa27f13 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ import './style/style.sass'; -import App from './components/app'; +import App from './components'; import { h, render } from "preact" render(, document.body) diff --git a/src/routes/home/index.js b/src/route/home/index.js similarity index 58% rename from src/routes/home/index.js rename to src/route/home/index.js index 28777fc..b42343f 100644 --- a/src/routes/home/index.js +++ b/src/route/home/index.js @@ -1,11 +1,10 @@ import { h } from 'preact'; -import style from './style.css'; -const Home = () => ( -
+function Home() {return( +

Home

This is the Home component.

); - +} export default Home; diff --git a/src/route/index.js b/src/route/index.js new file mode 100644 index 0000000..a3f6098 --- /dev/null +++ b/src/route/index.js @@ -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 } \ No newline at end of file diff --git a/src/routes/login/index.jsx b/src/route/login/index.jsx similarity index 57% rename from src/routes/login/index.jsx rename to src/route/login/index.jsx index 51f2a3e..5876282 100644 --- a/src/routes/login/index.jsx +++ b/src/route/login/index.jsx @@ -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 (
+ return (
-

+

Bitte melden Sie sich mit ihren Nutzerdaten an. +

+ {val.error !== null && Fehler: Ungültige Anmeldedaten.}
- set( {...val, username: e.target.value} )} value={val.username} /> + set({ ...val, username: e.target.value })} value={val.username} />
- set( {...val, password: e.target.value} )} value={val.password} /> + set({ ...val, password: e.target.value })} value={val.password} />
-
); + ); } diff --git a/src/route/logout/index.jsx b/src/route/logout/index.jsx new file mode 100644 index 0000000..2becf48 --- /dev/null +++ b/src/route/logout/index.jsx @@ -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 ( +
+ + +

+ Erfolgreich abgemeldet. + Erneut Anmelden +

+
+ ); + +} + +export default Logout; \ No newline at end of file diff --git a/src/routes/profile/index.js b/src/route/profile/index.js similarity index 50% rename from src/routes/profile/index.js rename to src/route/profile/index.js index 84a57e0..e1564a9 100644 --- a/src/routes/profile/index.js +++ b/src/route/profile/index.js @@ -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 ( -
-

Profile: {user}

-

This is the user profile for a user named { user }.

+
+
+

Profile: {user}

+

This is the user profile for a user named {user}.

-
Current time: {new Date(time).toLocaleString()}
+
Current time: {new Date(time).toLocaleString()}
-

- - {' '} - Clicked {count} times. -

+

+ + {' '} + Clicked {count} times. +

+
); } diff --git a/src/routes/profile/style.css b/src/route/profile/style.css similarity index 100% rename from src/routes/profile/style.css rename to src/route/profile/style.css diff --git a/src/route/system/index.jsx b/src/route/system/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/users/index.jsx b/src/route/users/index.jsx similarity index 100% rename from src/routes/users/index.jsx rename to src/route/users/index.jsx diff --git a/src/routes/home/style.css b/src/routes/home/style.css deleted file mode 100644 index f052d25..0000000 --- a/src/routes/home/style.css +++ /dev/null @@ -1,5 +0,0 @@ -.home { - padding: 56px 20px; - min-height: 100%; - width: 100%; -} diff --git a/src/style/_breadcrumbs.sass b/src/style/_breadcrumbs.sass index 1c8170d..afa8a49 100644 --- a/src/style/_breadcrumbs.sass +++ b/src/style/_breadcrumbs.sass @@ -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 diff --git a/src/style/_footer.sass b/src/style/_footer.sass new file mode 100644 index 0000000..fe2ea5f --- /dev/null +++ b/src/style/_footer.sass @@ -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% \ No newline at end of file diff --git a/src/style/_menu.sass b/src/style/_menu.sass index 63343f9..10c6574 100644 --- a/src/style/_menu.sass +++ b/src/style/_menu.sass @@ -16,6 +16,9 @@ //text-shadow: 0 0 .2em #000 width: 100% //background: #ccc + &:hover + background: #bbb + color: #333 &::after top: 100% left: 0 diff --git a/src/style/style.sass b/src/style/style.sass index c6bed66..dc2822b 100644 --- a/src/style/style.sass +++ b/src/style/style.sass @@ -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 \ No newline at end of file diff --git a/src/utils/appdata/ObservableData.js b/src/utils/appdata/ObservableData.js index c09f9fb..7cd3293 100644 --- a/src/utils/appdata/ObservableData.js +++ b/src/utils/appdata/ObservableData.js @@ -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; \ No newline at end of file diff --git a/src/utils/appdata/actions.js b/src/utils/appdata/actions.js new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/appdata/createAppData.js b/src/utils/appdata/createAppData.js new file mode 100644 index 0000000..e69de29