Add average mark to progress page & fix loader
This commit is contained in:
@@ -222,5 +222,9 @@ service cloud.firestore {
|
||||
match /join_codes/{joinCode} {
|
||||
allow get: if isSignedIn();
|
||||
}
|
||||
|
||||
match /completed_progress/{setIds} {
|
||||
allow get: if isSignedIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,6 +386,7 @@ function cleanseVocabString(item) {
|
||||
* @param {object} data The data passed to the function.
|
||||
* @param {string} data.progressId The ID of the progress document to update.
|
||||
* @param {string} data.answer The answer given by the user to the current prompt.
|
||||
* @return {string} averagePercentage The average percentage mark for the current collection of sets. Only returned when the test is complete.
|
||||
* @return {boolean} correct Whether the provided answer was correct.
|
||||
* @return {array} correctAnswers An array of correct answers for the question just answered. If not all correct
|
||||
* answers have yet been given, and the current answer is correct, this only contains the correct
|
||||
@@ -551,8 +552,27 @@ exports.processAnswer = functions.https.onCall((data, context) => {
|
||||
|
||||
if (mode === "lives" && docData.lives <= 0) docData.questions.length = returnData.totalQuestions = docData.progress;
|
||||
|
||||
const completedProgressDocId = db.collection("completed_progress").doc(progressDoc.data().setIds.sort().join("__"));
|
||||
return transaction.get(completedProgressDocId).then((completedProgressDoc) => {
|
||||
const totalPercentage = completedProgressDoc.data().total_percentage + (docData.correct.length / docData.questions.length * 100);
|
||||
const attempts = completedProgressDoc.data().attempts + 1;
|
||||
transaction.set(completedProgressDocId, {
|
||||
attempts: attempts,
|
||||
total_percentage: totalPercentage,
|
||||
});
|
||||
returnData.averagePercentage = (totalPercentage / attempts).toFixed(2);
|
||||
transaction.set(progressDocId, docData);
|
||||
return returnData;
|
||||
}).catch((error) => {
|
||||
const totalPercentage = docData.correct.length / docData.questions.length * 100;
|
||||
transaction.set(completedProgressDocId, {
|
||||
attempts: 1,
|
||||
total_percentage: totalPercentage,
|
||||
});
|
||||
returnData.averagePercentage = totalPercentage.toFixed(2);
|
||||
transaction.set(progressDocId, docData);
|
||||
return returnData;
|
||||
});
|
||||
} else {
|
||||
const nextVocabId = docData.questions[docData.progress];
|
||||
const nextSetOwner = nextVocabId.split("__")[0];
|
||||
|
||||
@@ -70,6 +70,8 @@ export default withRouter(class Progress extends React.Component {
|
||||
lives: 1,
|
||||
startLives: null,
|
||||
setComplete: false,
|
||||
averagePercentage: null,
|
||||
pageLoaded: false,
|
||||
};
|
||||
|
||||
let isMounted = true;
|
||||
@@ -87,7 +89,7 @@ export default withRouter(class Progress extends React.Component {
|
||||
const progressId = this.props.match.params.progressId;
|
||||
const progressRef = this.state.db.collection("progress").doc(progressId);
|
||||
|
||||
let [ newState, setDone, incorrectAnswers, duration ] = await progressRef.get().then((doc) => {
|
||||
let [ newState, setDone, incorrectAnswers, duration, setIds ] = await progressRef.get().then((doc) => {
|
||||
const data = doc.data();
|
||||
|
||||
document.title = `Study | ${data.set_title} | Parandum`;
|
||||
@@ -107,6 +109,7 @@ export default withRouter(class Progress extends React.Component {
|
||||
setIds: data.setIds,
|
||||
originalTotalQuestions: [...new Set(data.questions)].length,
|
||||
setComplete: data.duration !== null,
|
||||
pageLoaded: true,
|
||||
};
|
||||
|
||||
if (data.lives) {
|
||||
@@ -114,7 +117,7 @@ export default withRouter(class Progress extends React.Component {
|
||||
newState.startLives = data.start_lives;
|
||||
}
|
||||
|
||||
return [ newState, data.duration !== null, data.incorrect, data.duration ];
|
||||
return [ newState, data.duration !== null, data.incorrect, data.duration, data.setIds ];
|
||||
}).catch((error) => {
|
||||
console.log(`Progress data inaccessible: ${error}`);
|
||||
return [
|
||||
@@ -166,6 +169,16 @@ export default withRouter(class Progress extends React.Component {
|
||||
}));
|
||||
}));
|
||||
|
||||
promises.push(this.state.db.collection("completed_progress")
|
||||
.doc(setIds.sort().join("__"))
|
||||
.get()
|
||||
.then((completedProgressDoc) => {
|
||||
newState.averagePercentage = (completedProgressDoc.data().total_percentage / completedProgressDoc.data().attempts).toFixed(2);
|
||||
}).catch((error) => {
|
||||
console.log(`Couldn't get average percentage: ${error}`);
|
||||
newState.averagePercentage = null;
|
||||
}));
|
||||
|
||||
if (incorrectAnswers.length > 0) {
|
||||
newState.incorrectAnswers = {};
|
||||
|
||||
@@ -363,6 +376,7 @@ export default withRouter(class Progress extends React.Component {
|
||||
if (data.duration) {
|
||||
// test done
|
||||
newState.duration = data.duration;
|
||||
newState.averagePercentage = data.averagePercentage;
|
||||
|
||||
this.props.logEvent("test_complete", {
|
||||
progress_id: this.props.match.params.progressId,
|
||||
@@ -491,7 +505,8 @@ export default withRouter(class Progress extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
this.state.progressInaccessible
|
||||
this.state.pageLoaded &&
|
||||
(this.state.progressInaccessible
|
||||
?
|
||||
<Error404 />
|
||||
:
|
||||
@@ -570,6 +585,13 @@ export default withRouter(class Progress extends React.Component {
|
||||
<p>You got</p>
|
||||
<h1>{`${(this.state.correct / this.state.totalQuestions * 100).toFixed(2)}%`}</h1>
|
||||
</div>
|
||||
{
|
||||
this.state.averagePercentage !== null &&
|
||||
<div className="stat-row stat-row--inline">
|
||||
<p>The average is</p>
|
||||
<h1>{`${this.state.averagePercentage}%`}</h1>
|
||||
</div>
|
||||
}
|
||||
<div className="stat-row stat-row--inline">
|
||||
<h1>{`${this.state.correct} of ${this.state.totalQuestions}`}</h1>
|
||||
<p>marks</p>
|
||||
@@ -739,7 +761,7 @@ export default withRouter(class Progress extends React.Component {
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
</>)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -820,4 +820,16 @@ describe("Parandum Firestore database", () => {
|
||||
const testDoc = db.collection("join_codes").doc(joinCodeOne);
|
||||
await firebase.assertFails(testDoc.get());
|
||||
});
|
||||
|
||||
it("Can read completed progress docs when signed in", async () => {
|
||||
const db = getFirestore(myAuth);
|
||||
const testDoc = db.collection("completed_progress").doc(setOne);
|
||||
await firebase.assertSucceeds(testDoc.get());
|
||||
});
|
||||
|
||||
it("Can't read completed progress docs when not signed in", async () => {
|
||||
const db = getFirestore(null);
|
||||
const testDoc = db.collection("completed_progress").doc(setOne);
|
||||
await firebase.assertFails(testDoc.get());
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user