feat: Implement a scoreboard

This commit is contained in:
Alexander Polynomdivision 2018-08-26 17:12:07 +02:00
parent 4e1ab04d29
commit 0ff53d12f7
4 changed files with 129 additions and 35 deletions

View File

@ -31,6 +31,7 @@ export default class Application extends React.Component<{}, IState> {
}
lessons(): ILesson[] {
// TODO: Actually fetch them from somewhere
const lessons = [{
name: "Der Bauer auf dem Feld",
desc: "So fängt alles an: Du bist ein einfacher Bauer und musst dich die Karriereleiter mit deinen freshen Latein-Skills hinaufarbeiten",
@ -46,6 +47,22 @@ export default class Application extends React.Component<{}, IState> {
return lessons;
}
learners(): ILearner[] {
return [{
username: "Polynomdivision",
level: 5,
score: 400,
}, {
username: "Polynomdivision2",
level: 3,
score: 500,
}, {
username: "Der eine Typ",
level: 7,
score: 100,
}];
}
login(username: string, password: string): Promise<boolean> {
return new Promise((res, rej) => {
// TODO
@ -79,8 +96,14 @@ export default class Application extends React.Component<{}, IState> {
<Route exact path="/login" component={() => {
return <LoginPage loggedIn={this.state.loggedIn} login={this.login} />
}} />
<AuthRoute isAuth={this.isAuthenticated} path="/dashboard" component={() => <Dashboard lessons={this.lessons()} />} />
<AuthRoute isAuth={this.isAuthenticated} path="/lessons" component={() => <LessonsPage lessons={this.lessons()} />} />
<AuthRoute
isAuth={this.isAuthenticated}
path="/dashboard"
component={() => <Dashboard lessons={this.lessons()} learners={this.learners()} />} />
<AuthRoute
isAuth={this.isAuthenticated}
path="/lessons"
component={() => <LessonsPage lessons={this.lessons()} />} />
</div>
</div>
</BrowserRouter>;

View File

@ -0,0 +1,73 @@
import * as React from "react";
import Table from "@material-ui/core/Table";
import TableHead from "@material-ui/core/TableHead";
import TableBody from "@material-ui/core/TableBody";
import TableRow from "@material-ui/core/TableRow";
import TableCell from "@material-ui/core/TableCell";
import Typography from "@material-ui/core/Typography";
import { ILearner } from "../models/learner";
interface IProps {
learners: ILearner[];
}
export default class Scoreboard extends React.Component<{}> {
private unique = 0;
private nr = 1;
constructor(props: any) {
super(props);
this.genId = this.genId.bind(this);
this.tableRow = this.tableRow.bind(this);
}
genId() {
return "SCOREBOARD" + this.unique++;
}
tableRow(learner: ILearner) {
return <TableRow key={this.genId()}>
<TableCell>
<Typography variant="title" component="b">
{this.nr++}
</Typography>
</TableCell>
<TableCell>
<Typography component="b">{learner.username}</Typography>
</TableCell>
{/*<TableCell numeric>{learner.level}</TableCell>*/}
{/* To make this fit on both mobile and desktop, we don't use
numeric, as it would otherwise look weir otherwise look weird */}
<TableCell>{learner.score}</TableCell>
</TableRow>
}
render() {
const sortedLearners = this.props.learners.sort((a, b) => {
if (a.score > b.score) {
return -1;
} else if (a.score < b.score) {
return 1;
}
return 0;
});
return <Table padding="none">
<TableHead>
<TableRow>
<TableCell>#</TableCell>
<TableCell>User</TableCell>
{/*<TableCell>Level</TableCell>*/}
<TableCell>Punktzahl</TableCell>
</TableRow>
</TableHead>
<TableBody>
{sortedLearners.map(this.tableRow)}
</TableBody>
</Table>;
}
}

5
src/models/learner.ts Normal file
View File

@ -0,0 +1,5 @@
export interface ILearner {
username: string;
level: number;
score: number;
}

View File

@ -3,50 +3,43 @@ import * as React from "react";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
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 Scoreboard from "../components/scoreboard";
import { ILesson } from "../models/lesson";
import { ILearner } from "../models/learner";
interface IProps {
lessons: ILesson[];
learners: ILearner[];
}
export default class Dashboard extends React.Component<{}> {
constructor(props: any) {
super(props);
}
render() {
const small = window.matchMedia("(max-width: 700px)").matches;
const cName = small ? "lesson-card-xs" : "lesson-card-lg";
const direction = small ? "column" : "row";
let key = 0;
const lessonToCard = (lesson: ILesson) => {
return <Grid item key={key++}>
<Card style={{
width: small ? window.width - 32 : "300px"
}}>
<CardContent className={cName}>
<Typography variant="title">{`Level ${lesson.level}`}</Typography>
<Typography variant="title" component="p">{lesson.name}</Typography>
<br />
<Typography component="p">
{lesson.desc}
</Typography>
</CardContent>
<CardActions>
<Button className="lesson-card-btn">
Zum Level
</Button>
</CardActions>
</Card>
</Grid>;
};
return <Grid container spacing={16} direction="row">
{this.props.lessons.map(lessonToCard)}
return <Grid container direction={direction} spacing={16}>
<Grid item lg={4}>
<Paper className="paper">
N&auml;chstes Level
</Paper>
</Grid>
<Grid item lg={4}>
<Paper className="paper">
<Typography variant="title" component="p">
Rangliste
</Typography>
<Scoreboard learners={this.props.learners} />
</Paper>
</Grid>
<Grid item lg={4}>
<Paper className="paper">
Some stuff
</Paper>
</Grid>
</Grid>;
}
};