import * as React from "react"; import { BrowserRouter, Route, Redirect } from "react-router-dom"; import AuthRoute from "../security/AuthRoute"; import { setSessionToken, removeSessionToken, getSessionToken } from "../security/Token"; import Dashboard from "../containers/Dashboard"; import LoginPage from "../containers/LoginPage"; import LevelListPage from "../containers/LevelList"; import LevelPage from "../containers/LevelPage"; import ReviewPage from "../containers/Review"; import SummaryPage from "../containers/SummaryPage"; import WelcomePage from "../pages/intro"; import Drawer from "../containers/Drawer"; import { BACKEND_URL } from "../config"; import { ILevel } from "../models/level"; import { ILearner, TopTen } from "../models/learner"; import { IVocab, VocabType } from "../models/vocab"; import { IReviewMetadata, ReviewType } from "../models/review"; import { IUser } from "../models/user"; import { IResponse } from "../models/server"; interface IProps { authenticated: boolean; user: IUser; setAuthenticated: (status: boolean) => void; setDidLogin: (status: boolean) => void; setUser: (user: IUser) => void; }; // TODO: Replace the sessionStorage with localStorage? export default class Application extends React.Component { componentDidMount() { // TODO: Ask the server if our session is still valid // TODO: When asking the server if our session is still valid, a spinner // should be shown if (getSessionToken(window) !== null) { this.props.setAuthenticated(true); } } getLevels(): Promise { console.log("STUB: Application::getLevels"); return new Promise((res, rej) => { // TODO: Actually fetch them from somewhere setTimeout(() => { const levels = [{ 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, }]; res(levels); }, 2000); }); } getLastReview = (): IReviewMetadata => { console.log("STUB: Application::getLastReview"); // TODO: Actually fetch this // TODO: Stub return {} as IReviewMetadata; } setLastReview = (meta: IReviewMetadata) => { console.log("STUB: Application::setLastReview"); // TODO: Send this to the server this.setState({ lastReview: meta, }); } getReviewQueue = (): Promise => { console.log("STUB: Application::getReviewQueue"); // TODO: Implement return new Promise((res, rej) => { setTimeout(() => { res([ { german: ["Wein"], hint: "Worte auf '-um' sind meistens NeutrUM", type: VocabType.NOMEN, latin: { grundform: "Vinum", genitiv: "Vini", genus: "Neutrum" }, id: 0 }/* , { * 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", * type: VocabType.NOMEN, * id: 2 }, { * latin: "fuga", * german: "Flucht", * hint: "Worte auf \"-a\" sind FeminA", * type: VocabType.NOMEN, * id: 3 } */ ]); }, 2000); }); } getLearners(): ILearner[] { console.log("STUB: Application::getLearners"); // TODO: Implement return [{ username: "Polynomdivision", level: 5, score: 400, }, { username: "Polynomdivision2", level: 3, score: 500, }, { username: "Der eine Typ", level: 7, score: 100, }]; } getTopTenLearners = (): Promise => { const id = this.props.user.classId; return new Promise((res, rej) => { fetch(`${BACKEND_URL}/auth/class/${id}/topTen`, { headers: new Headers({ "Content-Type": "application/json", "Token": this.props.user.sessionToken, }), }).then(resp => resp.json(), err => rej(err)) .then(data => { if (data.error === "0") { res(data.data.topTen); } else { rej(data); } }); }); } getNextLevel = (): Promise => { return new Promise((res, rej) => { fetch(`${BACKEND_URL}/auth/user/nextLevel`, { headers: new Headers({ "Content-Type": "application/json", "Token": this.props.user.sessionToken, }), }).then(resp => resp.json(), err => rej(err)) .then(data => { if (data.error === "0") { res(data.data); } else { rej(data); } }); }); } getLevelVocab = (id: number): Promise => { return new Promise((res, rej) => { fetch(`${BACKEND_URL}/auth/level/${id}/vocab`, { method: "GET", headers: new Headers({ "Content-Type": "application/json", "Token": this.props.user.sessionToken, }), }).then(data => data.json(), err => { rej(err); }).then((resp: IResponse) => { if (resp.error === "0") { res(resp.data.vocab); } else { rej(resp); } }); }); } login = (username: string, password: string): Promise => { return new Promise((res, rej) => { fetch(`${BACKEND_URL}/login`, { method: "POST", headers: new Headers({ "Content-Type": "application/json", }), body: JSON.stringify({ // NOTE: We will force HTTPS, so this should not be a // problem username, password, }), }).then(data => data.json(), err => { // The fetch failed rej(err); }).then((resp: IResponse) => { if (resp.error === "0") { // Successful login this.props.setUser(resp.data); this.props.setDidLogin(true); setSessionToken(window, resp.data.sessionToken); this.props.setAuthenticated(true); res(resp.data); } else { rej(resp); } }); }); } logout = () => { // TODO: Tell the server that we're logging ourselves out removeSessionToken(window); this.props.setAuthenticated(false); } // Checks whether the user is logged in isAuthenticated = () => { return this.props.authenticated; } render() { // TODO: Show a spinner before mounting the routes, so that we can // check if were authenticated before doing any requests return
} /> { return }} /> { return }} /> { return }} /> } /> {/*We cannot use AuthRoute here, because match is undefined otherwise*/} { if (this.isAuthenticated()) { return ; } else { return ; } }} /> { if (this.isAuthenticated()) { return ; } else { return ; } }} /> { return ; }} /> { return }} />
; } };