feat: Implement a scoreboard
This commit is contained in:
parent
4e1ab04d29
commit
0ff53d12f7
@ -31,6 +31,7 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lessons(): ILesson[] {
|
lessons(): ILesson[] {
|
||||||
|
// TODO: Actually fetch them from somewhere
|
||||||
const lessons = [{
|
const lessons = [{
|
||||||
name: "Der Bauer auf dem Feld",
|
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",
|
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;
|
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> {
|
login(username: string, password: string): Promise<boolean> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
// TODO
|
// TODO
|
||||||
@ -79,8 +96,14 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
<Route exact path="/login" component={() => {
|
<Route exact path="/login" component={() => {
|
||||||
return <LoginPage loggedIn={this.state.loggedIn} login={this.login} />
|
return <LoginPage loggedIn={this.state.loggedIn} login={this.login} />
|
||||||
}} />
|
}} />
|
||||||
<AuthRoute isAuth={this.isAuthenticated} path="/dashboard" component={() => <Dashboard lessons={this.lessons()} />} />
|
<AuthRoute
|
||||||
<AuthRoute isAuth={this.isAuthenticated} path="/lessons" component={() => <LessonsPage lessons={this.lessons()} />} />
|
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>
|
||||||
</div>
|
</div>
|
||||||
</BrowserRouter>;
|
</BrowserRouter>;
|
||||||
|
73
src/components/scoreboard.tsx
Normal file
73
src/components/scoreboard.tsx
Normal 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
5
src/models/learner.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface ILearner {
|
||||||
|
username: string;
|
||||||
|
level: number;
|
||||||
|
score: number;
|
||||||
|
}
|
@ -3,50 +3,43 @@ import * as React from "react";
|
|||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import Card from '@material-ui/core/Card';
|
import Paper from "@material-ui/core/Paper";
|
||||||
import CardActions from '@material-ui/core/CardActions';
|
|
||||||
import CardContent from '@material-ui/core/CardContent';
|
import Scoreboard from "../components/scoreboard";
|
||||||
|
|
||||||
import { ILesson } from "../models/lesson";
|
import { ILesson } from "../models/lesson";
|
||||||
|
import { ILearner } from "../models/learner";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
lessons: ILesson[];
|
lessons: ILesson[];
|
||||||
|
learners: ILearner[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Dashboard extends React.Component<{}> {
|
export default class Dashboard extends React.Component<{}> {
|
||||||
constructor(props: any) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const small = window.matchMedia("(max-width: 700px)").matches;
|
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;
|
return <Grid container direction={direction} spacing={16}>
|
||||||
const lessonToCard = (lesson: ILesson) => {
|
<Grid item lg={4}>
|
||||||
return <Grid item key={key++}>
|
<Paper className="paper">
|
||||||
<Card style={{
|
Nächstes Level
|
||||||
width: small ? window.width - 32 : "300px"
|
</Paper>
|
||||||
}}>
|
</Grid>
|
||||||
<CardContent className={cName}>
|
<Grid item lg={4}>
|
||||||
<Typography variant="title">{`Level ${lesson.level}`}</Typography>
|
<Paper className="paper">
|
||||||
<Typography variant="title" component="p">{lesson.name}</Typography>
|
<Typography variant="title" component="p">
|
||||||
<br />
|
Rangliste
|
||||||
<Typography component="p">
|
</Typography>
|
||||||
{lesson.desc}
|
|
||||||
</Typography>
|
|
||||||
</CardContent>
|
|
||||||
<CardActions>
|
|
||||||
<Button className="lesson-card-btn">
|
|
||||||
Zum Level
|
|
||||||
</Button>
|
|
||||||
</CardActions>
|
|
||||||
</Card>
|
|
||||||
</Grid>;
|
|
||||||
};
|
|
||||||
|
|
||||||
return <Grid container spacing={16} direction="row">
|
<Scoreboard learners={this.props.learners} />
|
||||||
{this.props.lessons.map(lessonToCard)}
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item lg={4}>
|
||||||
|
<Paper className="paper">
|
||||||
|
Some stuff
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Grid>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user