2018-09-06 18:05:21 +00:00
|
|
|
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 Typography from "@material-ui/core/Typography";
|
2018-09-18 18:20:26 +00:00
|
|
|
import Paper from "@material-ui/core/Paper";
|
|
|
|
import Grid from "@material-ui/core/Grid";
|
2018-09-06 18:05:21 +00:00
|
|
|
import Card from "@material-ui/core/Card";
|
|
|
|
import CardContent from "@material-ui/core/CardContent";
|
2018-09-18 18:20:26 +00:00
|
|
|
import CircularProgress from "@material-ui/core/CircularProgress";
|
2018-09-06 18:05:21 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
import { withRouter } from "react-router-dom";
|
2018-09-12 13:15:55 +00:00
|
|
|
|
2018-09-06 18:05:21 +00:00
|
|
|
import { IVocab } from "../models/vocab";
|
|
|
|
|
|
|
|
interface IProps {
|
|
|
|
id: string;
|
2018-09-18 18:20:26 +00:00
|
|
|
levelVocab: (id: string) => Promise<IVocab[]>;
|
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
history: any;
|
|
|
|
|
2018-09-18 18:20:26 +00:00
|
|
|
loading: boolean;
|
|
|
|
setLoading: (state: boolean) => void;
|
|
|
|
vocab: IVocab[];
|
|
|
|
setVocab: (vocab: IVocab[]) => void;
|
|
|
|
setLookedAt: (ids: number[]) => void;
|
|
|
|
setCurrentVocab: (vocab: IVocab) => void;
|
2018-09-15 12:26:22 +00:00
|
|
|
drawerButtonState: (state: boolean) => void;
|
2018-09-06 18:05:21 +00:00
|
|
|
currentVocab: IVocab;
|
|
|
|
lookedAt: number[];
|
|
|
|
};
|
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
const LevelPageWithRouter = withRouter(
|
|
|
|
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 } = {};
|
2018-09-06 18:05:21 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
componentDidMount() {
|
|
|
|
// Hide the drawer
|
|
|
|
this.props.drawerButtonState(false);
|
2018-09-15 12:26:22 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
// Fetch the vocabulary
|
|
|
|
this.props.setLoading(true);
|
2018-09-18 18:20:26 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
// TODO: Error handling
|
|
|
|
this.props.levelVocab(this.props.id).then(vocab => {
|
|
|
|
this.props.setVocab(vocab);
|
|
|
|
this.props.setCurrentVocab(vocab[0]);
|
|
|
|
this.props.setLoading(false);
|
|
|
|
});
|
2018-09-18 18:20:26 +00:00
|
|
|
|
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
}
|
2018-09-06 18:05:21 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
genUID = (vocab: IVocab): string => {
|
|
|
|
const { grundform } = vocab.latin;
|
|
|
|
if (grundform in this.uids) {
|
|
|
|
return this.uids[grundform];
|
|
|
|
} else {
|
|
|
|
this.uids[grundform] = "LEVELPAGE" + this.uid++;
|
|
|
|
return this.uids[grundform];
|
|
|
|
}
|
2018-09-14 14:13:42 +00:00
|
|
|
}
|
2018-09-06 18:05:21 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
renderVocabListItem = (vocab: IVocab): any => {
|
|
|
|
// Check if the vocab was already looked at
|
|
|
|
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.props.setCurrentVocab(vocab);
|
|
|
|
this.props.setLookedAt(lookedAt ? (
|
|
|
|
this.props.lookedAt
|
|
|
|
) : this.props.lookedAt.concat(vocab.id));
|
|
|
|
}}>
|
|
|
|
<ListItemText>
|
|
|
|
{`${vocab.latin.grundform} ${lookedAt ? "✔" : ""}`}
|
|
|
|
</ListItemText>
|
|
|
|
</ListItem>;
|
|
|
|
}
|
2018-09-06 18:05:21 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
toReview = () => {
|
|
|
|
const { vocab, lookedAt, id } = this.props;
|
|
|
|
// Only go to the review if all vocabulary item have been looked at
|
|
|
|
if (vocab.length === lookedAt.length) {
|
|
|
|
this.props.setLoading(true);
|
|
|
|
this.props.history.push(`/review/level/${id}`);
|
|
|
|
}
|
2018-09-12 17:23:00 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
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>
|
2018-09-18 18:20:26 +00:00
|
|
|
</Grid>
|
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
</div>;
|
|
|
|
}
|
2018-09-06 18:05:21 +00:00
|
|
|
|
2018-09-19 18:30:42 +00:00
|
|
|
const { currentVocab } = this.props;
|
|
|
|
return <div>
|
|
|
|
<Grid container direction="row">
|
|
|
|
<Grid item xs={3}>
|
|
|
|
<List>
|
|
|
|
{this.props.vocab
|
|
|
|
.map(this.renderVocabListItem)}
|
|
|
|
<ListItem button onClick={this.toReview}>
|
|
|
|
<ListItemText>
|
|
|
|
Zur Übung
|
2018-09-06 18:05:21 +00:00
|
|
|
</ListItemText>
|
2018-09-19 18:30:42 +00:00
|
|
|
</ListItem>
|
|
|
|
</List>
|
|
|
|
</Grid>
|
|
|
|
<Grid item lg={7} xs={9}>
|
|
|
|
<Grid container direction="column">
|
|
|
|
<Grid item style={{ margin: 12 }}>
|
|
|
|
<Card>
|
|
|
|
<CardContent>
|
|
|
|
<Typography gutterBottom variant="headline" component="h2">
|
|
|
|
{currentVocab.latin.grundform}
|
|
|
|
</Typography>
|
|
|
|
<Typography gutterBottom variant="headline" component="h3">
|
|
|
|
{currentVocab.german.join(", ")}
|
|
|
|
</Typography>
|
|
|
|
{
|
|
|
|
currentVocab.hint ? (
|
|
|
|
<div style={{
|
|
|
|
border: "dashed",
|
|
|
|
borderColor: "red",
|
|
|
|
padding: 12,
|
|
|
|
}}>
|
|
|
|
<Typography variant="subheading" component="p">
|
|
|
|
<b>Tipp:</b>
|
|
|
|
</Typography>
|
|
|
|
<Typography variant="body2">
|
|
|
|
{currentVocab.hint}
|
|
|
|
</Typography>
|
|
|
|
</div>
|
|
|
|
) : undefined
|
|
|
|
}
|
|
|
|
{
|
|
|
|
currentVocab.mnemonic ? (
|
|
|
|
<div style={{
|
|
|
|
border: "dashed",
|
|
|
|
borderColor: "#f1c40f",
|
|
|
|
marginTop: 12,
|
|
|
|
padding: 12,
|
|
|
|
}}>
|
|
|
|
<Typography variant="subheading" component="p">
|
|
|
|
<b>Eselsbrücke:</b>
|
|
|
|
</Typography>
|
|
|
|
<Typography variant="body2">
|
|
|
|
{currentVocab.mnemonic}
|
|
|
|
</Typography>
|
|
|
|
</div>
|
|
|
|
) : undefined
|
|
|
|
}
|
|
|
|
</CardContent>
|
|
|
|
{/*TODO: Maybe "next" and "prev" buttons?*/}
|
|
|
|
</Card>
|
|
|
|
</Grid>
|
2018-09-06 18:05:21 +00:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
2018-09-19 18:30:42 +00:00
|
|
|
</div>;
|
|
|
|
}
|
2018-09-06 18:05:21 +00:00
|
|
|
}
|
2018-09-19 18:30:42 +00:00
|
|
|
);
|
|
|
|
export default LevelPageWithRouter;
|