From 6734e59a1be5bc74a219e17ece2d840337c610b6 Mon Sep 17 00:00:00 2001 From: Alexander Polynomdivision Date: Sun, 26 Aug 2018 16:23:48 +0200 Subject: [PATCH] feat: Implement routing --- src/components/app.tsx | 66 +++++++++++++++++++++++++++++++------- src/models/lesson.ts | 7 ++++ src/pages/dashboard.tsx | 52 ++++++++++++++++++++++++++++++ src/pages/lessons.tsx | 52 ++++++++++++++++++++++++++++++ src/pages/login.tsx | 10 +++++- src/security/AuthRoute.tsx | 18 +++++++++++ 6 files changed, 193 insertions(+), 12 deletions(-) create mode 100644 src/models/lesson.ts create mode 100644 src/pages/dashboard.tsx create mode 100644 src/pages/lessons.tsx create mode 100644 src/security/AuthRoute.tsx diff --git a/src/components/app.tsx b/src/components/app.tsx index aa7e109..6a70d73 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -4,7 +4,15 @@ import AppBar from "@material-ui/core/AppBar"; import Toolbar from "@material-ui/core/Toolbar"; import Typography from "@material-ui/core/Typography"; +import { BrowserRouter, Route, Redirect } from "react-router-dom"; + +import AuthRoute from "../security/AuthRoute"; + +import Dashboard from "../pages/dashboard"; import LoginPage from "../pages/login"; +import LessonsPage from "../pages/lessons"; + +import { ILesson } from "../models/lesson"; interface IState { loggedIn: boolean; @@ -19,26 +27,62 @@ export default class Application extends React.Component<{}, IState> { }; this.login = this.login.bind(this); + this.isAuthenticated = this.isAuthenticated.bind(this); + } + + lessons(): ILesson[] { + const lessons = [{ + name: "Der Bauer auf dem Feld", + desc: "So fängt alles an: Du bist ein einfacher Bauer und musst dich die Karriereleiter mit deinen freshen Latein-Skills hinaufarbeiten", + level: 1, + done: true, + }, { + name: "???", + desc: "Warum schreibe ich überhaupt was?dsd dddddddddddddddddddddd", + level: 2, + done: false, + }]; + + return lessons; } login(username: string, password: string): Promise { return new Promise((res, rej) => { // TODO + this.setState({ + loggedIn: true + }); res(); }); } - render() { - return
- - - - Lateinicus - - - + // Checks whether the user is logged in + isAuthenticated() { + // TODO: Security? + return this.state.loggedIn === true; + } - -
; + render() { + return +
+ + + + Lateinicus + + + + +
+ } /> + { + return + }} /> + } /> + } /> +
+
+
; } }; diff --git a/src/models/lesson.ts b/src/models/lesson.ts new file mode 100644 index 0000000..5928b48 --- /dev/null +++ b/src/models/lesson.ts @@ -0,0 +1,7 @@ +export interface ILesson { + name: string; + desc: string; + level: number; + + done: boolean; +} diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx new file mode 100644 index 0000000..290c166 --- /dev/null +++ b/src/pages/dashboard.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; + +import Grid from "@material-ui/core/Grid"; +import Typography from "@material-ui/core/Typography"; +import Button from "@material-ui/core/Button"; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; + +import { ILesson } from "../models/lesson"; + +interface IProps { + lessons: ILesson[]; +} + +export default class Dashboard extends React.Component<{}> { + constructor(props: any) { + super(props); + } + + render() { + const small = window.matchMedia("(max-width: 700px)").matches; + const cName = small ? "lesson-card-xs" : "lesson-card-lg"; + + let key = 0; + const lessonToCard = (lesson: ILesson) => { + return + + + {`Level ${lesson.level}`} + {lesson.name} +
+ + {lesson.desc} + +
+ + + +
+
; + }; + + return + {this.props.lessons.map(lessonToCard)} + + } +}; diff --git a/src/pages/lessons.tsx b/src/pages/lessons.tsx new file mode 100644 index 0000000..290c166 --- /dev/null +++ b/src/pages/lessons.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; + +import Grid from "@material-ui/core/Grid"; +import Typography from "@material-ui/core/Typography"; +import Button from "@material-ui/core/Button"; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; + +import { ILesson } from "../models/lesson"; + +interface IProps { + lessons: ILesson[]; +} + +export default class Dashboard extends React.Component<{}> { + constructor(props: any) { + super(props); + } + + render() { + const small = window.matchMedia("(max-width: 700px)").matches; + const cName = small ? "lesson-card-xs" : "lesson-card-lg"; + + let key = 0; + const lessonToCard = (lesson: ILesson) => { + return + + + {`Level ${lesson.level}`} + {lesson.name} +
+ + {lesson.desc} + +
+ + + +
+
; + }; + + return + {this.props.lessons.map(lessonToCard)} + + } +}; diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 4bd92df..066def3 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -8,8 +8,11 @@ import Button from "@material-ui/core/Button"; import LinearProgress from "@material-ui/core/LinearProgress"; import Snackbar from "@material-ui/core/Snackbar"; +import { Redirect } from "react-router-dom"; + interface IProps { login: (username: string, password: string) => Promise; + loggedIn: boolean; } interface IState { @@ -63,7 +66,7 @@ export default class LoginPage extends React.Component<{}, IState> { const { username, password } = this.state; this.props.login(username, password).then((res) => { - load(false); + // Don't even do anything here! }, (err) => { load(false); showSnackbar("Failed to log in"); @@ -121,6 +124,11 @@ export default class LoginPage extends React.Component<{}, IState> { onClose={snackbarClose} message={this.state.snack} autoHideDuration={6000} /> + { + this.props.loggedIn ? ( + + ) : undefined + } ; } }; diff --git a/src/security/AuthRoute.tsx b/src/security/AuthRoute.tsx new file mode 100644 index 0000000..f47ce09 --- /dev/null +++ b/src/security/AuthRoute.tsx @@ -0,0 +1,18 @@ +import * as React from "react"; + +import { Route, Redirect } from "react-router-dom"; + +interface IAuthRouteProps { + path: string; + component: any; + isAuth: () => boolean; +} + +export default class AuthRoute extends React.Component { + render() { + const auth = this.props.isAuth(); + return auth ? : + } />; + } +};