refactor: Move the LevelPage to Redux
This commit is contained in:
@@ -5,8 +5,11 @@ 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";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
|
||||
import { Redirect } from "react-router-dom";
|
||||
|
||||
@@ -14,35 +17,42 @@ import { IVocab } from "../models/vocab";
|
||||
|
||||
interface IProps {
|
||||
id: string;
|
||||
levelVocab: (id: string) => Promise<IVocab[]>;
|
||||
|
||||
levelVocab: (id: string) => IVocab[];
|
||||
|
||||
loading: boolean;
|
||||
setLoading: (state: boolean) => void;
|
||||
vocab: IVocab[];
|
||||
setVocab: (vocab: IVocab[]) => void;
|
||||
setLookedAt: (ids: number[]) => void;
|
||||
setCurrentVocab: (vocab: IVocab) => void;
|
||||
setReview: (state: boolean) => void;
|
||||
drawerButtonState: (state: boolean) => void;
|
||||
};
|
||||
|
||||
interface IState {
|
||||
currentVocab: IVocab;
|
||||
lookedAt: number[];
|
||||
toReview: boolean;
|
||||
};
|
||||
|
||||
export default class LevelPage extends React.Component<IProps, IState> {
|
||||
export default class LevelPage extends React.Component<IProps> {
|
||||
private uid = 0;
|
||||
// To prevent React from redrawing the vocabulary list and prematurely
|
||||
// cancelling the animation
|
||||
private uids: { [key: string]: string } = {};
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
|
||||
componentDidMount() {
|
||||
// Hide the drawer
|
||||
this.props.drawerButtonState(false);
|
||||
|
||||
this.state = {
|
||||
currentVocab: this.props.levelVocab(this.props.id)[0],
|
||||
lookedAt: [0],
|
||||
toReview: false,
|
||||
};
|
||||
// Fetch the vocabulary
|
||||
this.props.setLoading(true);
|
||||
|
||||
// TODO: Error handling
|
||||
this.props.levelVocab(this.props.id).then(vocab => {
|
||||
this.props.setVocab(vocab);
|
||||
this.props.setCurrentVocab(vocab[0]);
|
||||
this.props.setLoading(false);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
genUID = (vocab: IVocab): string => {
|
||||
@@ -57,16 +67,16 @@ export default class LevelPage extends React.Component<IProps, IState> {
|
||||
|
||||
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;
|
||||
const lookedAt = this.props.lookedAt.find((el) => el === vocab.id) || vocab.id === 0;
|
||||
|
||||
return <ListItem button key={this.genUID(vocab)} onClick={() => {
|
||||
// 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: lookedAt ? this.state.lookedAt : this.state.lookedAt.concat(vocab.id),
|
||||
});
|
||||
this.props.setCurrentVocab(vocab);
|
||||
this.props.setLookedAt(lookedAt ? (
|
||||
this.props.lookedAt
|
||||
) : this.props.lookedAt.concat(vocab.id));
|
||||
}}>
|
||||
<ListItemText>
|
||||
{`${vocab.latin.grundform} ${lookedAt ? "✔" : ""}`}
|
||||
@@ -75,23 +85,52 @@ export default class LevelPage extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
toReview = () => {
|
||||
const { levelVocab, id } = this.props;
|
||||
const { vocab, lookedAt } = this.props;
|
||||
// Only go to the review if all vocabulary item have been looked at
|
||||
if (levelVocab(id).length === this.state.lookedAt.length) {
|
||||
this.setState({
|
||||
toReview: true,
|
||||
});
|
||||
if (vocab.length === lookedAt.length) {
|
||||
this.props.setReview(true);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { currentVocab } = this.state;
|
||||
if (this.props.loading) {
|
||||
return <div>
|
||||
{/*
|
||||
* This would be the case when the user presses the "to
|
||||
* review" button. That is because we need the state of loading
|
||||
* to be true, when this page gets called
|
||||
* TODO:?
|
||||
*/}
|
||||
{
|
||||
this.props.toReview ? (
|
||||
<Redirect to={`/review/level/${this.props.id}`} />
|
||||
) : undefined
|
||||
}
|
||||
<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 { currentVocab } = this.props;
|
||||
return <div>
|
||||
<Grid container direction="row">
|
||||
<Grid item xs={3}>
|
||||
<List>
|
||||
{this.props.levelVocab(this.props.id)
|
||||
{this.props.vocab
|
||||
.map(this.renderVocabListItem)}
|
||||
{/* TODO*/}
|
||||
<ListItem button onClick={this.toReview}>
|
||||
@@ -102,7 +141,7 @@ export default class LevelPage extends React.Component<IProps, IState> {
|
||||
</List>
|
||||
</Grid>
|
||||
{
|
||||
this.state.toReview ? (
|
||||
this.props.toReview ? (
|
||||
<Redirect to={`/review/level/${this.props.id}`} />
|
||||
) : undefined
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user