feat: Rework the Level UI
This commit is contained in:
@@ -1,14 +1,20 @@
|
||||
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";
|
||||
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 MobileStepper from '@material-ui/core/MobileStepper';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
|
||||
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import Dialog from "@material-ui/core/Dialog";
|
||||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogContentText from "@material-ui/core/DialogContentText";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
@@ -22,15 +28,21 @@ interface IProps {
|
||||
|
||||
history: any;
|
||||
|
||||
stepperIndex: number;
|
||||
loading: boolean;
|
||||
setLoading: (state: boolean) => void;
|
||||
vocab: IVocab[];
|
||||
lookedAt: number[];
|
||||
currentVocab: IVocab;
|
||||
leaveDialog: boolean;
|
||||
reviewDialog: boolean;
|
||||
setVocab: (vocab: IVocab[]) => void;
|
||||
setLookedAt: (ids: number[]) => void;
|
||||
setCurrentVocab: (vocab: IVocab) => void;
|
||||
drawerButtonState: (state: boolean) => void;
|
||||
currentVocab: IVocab;
|
||||
lookedAt: number[];
|
||||
setLoading: (state: boolean) => void;
|
||||
setStepper: (index: number) => void;
|
||||
setReviewDialog: (state: boolean) => void;
|
||||
setLeaveDialog: (state: boolean) => void;
|
||||
};
|
||||
|
||||
const LevelPageWithRouter = withRouter(
|
||||
@@ -52,10 +64,9 @@ const LevelPageWithRouter = withRouter(
|
||||
this.props.setVocab(vocab);
|
||||
this.props.setCurrentVocab(vocab[0]);
|
||||
this.props.setLookedAt([vocab[0].id]);
|
||||
this.props.setStepper(0);
|
||||
this.props.setLoading(false);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
genUID = (vocab: IVocab): string => {
|
||||
@@ -68,32 +79,61 @@ const LevelPageWithRouter = withRouter(
|
||||
}
|
||||
}
|
||||
|
||||
renderVocabListItem = (vocab: IVocab): any => {
|
||||
// Check if the vocab was already looked at
|
||||
const lookedAt = this.props.lookedAt.find((el) => el === vocab.id);
|
||||
|
||||
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>;
|
||||
toReview = () => {
|
||||
this.props.setLoading(true);
|
||||
this.props.setStepper(0);
|
||||
this.props.history.push(`/review/level/${this.props.id}`);
|
||||
}
|
||||
|
||||
toReview = () => {
|
||||
const { vocab, lookedAt, id } = this.props;
|
||||
openReview = () => {
|
||||
this.props.setReviewDialog(true);
|
||||
}
|
||||
closeReview = () => {
|
||||
this.props.setReviewDialog(false);
|
||||
}
|
||||
|
||||
// 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}`);
|
||||
openLeave = () => {
|
||||
this.props.setLeaveDialog(true);
|
||||
}
|
||||
closeLeave = () => {
|
||||
this.props.setLeaveDialog(false);
|
||||
}
|
||||
|
||||
cancelLevel = () => {
|
||||
this.closeLeave();
|
||||
this.props.history.push("/dashboard");
|
||||
}
|
||||
|
||||
nextVocab = () => {
|
||||
// Get the next vocab item
|
||||
const { stepperIndex, vocab } = this.props;
|
||||
|
||||
// When we are about to go out of bounds, then we want to
|
||||
// ask whether the user wants to review
|
||||
if (stepperIndex + 1 >= vocab.length) {
|
||||
this.openReview();
|
||||
} else {
|
||||
const newVocab = vocab[stepperIndex + 1];
|
||||
|
||||
// Set the stepperIndex and the currentVocab
|
||||
this.props.setStepper(stepperIndex + 1);
|
||||
this.props.setCurrentVocab(newVocab);
|
||||
}
|
||||
}
|
||||
|
||||
prevVocab = () => {
|
||||
// Get the next vocab item
|
||||
const { stepperIndex, vocab } = this.props;
|
||||
|
||||
// Prevent going out of bounds
|
||||
if (stepperIndex - 1 < 0) {
|
||||
this.openLeave();
|
||||
} else {
|
||||
const newVocab = vocab[stepperIndex - 1];
|
||||
|
||||
// Set the stepperIndex and the currentVocab
|
||||
this.props.setStepper(stepperIndex - 1);
|
||||
this.props.setCurrentVocab(newVocab);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,25 +165,15 @@ const LevelPageWithRouter = withRouter(
|
||||
[VocabType.ADJEKTIV]: "Adjektiv",
|
||||
[VocabType.ADVERB]: "Adverb",
|
||||
};
|
||||
|
||||
const { currentVocab } = this.props;
|
||||
const { currentVocab, vocab, stepperIndex } = 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
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Grid>
|
||||
<Grid item lg={7} xs={9}>
|
||||
<Grid container justify="center">
|
||||
<Grid item>
|
||||
<Grid container direction="column">
|
||||
<Grid item style={{ margin: 12 }}>
|
||||
<Card>
|
||||
<Grid item className="level-card">
|
||||
<Card
|
||||
square={true}
|
||||
style={{ margin: 12 }}>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="headline" component="h2">
|
||||
{`${currentVocab.latin.grundform} (${vocabTypeToStr[currentVocab.type]})`}
|
||||
@@ -153,8 +183,72 @@ const LevelPageWithRouter = withRouter(
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
<MobileStepper
|
||||
steps={vocab.length + 1}
|
||||
position="static"
|
||||
activeStep={stepperIndex}
|
||||
className="level-stepper"
|
||||
nextButton={
|
||||
<Button
|
||||
onClick={this.nextVocab}
|
||||
disabled={stepperIndex >= vocab.length + 1}>
|
||||
<KeyboardArrowRight />
|
||||
Nächste
|
||||
</Button>
|
||||
}
|
||||
backButton={
|
||||
<Button onClick={this.prevVocab}>
|
||||
<KeyboardArrowLeft />
|
||||
{
|
||||
stepperIndex === 0 ? (
|
||||
`Abbrechen`
|
||||
) : (
|
||||
`Zurück`
|
||||
)
|
||||
}
|
||||
</Button>
|
||||
} />
|
||||
|
||||
{/*The leave and the "to review" dialog*/}
|
||||
<Dialog
|
||||
open={this.props.reviewDialog}
|
||||
onClose={this.closeReview}>
|
||||
<DialogTitle>Willst du zur Übung?</DialogTitle>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={this.toReview}>
|
||||
Zur Übung
|
||||
</Button>
|
||||
<Button
|
||||
onClick={this.closeReview}>
|
||||
Noch nicht
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
open={this.props.leaveDialog}
|
||||
onClose={this.closeLeave}>
|
||||
<DialogTitle>Willst du das Level abbrechen?</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
Wenn du jetzt abbricht, dann geht dein Fortschritt
|
||||
in diesem Level verloren.
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={this.closeLeave}>
|
||||
Zurück zum Level
|
||||
</Button>
|
||||
<Button
|
||||
onClick={this.cancelLevel}>
|
||||
Level abbrechen
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user