feat: Implement setting the last review
This commit is contained in:
parent
18c13c06cd
commit
2c41347cea
@ -9,11 +9,13 @@ import TableCell from "@material-ui/core/TableCell";
|
|||||||
import { IReviewMetadata } from "../models/review";
|
import { IReviewMetadata } from "../models/review";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
reviewMeta: IReviewMetadata;
|
reviewMeta: () => IReviewMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SummaryTable extends React.Component<IProps> {
|
export default class SummaryTable extends React.Component<IProps> {
|
||||||
render() {
|
render() {
|
||||||
|
const meta = this.props.reviewMeta();
|
||||||
|
|
||||||
return <Table>
|
return <Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
@ -24,15 +26,11 @@ export default class SummaryTable extends React.Component<IProps> {
|
|||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>Korrekt</TableCell>
|
<TableCell>Korrekt</TableCell>
|
||||||
<TableCell numeric>{this.props.reviewMeta.correct}</TableCell>
|
<TableCell numeric>{meta.correct}</TableCell>
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell>Fast richtig</TableCell>
|
|
||||||
<TableCell numeric>{this.props.reviewMeta.nearly}</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>Falsch</TableCell>
|
<TableCell>Falsch</TableCell>
|
||||||
<TableCell numeric>{this.props.reviewMeta.wrong}</TableCell>
|
<TableCell numeric>{meta.wrong}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>;
|
</Table>;
|
||||||
|
@ -39,6 +39,8 @@ import { IReviewMetadata, ReviewType } from "../models/review";
|
|||||||
interface IState {
|
interface IState {
|
||||||
loggedIn: boolean;
|
loggedIn: boolean;
|
||||||
|
|
||||||
|
lastReview: IReviewMetadata;
|
||||||
|
|
||||||
drawerOpen: boolean;
|
drawerOpen: boolean;
|
||||||
showDrawerButton: boolean;
|
showDrawerButton: boolean;
|
||||||
}
|
}
|
||||||
@ -54,8 +56,15 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
// TODO
|
// TODO
|
||||||
const loggedIn = authKey !== null;
|
const loggedIn = authKey !== null;
|
||||||
|
|
||||||
|
// TODO: Fetch the last review
|
||||||
this.state = {
|
this.state = {
|
||||||
loggedIn,
|
loggedIn,
|
||||||
|
|
||||||
|
lastReview: {
|
||||||
|
correct: 0,
|
||||||
|
wrong: 0,
|
||||||
|
},
|
||||||
|
|
||||||
drawerOpen: false,
|
drawerOpen: false,
|
||||||
showDrawerButton: true,
|
showDrawerButton: true,
|
||||||
};
|
};
|
||||||
@ -82,15 +91,18 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
return levels;
|
return levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLastReview(): IReviewMetadata {
|
getLastReview = (): IReviewMetadata => {
|
||||||
console.log("STUB: Application::getLastReview");
|
console.log("STUB: Application::getLastReview");
|
||||||
|
|
||||||
// TODO: Actually fetch this
|
// TODO: Actually fetch this
|
||||||
return {
|
return this.state.lastReview;
|
||||||
correct: 5,
|
}
|
||||||
nearly: 5,
|
|
||||||
wrong: 5,
|
setLastReview = (meta: IReviewMetadata) => {
|
||||||
};
|
// TODO: Send this to the server
|
||||||
|
this.setState({
|
||||||
|
lastReview: meta,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getReviewQueue = (): IVocab[] => {
|
getReviewQueue = (): IVocab[] => {
|
||||||
@ -360,7 +372,7 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
component={() => {
|
component={() => {
|
||||||
return <Dashboard
|
return <Dashboard
|
||||||
nextLevel={this.getNextLevel}
|
nextLevel={this.getNextLevel}
|
||||||
lastReview={this.getLastReview}
|
getLastReview={this.getLastReview}
|
||||||
getTopTen={this.getTopTenLearners} />
|
getTopTen={this.getTopTenLearners} />
|
||||||
}} />
|
}} />
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
@ -382,7 +394,8 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
return <LevelPage
|
return <LevelPage
|
||||||
id={match.params.id}
|
id={match.params.id}
|
||||||
levelVocab={this.getLevelVocab}
|
levelVocab={this.getLevelVocab}
|
||||||
drawerButtonState={this.drawerButtonState} />;
|
drawerButtonState={this.drawerButtonState}
|
||||||
|
setLastReview={this.setLastReview} />;
|
||||||
} else {
|
} else {
|
||||||
return <Redirect to="/login" />;
|
return <Redirect to="/login" />;
|
||||||
}
|
}
|
||||||
@ -395,7 +408,8 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
reviewType={ReviewType.LEVEL}
|
reviewType={ReviewType.LEVEL}
|
||||||
levelId={match.params.id}
|
levelId={match.params.id}
|
||||||
vocabByLevel={this.getLevelVocab}
|
vocabByLevel={this.getLevelVocab}
|
||||||
drawerButtonState={this.drawerButtonState} />;
|
drawerButtonState={this.drawerButtonState}
|
||||||
|
setLastReview={this.setLastReview} />;
|
||||||
} else {
|
} else {
|
||||||
return <Redirect to="/login" />;
|
return <Redirect to="/login" />;
|
||||||
}
|
}
|
||||||
@ -407,7 +421,8 @@ export default class Application extends React.Component<{}, IState> {
|
|||||||
return <ReviewPage
|
return <ReviewPage
|
||||||
reviewType={ReviewType.QUEUE}
|
reviewType={ReviewType.QUEUE}
|
||||||
vocabByQueue={this.getReviewQueue}
|
vocabByQueue={this.getReviewQueue}
|
||||||
drawerButtonState={this.drawerButtonState} />;
|
drawerButtonState={this.drawerButtonState}
|
||||||
|
setLastReview={this.setLastReview} />;
|
||||||
}} />
|
}} />
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
isAuth={this.isAuthenticated}
|
isAuth={this.isAuthenticated}
|
||||||
|
@ -3,8 +3,6 @@ export interface IReviewMetadata {
|
|||||||
correct: number;
|
correct: number;
|
||||||
// Number of wrong answers
|
// Number of wrong answers
|
||||||
wrong: number;
|
wrong: number;
|
||||||
// Number of nearly correct answers
|
|
||||||
nearly: number;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum ReviewType {
|
export enum ReviewType {
|
||||||
|
@ -16,7 +16,7 @@ import { IReviewMetadata } from "../models/review";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
nextLevel: () => ILevel;
|
nextLevel: () => ILevel;
|
||||||
lastReview: () => IReviewMetadata;
|
getLastReview: () => IReviewMetadata;
|
||||||
getTopTen: () => ILearner[];
|
getTopTen: () => ILearner[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ export default class Dashboard extends React.Component<IProps> {
|
|||||||
<Typography variant="title">
|
<Typography variant="title">
|
||||||
Letzte Wiederholung
|
Letzte Wiederholung
|
||||||
</Typography>
|
</Typography>
|
||||||
<SummaryTable reviewMeta={this.props.lastReview()} />
|
<SummaryTable reviewMeta={this.props.getLastReview} />
|
||||||
</Paper>
|
</Paper>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -11,7 +11,7 @@ import Popover from "@material-ui/core/Popover";
|
|||||||
import { Redirect } from "react-router-dom";
|
import { Redirect } from "react-router-dom";
|
||||||
|
|
||||||
import { IVocab, IReviewCard, vocabToReviewCard, reviewQTypeToStr } from "../models/vocab";
|
import { IVocab, IReviewCard, vocabToReviewCard, reviewQTypeToStr } from "../models/vocab";
|
||||||
import { ReviewType } from "../models/review";
|
import { ReviewType, IReviewMetadata } from "../models/review";
|
||||||
|
|
||||||
import { levW } from "../algorithms/levenshtein";
|
import { levW } from "../algorithms/levenshtein";
|
||||||
import { LEVENSHTEIN_MAX_DISTANCE } from "../config";
|
import { LEVENSHTEIN_MAX_DISTANCE } from "../config";
|
||||||
@ -23,6 +23,8 @@ interface IProps {
|
|||||||
vocabByLevel?: (level: number) => IVocab[];
|
vocabByLevel?: (level: number) => IVocab[];
|
||||||
vocabByQueue?: () => IVocab[];
|
vocabByQueue?: () => IVocab[];
|
||||||
|
|
||||||
|
setLastReview: (meta: IReviewMetadata) => void;
|
||||||
|
|
||||||
reviewType: ReviewType;
|
reviewType: ReviewType;
|
||||||
|
|
||||||
drawerButtonState: (state: boolean) => void;
|
drawerButtonState: (state: boolean) => void;
|
||||||
@ -32,6 +34,8 @@ interface IState {
|
|||||||
input: string;
|
input: string;
|
||||||
current: IReviewCard;
|
current: IReviewCard;
|
||||||
|
|
||||||
|
metadata: IReviewMetadata;
|
||||||
|
|
||||||
toSummary: boolean;
|
toSummary: boolean;
|
||||||
|
|
||||||
popoverOpen: boolean;
|
popoverOpen: boolean;
|
||||||
@ -41,7 +45,7 @@ interface IState {
|
|||||||
|
|
||||||
export default class ReviewPage extends React.Component<IProps, IState> {
|
export default class ReviewPage extends React.Component<IProps, IState> {
|
||||||
private vocab: IVocab[] = [];
|
private vocab: IVocab[] = [];
|
||||||
private reviewQueue: Queue<IReviewCard> = new Queue();
|
private reviewQueue: Queue<IReviewCard> = undefined;
|
||||||
// Used for positioning the popover
|
// Used for positioning the popover
|
||||||
private buttonRef: HTMLButtonElement;
|
private buttonRef: HTMLButtonElement;
|
||||||
|
|
||||||
@ -73,13 +77,20 @@ export default class ReviewPage extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Turn the vocabulary into IReviewCards and queue them
|
// Turn the vocabulary into IReviewCards and queue them
|
||||||
|
if (!this.reviewQueue) {
|
||||||
|
this.reviewQueue = new Queue();
|
||||||
this.vocab.forEach((vocab) => {
|
this.vocab.forEach((vocab) => {
|
||||||
vocabToReviewCard(vocab).forEach(this.reviewQueue.enqueue);
|
vocabToReviewCard(vocab).forEach(this.reviewQueue.enqueue);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
input: "",
|
input: "",
|
||||||
current: this.reviewQueue.dequeue(),
|
current: this.reviewQueue.dequeue(),
|
||||||
|
metadata: {
|
||||||
|
correct: 0,
|
||||||
|
wrong: 0,
|
||||||
|
},
|
||||||
|
|
||||||
toSummary: false,
|
toSummary: false,
|
||||||
|
|
||||||
@ -89,6 +100,15 @@ export default class ReviewPage extends React.Component<IProps, IState> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
increaseMeta = (correct: number, wrong: number): IReviewMetadata => {
|
||||||
|
const { metadata } = this.state;
|
||||||
|
|
||||||
|
return {
|
||||||
|
wrong: metadata.wrong + wrong,
|
||||||
|
correct: metadata.correct + correct,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
vocabFromId = (id: number) => {
|
vocabFromId = (id: number) => {
|
||||||
return this.vocab.find((el) => el.id === this.state.current.id);
|
return this.vocab.find((el) => el.id === this.state.current.id);
|
||||||
}
|
}
|
||||||
@ -104,20 +124,27 @@ export default class ReviewPage extends React.Component<IProps, IState> {
|
|||||||
// Find the lowest distance
|
// Find the lowest distance
|
||||||
const minDist = Math.min(...dists);
|
const minDist = Math.min(...dists);
|
||||||
|
|
||||||
|
console.log(this.reviewQueue.size());
|
||||||
|
|
||||||
// Check if the user's answer was correct
|
// Check if the user's answer was correct
|
||||||
if (minDist === 0) {
|
if (minDist === 0) {
|
||||||
// TODO: Show it's correct?
|
// TODO: Show it's correct?
|
||||||
// Show the next vocab word
|
// Show the next vocab word
|
||||||
if (this.reviewQueue.size() === 0) {
|
if (this.reviewQueue.size() === 0) {
|
||||||
// TODO: Set some data that the summary screen will show
|
// Go to the summary screen
|
||||||
this.setState({
|
this.setState({
|
||||||
toSummary: true,
|
toSummary: true,
|
||||||
|
}, () => {
|
||||||
|
// Update the "Last Review" data
|
||||||
|
this.props.setLastReview(this.state.metadata);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Increase the vocab
|
// Increase the vocab
|
||||||
this.setState({
|
this.setState({
|
||||||
current: this.reviewQueue.dequeue(),
|
current: this.reviewQueue.dequeue(),
|
||||||
input: "",
|
input: "",
|
||||||
|
// Add one correct answer
|
||||||
|
metadata: this.increaseMeta(1, 0),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (minDist <= LEVENSHTEIN_MAX_DISTANCE) {
|
} else if (minDist <= LEVENSHTEIN_MAX_DISTANCE) {
|
||||||
@ -140,6 +167,7 @@ export default class ReviewPage extends React.Component<IProps, IState> {
|
|||||||
popoverColor: "red",
|
popoverColor: "red",
|
||||||
// TODO: Or maybe don't reset the text
|
// TODO: Or maybe don't reset the text
|
||||||
input: "",
|
input: "",
|
||||||
|
metadata: this.increaseMeta(0, 1),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user