refactor: Move the LevelList to Redux
This commit is contained in:
@@ -3,7 +3,6 @@ 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 Paper from "@material-ui/core/Paper";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
|
||||
@@ -6,21 +6,55 @@ 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 Paper from "@material-ui/core/Paper";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { ILevel } from "../models/lesson";
|
||||
import { ILevel } from "../models/level";
|
||||
|
||||
interface IProps {
|
||||
getLevels: () => Promise<ILevel[]>;
|
||||
|
||||
setLevels: (levels: ILevel[]) => void;
|
||||
setLoading: (state: boolean) => void;
|
||||
loading: boolean;
|
||||
levels: ILevel[];
|
||||
}
|
||||
|
||||
export default class Dashboard extends React.Component<{}> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
export default class Dashboard extends React.Component<IProps> {
|
||||
componentDidMount() {
|
||||
this.props.setLoading(true);
|
||||
|
||||
// Fetch the levels
|
||||
this.props.getLevels().then(res => {
|
||||
this.props.setLevels(res);
|
||||
this.props.setLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.loading) {
|
||||
return <div>
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Grid container direction="column" spacing={8}>
|
||||
<CircularProgress />
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</div>;
|
||||
}
|
||||
|
||||
const small = window.matchMedia("(max-width: 700px)").matches;
|
||||
const cName = small ? "lesson-card-xs" : "lesson-card-lg";
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@ 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";
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
import { IUser } from "../models/user";
|
||||
|
||||
interface IProps {
|
||||
login: (username: string, password: string) => Promise<IUser | {}>;
|
||||
authenticated: boolean;
|
||||
history: any;
|
||||
|
||||
setLoading: (state: boolean) => void;
|
||||
setSnackbar: (state: boolean, msg: string) => void;
|
||||
@@ -22,84 +23,83 @@ interface IProps {
|
||||
snackOpen: boolean;
|
||||
snackMsg: string;
|
||||
}
|
||||
/*
|
||||
* interface IState {
|
||||
* loading: boolean;
|
||||
*
|
||||
* snack: string; // The message
|
||||
* open: boolean;
|
||||
* } */
|
||||
|
||||
export default class LoginPage extends React.Component<IProps> {
|
||||
private usernameRef: any = undefined;
|
||||
private passwordRef: any = undefined;
|
||||
const LoginPageWithRouter = withRouter(
|
||||
class LoginPage extends React.Component<IProps> {
|
||||
private usernameRef: any = undefined;
|
||||
private passwordRef: any = undefined;
|
||||
|
||||
performLogin = () => {
|
||||
this.props.setLoading(true);
|
||||
performLogin = () => {
|
||||
this.props.setLoading(true);
|
||||
|
||||
const username = this.usernameRef.value || "";
|
||||
const password = this.passwordRef.value || "";
|
||||
this.props.login(username, password).then((res: IUser) => {
|
||||
// Set the session key
|
||||
window.sessionStorage.setItem("sessionToken", res.sessionToken);
|
||||
}, (err) => {
|
||||
this.props.setLoading(false);
|
||||
this.props.setSnackbar(true, "Failed to log in");
|
||||
});
|
||||
}
|
||||
const username = this.usernameRef.value || "";
|
||||
const password = this.passwordRef.value || "";
|
||||
this.props.login(username, password).then((res: IUser) => {
|
||||
// Set the session key
|
||||
window.sessionStorage.setItem("sessionToken", res.sessionToken);
|
||||
this.props.history.push("/dashboard");
|
||||
}, (err) => {
|
||||
this.props.setLoading(false);
|
||||
this.props.setSnackbar(true, "Failed to log in");
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Typography variant="title">Login</Typography>
|
||||
<Grid container direction="column" spacing={8}>
|
||||
<Grid item>
|
||||
<TextField
|
||||
label="Username"
|
||||
inputRef={node => this.usernameRef = node} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<TextField
|
||||
label="Passwort"
|
||||
type="password"
|
||||
inputRef={node => this.passwordRef = node} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="login-btn"
|
||||
onClick={() => this.performLogin()}>
|
||||
Login
|
||||
</Button>
|
||||
{
|
||||
this.props.loading ? (
|
||||
<LinearProgress />
|
||||
) : undefined
|
||||
}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Snackbar
|
||||
open={this.props.snackOpen}
|
||||
onClose={() => this.props.setSnackbar(false, "")}
|
||||
message={this.props.snackMsg}
|
||||
autoHideDuration={6000} />
|
||||
{
|
||||
this.props.authenticated ? (
|
||||
<Redirect to="/dashboard" />
|
||||
) : undefined
|
||||
componentDidMount() {
|
||||
// If we're already authenticated, we can skip the login page
|
||||
if (this.props.authenticated) {
|
||||
this.props.history.push("/dashboard");
|
||||
}
|
||||
</div>;
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Typography variant="title">Login</Typography>
|
||||
<Grid container direction="column" spacing={8}>
|
||||
<Grid item>
|
||||
<TextField
|
||||
label="Username"
|
||||
inputRef={node => this.usernameRef = node} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<TextField
|
||||
label="Passwort"
|
||||
type="password"
|
||||
inputRef={node => this.passwordRef = node} />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="login-btn"
|
||||
onClick={() => this.performLogin()}>
|
||||
Login
|
||||
</Button>
|
||||
{
|
||||
this.props.loading ? (
|
||||
<LinearProgress />
|
||||
) : undefined
|
||||
}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Snackbar
|
||||
open={this.props.snackOpen}
|
||||
onClose={() => this.props.setSnackbar(false, "")}
|
||||
message={this.props.snackMsg}
|
||||
autoHideDuration={6000} />
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
export default LoginPageWithRouter;
|
||||
|
||||
@@ -73,30 +73,23 @@ const ReviewPageWithRouter = withRouter(
|
||||
|
||||
// Get the correct vocabulary
|
||||
const { reviewType, vocabByLevel, levelId, vocabByQueue } = this.props;
|
||||
switch (reviewType) {
|
||||
case ReviewType.LEVEL:
|
||||
if (!vocabByLevel || !levelId) {
|
||||
alert("[ReviewPage::constructor] vocabByLevel or levelId undefined");
|
||||
} else {
|
||||
vocabByLevel(levelId).then(res => {
|
||||
this.vocab = res;
|
||||
vocToQueue();
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ReviewType.QUEUE:
|
||||
if (!vocabByQueue) {
|
||||
alert("[ReviewPage::constructor] vocabByQueue undefined");
|
||||
} else {
|
||||
vocabByQueue().then(res => {
|
||||
this.vocab = res;
|
||||
vocToQueue();
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// Just to make TSC shut up
|
||||
const noopPromise = () => {
|
||||
return new Promise<IVocab[]>((res, rej) => {
|
||||
rej([]);
|
||||
});
|
||||
};
|
||||
const vocabByLevelW = vocabByLevel || noopPromise;
|
||||
const vocabByQueueW = vocabByQueue || noopPromise;
|
||||
const getVocab = {
|
||||
[ReviewType.LEVEL]: () => vocabByLevelW(levelId),
|
||||
[ReviewType.QUEUE]: () => vocabByQueueW(),
|
||||
}[reviewType];
|
||||
getVocab().then((res: IVocab[]) => {
|
||||
this.vocab = res;
|
||||
vocToQueue();
|
||||
});
|
||||
}
|
||||
|
||||
increaseMeta = (correct: number, wrong: number): IReviewMetadata => {
|
||||
|
||||
Reference in New Issue
Block a user