From f4f686073fa4ee9c4b2704d19073dc89710c4eda Mon Sep 17 00:00:00 2001 From: Alexander Polynomdivision Date: Thu, 6 Sep 2018 20:05:21 +0200 Subject: [PATCH] feat: Implement the level view --- src/components/app.tsx | 57 ++++++++++++++++-- src/models/vocab.ts | 9 +++ src/pages/dashboard.tsx | 74 +++++++++++++++++------ src/pages/level.tsx | 128 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 243 insertions(+), 25 deletions(-) create mode 100644 src/models/vocab.ts create mode 100644 src/pages/level.tsx diff --git a/src/components/app.tsx b/src/components/app.tsx index 00674e2..aaa403c 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -23,8 +23,10 @@ import AuthRoute from "../security/AuthRoute"; import Dashboard from "../pages/dashboard"; import LoginPage from "../pages/login"; import LessonsPage from "../pages/lessons"; +import LevelPage from "../pages/level"; import { ILesson } from "../models/lesson"; +import { IVocab } from "../models/vocab"; interface IState { loggedIn: boolean; @@ -38,13 +40,14 @@ export default class Application extends React.Component<{}, IState> { this.state = { loggedIn: false, + drawerOpen: false, }; this.login = this.login.bind(this); this.isAuthenticated = this.isAuthenticated.bind(this); } - lessons(): ILesson[] { + getLessons(): ILesson[] { // TODO: Actually fetch them from somewhere const lessons = [{ name: "Der Bauer auf dem Feld", @@ -61,7 +64,7 @@ export default class Application extends React.Component<{}, IState> { return lessons; } - learners(): ILearner[] { + getLearners(): ILearner[] { return [{ username: "Polynomdivision", level: 5, @@ -77,6 +80,36 @@ export default class Application extends React.Component<{}, IState> { }]; } + getNextLesson(): ILesson { + // TODO: Actually fetch data + return { + name: "???", + desc: "Warum schreibe ich überhaupt was?dsd dddddddddddddddddddddd", + level: 2, + done: false, + }; + } + + getLevelVocab(id: string): IVocab[] { + // TODO: Actually implement this + // TODO: Don't fetch this when it was already fetched once. + return [{ + latin: "Veni", + german: "", + id: 0 + }, { + latin: "Vidi", + german: "", + id: 1 + }, { + latin: "Vici", + german: "", + hint: "Wird \"Viki\" und nicht \"Vichi\" ausgesprochen", + mnemonic: "Merk dir das Wort mit Caesars berühmten Worten: \"Veni Vidi Vici\"; Er kam, sah und siegte", + id: 2 + }] as IVocab[]; + } + login(username: string, password: string): Promise { return new Promise((res, rej) => { // TODO @@ -146,7 +179,9 @@ export default class Application extends React.Component<{}, IState> { - + + Levelübersicht + @@ -168,11 +203,21 @@ export default class Application extends React.Component<{}, IState> { } /> + component={() => } /> } /> + path="/levelList" + component={() => } /> + {/*We cannot use AuthRoute here, because match is undefined otherwise*/} + { + if (this.isAuthenticated()) { + return ; + } else { + return ; + } + }} /> ; diff --git a/src/models/vocab.ts b/src/models/vocab.ts new file mode 100644 index 0000000..0aa95d1 --- /dev/null +++ b/src/models/vocab.ts @@ -0,0 +1,9 @@ +export interface IVocab { + german: string; + latin: string; + hint?: string; + mnemonic?: string; + + // This number is lesson specific + id: number; +}; diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 51acbaa..ed978fa 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -1,5 +1,7 @@ import * as React from "react"; +import { Redirect } from "react-router"; + import Grid from "@material-ui/core/Grid"; import Typography from "@material-ui/core/Typography"; import Button from "@material-ui/core/Button"; @@ -11,35 +13,69 @@ import { ILesson } from "../models/lesson"; import { ILearner } from "../models/learner"; interface IProps { - lessons: ILesson[]; + nextLesson: () => ILesson; learners: ILearner[]; } -export default class Dashboard extends React.Component<{}> { +interface IState { + toLevel: number; +} + +export default class Dashboard extends React.Component { + constructor(props: any) { + super(props); + + this.state = { + toLevel: -1; + }; + } + render() { const small = window.matchMedia("(max-width: 700px)").matches; const direction = small ? "column" : "row"; - return - - - Nächstes Level - - - - - - Rangliste: Top 10 + const lesson = this.props.nextLesson(); + + return
+ { + this.state.toLevel !== -1 ? ( + + ) : undefined + } + + + + {`Level ${lesson.level}`} + {lesson.name} +
+ + {lesson.desc} + + +
+
+ + + + Rangliste: Top 10 - + + + + + + Some stuff +
- - - Some stuff - - - ; +
; } }; diff --git a/src/pages/level.tsx b/src/pages/level.tsx new file mode 100644 index 0000000..146ea54 --- /dev/null +++ b/src/pages/level.tsx @@ -0,0 +1,128 @@ +import * as React from "react"; + +import List from "@material-ui/core/List"; +import ListItem from "@material-ui/core/ListItem"; +import ListItemText from "@material-ui/core/ListItemText"; +import Grid from "@material-ui/core/Grid"; +import Typography from "@material-ui/core/Typography"; +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; + +import { IVocab } from "../models/vocab"; + +interface IProps { + id: string; + + levelVocab: (id: string) => IVocab[]; +}; + +interface IState { + currentVocab: IVocab; + lookedAt: number[]; +}; + +export default class LevelPage extends React.Component { + private uid = 0; + + constructor(props: any) { + super(props); + + this.state = { + currentVocab: this.props.levelVocab(this.props.id)[0], + lookedAt: [0], + }; + } + + genUID = (): string => { + return "LEVELPAGE" + this.uid++; + } + + renderVocabListItem = (vocab: IVocab): any => { + // Check if the vocab was already looked at + const lookedAt = this.state.lookedAt.find((el) => el === vocab.id) || vocab.id === 0; + + // TODO: Actually update the "Vocab View" when clicking + return { + // Prevent the user from using too much memory by always clicking on the elements + // Show the clicked at vocab word + this.setState({ + currentVocab: vocab, + lookedAt: this.state.lookedAt.concat(vocab.id), + }); + }}> + + {`${vocab.latin} ${lookedAt ? "✔" : ""}`} + + ; + } + + render() { + const { currentVocab } = this.state; + + return
+ + + + {this.props.levelVocab(this.props.id).map(this.renderVocabListItem)} + {/* TODO*/} + alert("Übung")}> + + Zur Übung + + + + + + + + + + + {currentVocab.latin} + + + {currentVocab.german} + + { + currentVocab.hint ? ( +
+ + Tipp: + + + {currentVocab.hint} + +
+ ) : undefined + } + { + currentVocab.mnemonic ? ( +
+ + Eselsbrücke: + + + {currentVocab.mnemonic} + +
+ ) : undefined + } +
+ {/*TODO: Maybe "next" and "prev" buttons?*/} +
+
+
+
+
+
; + } +};