feat: Remove the login stub

This commit is contained in:
Alexander Polynomdivision 2018-09-16 17:16:24 +02:00
parent 1dfdd2f409
commit 2cadcec370
5 changed files with 63 additions and 20 deletions

View File

@ -31,13 +31,17 @@ import ReviewPage from "../pages/review";
import SummaryPage from "../pages/summary"; import SummaryPage from "../pages/summary";
import WelcomePage from "../pages/intro"; import WelcomePage from "../pages/intro";
import { BACKEND_URL } from "../config";
import { ILevel } from "../models/level"; import { ILevel } from "../models/level";
import { ILearner } from "../models/learner"; import { ILearner } from "../models/learner";
import { IVocab, VocabType } from "../models/vocab"; import { IVocab, VocabType } from "../models/vocab";
import { IReviewMetadata, ReviewType } from "../models/review"; import { IReviewMetadata, ReviewType } from "../models/review";
import { IUser } from "../models/user";
interface IState { interface IState {
loggedIn: boolean; loggedIn: boolean;
user: IUser | {};
lastReview: IReviewMetadata; lastReview: IReviewMetadata;
@ -47,18 +51,20 @@ interface IState {
// TODO: Replace the sessionStorage with localStorage? // TODO: Replace the sessionStorage with localStorage?
// TODO: Cache API-Calls // TODO: Cache API-Calls
// TODO: When mounting without a login, check if the sessionToken is still valid
export default class Application extends React.Component<{}, IState> { export default class Application extends React.Component<{}, IState> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
// Load a key from the SessionStorage // Load a key from the SessionStorage
const authKey = window.sessionStorage.getItem("authKey") || null; const authKey = window.sessionStorage.getItem("sessionToken") || null;
// TODO // TODO
const loggedIn = authKey !== null; const loggedIn = authKey !== null;
// TODO: Fetch the last review // TODO: Fetch the last review
this.state = { this.state = {
loggedIn, loggedIn,
user: {},
lastReview: { lastReview: {
correct: 0, correct: 0,
@ -99,6 +105,8 @@ export default class Application extends React.Component<{}, IState> {
} }
setLastReview = (meta: IReviewMetadata) => { setLastReview = (meta: IReviewMetadata) => {
console.log("STUB: Application::setLastReview");
// TODO: Send this to the server // TODO: Send this to the server
this.setState({ this.setState({
lastReview: meta, lastReview: meta,
@ -216,16 +224,32 @@ export default class Application extends React.Component<{}, IState> {
} */] as IVocab[]; } */] as IVocab[];
} }
login(username: string, password: string): Promise<boolean> { login(username: string, password: string): Promise<IUser | {}> {
console.log("STUB: Application::login");
return new Promise((res, rej) => { return new Promise((res, rej) => {
// TODO: First login? Redirect to /welcome // TODO: First login? Redirect to /welcome
// TODO fetch(`${BACKEND_URL}/login`, {
this.setState({ method: "POST",
loggedIn: true headers: new Headers({
}); 'Content-Type': "application/json",
res(); }),
body: JSON.stringify({
// NOTE: We will force HTTPS and hash using pbkdf2 on the
// server
username: username,
hash: password,
}),
}).then(data => data.json())
.then((resp) => {
if (resp.error === "0") {
this.setState({
loggedIn: true,
user: resp.data,
});
res(resp.data);
} else {
rej({});
}
});
}); });
} }
@ -278,9 +302,8 @@ export default class Application extends React.Component<{}, IState> {
onOpen={() => this.setState({ drawerOpen: true })}> onOpen={() => this.setState({ drawerOpen: true })}>
<List component="nav"> <List component="nav">
<ListItem> <ListItem>
{/* TODO: Replace with the actual username */}
<Avatar alt="{Username}" style={{ width: 80, height: 80 }} src="https://avatarfiles.alphacoders.com/105/105250.jpg" /> <Avatar alt="{Username}" style={{ width: 80, height: 80 }} src="https://avatarfiles.alphacoders.com/105/105250.jpg" />
<ListItemText primary="{Username}" /> <ListItemText primary={this.state.user.username} />
</ListItem> </ListItem>
<Divider /> <Divider />

View File

@ -1,2 +1,4 @@
// Maximum distance from the answer to be still considered correct // Maximum distance from the answer to be still considered correct
export const LEVENSHTEIN_MAX_DISTANCE = 2; export const LEVENSHTEIN_MAX_DISTANCE = 2;
export const BACKEND_URL = "http://127.0.0.1:8080";

7
src/models/user.ts Normal file
View File

@ -0,0 +1,7 @@
export interface IUser {
username: string;
uid: string;
showWelcome: boolean;
sessionToken: string;
};

View File

@ -10,8 +10,10 @@ import Snackbar from "@material-ui/core/Snackbar";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
import { IUser } from "../models/user";
interface IProps { interface IProps {
login: (username: string, password: string) => Promise<boolean>; login: (username: string, password: string) => Promise<IUser | {}>;
loggedIn: boolean; loggedIn: boolean;
} }
@ -25,14 +27,14 @@ interface IState {
open: boolean; open: boolean;
} }
export default class LoginPage extends React.Component<{}, IState> { export default class LoginPage extends React.Component<IProps, IState> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = { this.state = {
username: "", username: "",
password: "", password: "",
loading: false; loading: false,
snack: "", snack: "",
open: false, open: false,
}; };
@ -50,12 +52,12 @@ export default class LoginPage extends React.Component<{}, IState> {
} }
performLogin() { performLogin() {
const load = (loading) => { const load = (loading: boolean) => {
this.setState({ this.setState({
loading loading
}); });
} }
const showSnackbar = (msg) => { const showSnackbar = (msg: string) => {
this.setState({ this.setState({
open: true, open: true,
snack: msg, snack: msg,
@ -65,9 +67,10 @@ export default class LoginPage extends React.Component<{}, IState> {
load(true); load(true);
const { username, password } = this.state; const { username, password } = this.state;
this.props.login(username, password).then((res) => { console.log(this.state);
this.props.login(username, password).then((res: IUser) => {
// Set the session key // Set the session key
window.sessionStorage.setItem("authKey", "test123"); window.sessionStorage.setItem("sessionToken", res.sessionToken);
}, (err) => { }, (err) => {
load(false); load(false);
showSnackbar("Failed to log in"); showSnackbar("Failed to log in");
@ -94,13 +97,15 @@ export default class LoginPage extends React.Component<{}, IState> {
<Grid item> <Grid item>
<TextField <TextField
label="Username" label="Username"
onChange={(ev) => this.update("username")} /> onChange={this.update("username")}
value={this.state.username} />
</Grid> </Grid>
<Grid item> <Grid item>
<TextField <TextField
label="Passwort" label="Passwort"
type="password" type="password"
onChange={(ev) => this.update("password")} /> value={this.state.password}
onChange={this.update("password")} />
</Grid> </Grid>
<Grid item> <Grid item>
<Button <Button

View File

@ -7,6 +7,7 @@ import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button"; import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import Popover from "@material-ui/core/Popover"; import Popover from "@material-ui/core/Popover";
import LinearProgress from "@material-ui/core/LinearProgress";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
@ -177,6 +178,8 @@ export default class ReviewPage extends React.Component<IProps, IState> {
render() { render() {
const { question, qtype } = this.state.current; const { question, qtype } = this.state.current;
const questionTitle = `${question} (${reviewQTypeToStr(qtype)})`; const questionTitle = `${question} (${reviewQTypeToStr(qtype)})`;
// TODO:
const progress = 50;
return <div> return <div>
{ {
@ -204,6 +207,9 @@ export default class ReviewPage extends React.Component<IProps, IState> {
if (ev.key === "Enter") if (ev.key === "Enter")
this.checkInput(); this.checkInput();
}} /> }} />
<LinearProgress
variant="determinate"
value={progress} />
<Popover <Popover
open={this.state.popoverOpen} open={this.state.popoverOpen}
anchorOrigin={{ anchorOrigin={{