feat: Prevent users from starting levels that they did not reach yet
This commit is contained in:
@@ -7,9 +7,11 @@ 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 Snackbar from "@material-ui/core/Snackbar";
|
||||
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
|
||||
import { Link } from "react-router-dom";
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
import { ILevel } from "../models/level";
|
||||
import { IUser } from "../models/user";
|
||||
@@ -17,77 +19,102 @@ import { IUser } from "../models/user";
|
||||
interface IProps {
|
||||
getLevels: () => Promise<ILevel[]>;
|
||||
|
||||
history: any;
|
||||
|
||||
user: IUser;
|
||||
setLevels: (levels: ILevel[]) => void;
|
||||
setLoading: (state: boolean) => void;
|
||||
loading: boolean;
|
||||
snackbar: boolean;
|
||||
setSnackbar: (state: boolean) => void;
|
||||
levels: ILevel[];
|
||||
}
|
||||
|
||||
export default class Dashboard extends React.Component<IProps> {
|
||||
componentDidMount() {
|
||||
this.props.setLoading(true);
|
||||
const LevelListWithRouter = withRouter(
|
||||
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>;
|
||||
// Fetch the levels
|
||||
this.props.getLevels().then(res => {
|
||||
this.props.setLevels(res);
|
||||
this.props.setLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
const small = window.matchMedia("(max-width: 700px)").matches;
|
||||
const cName = small ? "lesson-card-xs" : "lesson-card-lg";
|
||||
toLevel(id: number) {
|
||||
const maxLevel = Math.max(...this.props.user.levels);
|
||||
if (maxLevel + 1 >= id) {
|
||||
this.props.history.push(`/level/${id}`);
|
||||
} else {
|
||||
this.props.setSnackbar(true);
|
||||
}
|
||||
}
|
||||
|
||||
let key = 0;
|
||||
const levelToCard = (level: ILevel) => {
|
||||
const suffix = level.level in this.props.user.levels ? " ✔" : "";
|
||||
return <Grid item key={key++}>
|
||||
<Card style={{
|
||||
width: small ? window.width - 32 : "300px"
|
||||
}}>
|
||||
<CardContent className={cName}>
|
||||
<Typography variant="title">{`Level ${level.level}${suffix}`}</Typography>
|
||||
<Typography variant="title" component="p">{level.name}</Typography>
|
||||
<br />
|
||||
<Typography component="p">
|
||||
{level.description}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button
|
||||
component={Link}
|
||||
to={`/level/${level.level}`}
|
||||
className="lesson-card-btn">
|
||||
Zum Level
|
||||
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";
|
||||
|
||||
let key = 0;
|
||||
const levelToCard = (level: ILevel) => {
|
||||
const suffix = level.level in this.props.user.levels ? " ✔" : "";
|
||||
return <Grid item key={key++}>
|
||||
<Card style={{
|
||||
width: small ? window.width - 32 : "300px"
|
||||
}}>
|
||||
<CardContent className={cName}>
|
||||
<Typography variant="title">{`Level ${level.level}${suffix}`}</Typography>
|
||||
<Typography variant="title" component="p">{level.name}</Typography>
|
||||
<br />
|
||||
<Typography component="p">
|
||||
{level.description}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button
|
||||
className="lesson-card-btn"
|
||||
onClick={() => this.toLevel(level.level)}>
|
||||
Zum Level
|
||||
</Button>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</Grid>;
|
||||
};
|
||||
</CardActions>
|
||||
</Card>
|
||||
</Grid>;
|
||||
};
|
||||
|
||||
return <Grid container spacing={16} direction="row">
|
||||
{this.props.levels.map(levelToCard)}
|
||||
</Grid>
|
||||
return <div>
|
||||
<Grid container spacing={16} direction="row">
|
||||
{this.props.levels.map(levelToCard)}
|
||||
</Grid>
|
||||
<Snackbar
|
||||
anchorOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
open={this.props.snackbar}
|
||||
onClose={() => this.props.setSnackbar(false)}
|
||||
message={<span>Du hast dieses Level noch nicht freigeschaltet!</span>} />
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
export default LevelListWithRouter;
|
||||
|
||||
Reference in New Issue
Block a user