fix: Implement more APIs

This commit is contained in:
Alexander Polynomdivision 2018-09-24 13:36:42 +02:00
parent 11bbdc627f
commit 8b6bfb681b
9 changed files with 117 additions and 46 deletions

View File

@ -49,7 +49,10 @@ userRouter.get("/lastReview", async (req, res) => {
// TODO: Stub
res.send({
error: "0",
data: {},
data: {
correct: 6,
wrong: 2,
},
});
});
userRouter.post("/lastReview", async (req, res) => {

View File

@ -44,6 +44,26 @@ app.use((req, res, next) => {
app.use("/api/level", LevelRouter);
app.use("/api/class", ClassRouter);
app.use("/api/user", UserRouter);
app.get("/api/levels", async (req, res) => {
const levels = [{
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",
level: 1,
done: true,
}, {
name: "???",
desc: "Warum schreibe ich überhaupt was?dsd dddddddddddddddddddddd",
level: 2,
done: false,
}];
res.send({
error: "0",
data: {
levels,
},
});
});
app.get("/api/health", (req, res) => {
res.send({
error: "0",

View File

@ -184,3 +184,11 @@ export function setDidLogin(state: boolean) {
state,
};
};
export const DASHBOARD_SET_LR_LOADING = "DASHBOARD_SET_LR_LOADING";
export function setDashboardLRLoading(state: boolean) {
return {
type: DASHBOARD_SET_LR_LOADING,
state,
};
};

View File

@ -9,12 +9,12 @@ import TableCell from "@material-ui/core/TableCell";
import { IReviewMetadata } from "../models/review";
interface IProps {
reviewMeta: () => IReviewMetadata;
reviewMeta: IReviewMetadata;
}
export default class SummaryTable extends React.Component<IProps> {
render() {
const meta = this.props.reviewMeta();
const { reviewMeta } = this.props;
return <Table>
<TableHead>
@ -26,11 +26,11 @@ export default class SummaryTable extends React.Component<IProps> {
<TableBody>
<TableRow>
<TableCell>Korrekt</TableCell>
<TableCell numeric>{meta.correct}</TableCell>
<TableCell numeric>{reviewMeta.correct}</TableCell>
</TableRow>
<TableRow>
<TableCell>Falsch</TableCell>
<TableCell numeric>{meta.wrong}</TableCell>
<TableCell numeric>{reviewMeta.wrong}</TableCell>
</TableRow>
</TableBody>
</Table>;

View File

@ -45,45 +45,49 @@ export default class Application extends React.Component<IProps> {
}
}
getLevels(): Promise<ILevel[]> {
console.log("STUB: Application::getLevels");
getLevels = (): Promise<ILevel[]> => {
return new Promise((res, rej) => {
// TODO: Actually fetch them from somewhere
setTimeout(() => {
const levels = [{
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",
level: 1,
done: true,
}, {
name: "???",
desc: "Warum schreibe ich überhaupt was?dsd dddddddddddddddddddddd",
level: 2,
done: false,
}];
res(levels);
}, 2000);
fetch(`${BACKEND_URL}/api/levels`, {
headers: new Headers({
"Content-Type": "application/json",
"Token": this.props.user.sessionToken,
}),
}).then(resp => resp.json(), err => rej(err))
.then(data => {
if (data.error === "0") {
res(data.data.levels);
} else {
rej(data);
}
});
});
}
getLastReview = (): IReviewMetadata => {
console.log("STUB: Application::getLastReview");
// TODO: Actually fetch this
// TODO: Stub
return {} as IReviewMetadata;
getLastReview = (): Promise<IReviewMetadata> => {
return new Promise((res, rej) => {
fetch(`${BACKEND_URL}/api/user/lastReview`, {
headers: new Headers({
"Content-Type": "application/json",
"Token": this.props.user.sessionToken,
}),
}).then(resp => resp.json(), err => rej(err))
.then(data => {
if (data.error === "0") {
res(data.data);
} else {
rej(data);
}
});
});
}
setLastReview = (meta: IReviewMetadata) => {
console.log("STUB: Application::setLastReview");
// TODO: Send this to the server
this.setState({
lastReview: meta,
});
/* this.setState({
* lastReview: meta,
* }); */
}
getReviewQueue = (): Promise<IVocab[]> => {

View File

@ -1,8 +1,13 @@
import { connect } from "react-redux";
import { setNextLevel, setDashboardNLLoading, setTopTen, setDashboardTTLoading } from "../actions";
import {
setNextLevel, setDashboardNLLoading, setTopTen, setDashboardTTLoading,
setDashboardLRLoading, setLastReview,
} from "../actions";
import { ILevel } from "../models/level";
import { ILearner } from "../models/learner";
import { IReviewMetadata } from "../models/review";
import DashboardPage from "../pages/dashboard";
@ -12,6 +17,8 @@ const mapStateToProps = state => {
loadingNextLevel: state.dashboard.loadingNL,
loadingTopTen: state.dashboard.loadingTT,
topTen: state.topTen,
loadingLastReview: state.dashboard.loadingLR,
lastReview: state.lastReview,
};
};
const mapDispatchToProps = dispatch => {
@ -20,6 +27,8 @@ const mapDispatchToProps = dispatch => {
setNextLevel: (level: ILevel) => dispatch(setNextLevel(level)),
setTopTen: (topTen: ILearner[]) => dispatch(setTopTen(topTen)),
setLoadingTT: (state: boolean) => dispatch(setDashboardTTLoading(state)),
setLastReview: (review: IReviewMetadata) => dispatch(setLastReview(review)),
setLoadingLR: (state: boolean) => dispatch(setDashboardLRLoading(state)),
}
};

View File

@ -17,7 +17,7 @@ import { IReviewMetadata } from "../models/review";
interface IProps {
getNextLevel: () => Promise<ILevel>;
getLastReview: () => IReviewMetadata;
getLastReview: () => Promise<IReviewMetadata>;
getTopTen: () => Promise<ILearner[]>;
nextLevel: ILevel;
@ -28,6 +28,10 @@ interface IProps {
loadingTopTen: boolean;
setLoadingTT: (state: boolean) => void;
setTopTen: (topten: TopTen[]) => void;
lastReview: IReviewMetadata;
loadingLastReview: boolean;
setLoadingLR: (state: boolean) => void;
setLastReview: (review: IReviewMetadata) => void;
}
export default class Dashboard extends React.Component<IProps> {
@ -47,6 +51,13 @@ export default class Dashboard extends React.Component<IProps> {
}, err => {
console.log("Failed to fetch Top Ten");
});
this.props.getLastReview().then(res => {
this.props.setLoadingLR(false);
this.props.setLastReview(res);
}, err => {
console.log("Failed to fetch Last Review");
});
}
render() {
@ -97,16 +108,24 @@ export default class Dashboard extends React.Component<IProps> {
</Grid>
<Grid item lg={4}>
<Paper className="paper">
{
this.props.loadingLastReview ? (
<CircularProgress />
) : (
<div>
<Typography variant="title">
Letzte Wiederholung
</Typography>
<SummaryTable reviewMeta={this.props.getLastReview} />
<SummaryTable reviewMeta={this.props.lastReview} />
<Button
component={Link}
to="/review/queue">
Vokabeln üben
</Button>
</div>
)
}
</Paper>
</Grid>
</Grid>

View File

@ -41,7 +41,7 @@ const SummaryPageWithRouter = withRouter(
<Paper className="paper">
<Typography variant="title">Zusammenfassung</Typography>
<Grid container direction="column">
<SummaryTable reviewMeta={() => this.props.reviewMeta} />
<SummaryTable reviewMeta={this.props.reviewMeta} />
<Button onClick={this.toDashboard}>
Zum Dashboard
</Button>

View File

@ -39,6 +39,7 @@ interface IState {
dashboard: {
loadingNL: boolean;
loadingTT: boolean;
loadingLR: boolean;
};
review: {
@ -97,6 +98,7 @@ const initialState: IState = {
dashboard: {
loadingNL: true,
loadingTT: true,
loadingLR: true,
},
review: {
@ -243,6 +245,12 @@ export function LateinicusApp(state: IState = initialState, action: any) {
return Object.assign({}, state, {
didLogin: state,
});
case Actions.DASHBOARD_SET_LR_LOADING:
return Object.assign({}, state, {
dashboard: Object.assign({}, state.dashboard, {
loadingLR: action.state,
}),
});
default:
// Ignore the initialization call to the reducer. By that we can
// catch all actions that are not implemented