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
	 Alexander Polynomdivision
						Alexander Polynomdivision