Skip to content

Commit b68925b

Browse files
committed
show learning progress breakdown
1 parent ef72aa7 commit b68925b

File tree

6 files changed

+166
-6
lines changed

6 files changed

+166
-6
lines changed

css/foundation.css

+4
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@
2525
.mobile-app-toggle .button.is-active {
2626
background: #1779ba;
2727
color: #fefefe;
28+
}
29+
30+
a > span.label {
31+
cursor: pointer;
2832
}

index.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
<li><a href="#">The quiz</a></li>
2424
<li><a href="settings.html">Settings</a></li>
2525
<li class="points" style="display: none;">
26-
<span id="completeCounter" class="label secondary">0% complete</span><span id="userLevel" class="label primary">Level 0</span>
26+
<a href="points.html">
27+
<span id="completeCounter" class="label secondary">0% complete</span>
28+
<span id="userLevel" class="label primary">Level 0</span>
29+
</a>
2730
</li>
2831
</ul>
2932
</div>

js/data.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export async function getUserPercentComplete() {
131131
const threshold = getMinCorrectAnswerThreshold(word);
132132
percentComplete += Math.min(1, nCorrectAnswer / threshold / list.length);
133133

134-
if (await wordIsDone(word)) {
134+
if (await wordIsDone(word, nCorrectAnswer, threshold)) {
135135
updateUserLevel(word.level, list.length);
136136
}
137137
}
@@ -157,9 +157,10 @@ export async function updateUserLevel(wordLevel, listLength) {
157157
userLevel += (Number(wordLevel) / listLength) * 100;
158158
}
159159

160-
export async function wordIsDone(word) {
161-
const nCorrectAnswer = getCorrectAnswerCount(word);
160+
export async function wordIsDone(word, nCorrectAnswer, threshold) {
161+
nCorrectAnswer = nCorrectAnswer || getCorrectAnswerCount(word);
162+
threshold = threshold || getMinCorrectAnswerThreshold(word);
162163

163-
const isWordDone = nCorrectAnswer >= getMinCorrectAnswerThreshold(word);
164+
const isWordDone = nCorrectAnswer >= threshold;
164165
return isWordDone;
165166
}

js/points.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import * as data from "./data.js";
2+
3+
async function initSettings() {
4+
await setPercentComplete();
5+
await fillTables();
6+
}
7+
8+
async function setPercentComplete() {
9+
const { percentComplete, userLevel } = await data.getUserPercentComplete();
10+
$("#completeCounter").text(
11+
`${Math.round(percentComplete * 10000) / 100}% complete`
12+
);
13+
$("#userLevel").text(`Level ${Math.ceil(userLevel)}`);
14+
$(".points").show();
15+
}
16+
17+
async function fillTables() {
18+
const list = await data.getVocabList();
19+
const rangeInterval = 1000;
20+
const indexRanges = {};
21+
const levels = {};
22+
23+
for (let i = 0; i < list.length; i++) {
24+
const word = list[i];
25+
const nCorrectAnswer = data.getCorrectAnswerCount(word);
26+
const threshold = data.getMinCorrectAnswerThreshold(word);
27+
const wordIsDone = await data.wordIsDone(word, nCorrectAnswer, threshold);
28+
29+
const indexMinRange = Math.floor(i / rangeInterval);
30+
const indexRange = `${indexMinRange * rangeInterval}-${(indexMinRange + 1) * rangeInterval}`;
31+
indexRanges[indexRange] = {
32+
nCorrect: (indexRanges[indexRange]?.nCorrect || 0) + nCorrectAnswer,
33+
totalCorrectNeeded: (indexRanges[indexRange]?.totalCorrectNeeded || 0) + threshold,
34+
wordsDone: (indexRanges[indexRange]?.wordsDone || 0) + (wordIsDone ? 1: 0),
35+
totalWords: (indexRanges[indexRange]?.totalWords || 0) + 1
36+
}
37+
38+
levels[word.level] = {
39+
nCorrect: (levels[word.level]?.nCorrect || 0) + nCorrectAnswer,
40+
totalCorrectNeeded: (levels[word.level]?.totalCorrectNeeded || 0) + threshold,
41+
wordsDone: (levels[word.level]?.wordsDone || 0) + (wordIsDone ? 1: 0),
42+
totalWords: (levels[word.level]?.totalWords || 0) + 1
43+
}
44+
}
45+
46+
for (const indexRange in indexRanges) {
47+
$("#byIndexTable tbody").append(`<tr>
48+
<td>${indexRange}</td>
49+
<td>${Math.round(indexRanges[indexRange].nCorrect / indexRanges[indexRange].totalCorrectNeeded * 1000) / 10}%</td>
50+
<td>${Math.round(indexRanges[indexRange].wordsDone / indexRanges[indexRange].totalWords * 1000) / 10}%</td></tr>`);
51+
}
52+
53+
for (const level in levels) {
54+
$("#byLevelTable tbody").append(`<tr>
55+
<td>${level}</td>
56+
<td>${Math.round(levels[level].nCorrect / levels[level].totalCorrectNeeded * 1000) / 10}%</td>
57+
<td>${Math.round(levels[level].wordsDone / levels[level].totalWords * 1000) / 10}%</td></tr>`);
58+
}
59+
}
60+
61+
initSettings();

points.html

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Japanese vocabulary quiz</title>
5+
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
6+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
9+
<link
10+
rel="stylesheet"
11+
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/foundation.min.css"
12+
crossorigin="anonymous"
13+
/>
14+
<link rel="stylesheet" type="text/css" href="css/foundation.css" />
15+
</head>
16+
<body>
17+
<!-- Start Top Bar -->
18+
<div class="top-bar">
19+
<div class="top-bar-left">
20+
<ul class="menu">
21+
<li class="menu-text">Japanese vocabulary quiz</li>
22+
<li><a href="index.html">The quiz</a></li>
23+
<li><a href="settings.html">Settings</a></li>
24+
<li class="points" style="display: none;">
25+
<a href="#">
26+
<span id="completeCounter" class="label secondary">0% complete</span>
27+
<span id="userLevel" class="label primary">Level 0</span>
28+
</a>
29+
</li>
30+
</ul>
31+
</div>
32+
</div>
33+
<!-- End Top Bar -->
34+
35+
<div class="callout primary">
36+
<div class="grid-container text-center">
37+
<h1>Learning progress</h1>
38+
</div>
39+
</div>
40+
41+
<div class="grid-container section">
42+
<div>
43+
<h5>By word index</h5>
44+
<div>
45+
<table id="byIndexTable" class="stack">
46+
<thead>
47+
<tr>
48+
<th width="200">Index range</th>
49+
<th width="100">% progress</th>
50+
<th width="100">% words completed</th>
51+
</tr>
52+
</thead>
53+
<tbody></tbody>
54+
</table>
55+
</div>
56+
</div>
57+
58+
<div>
59+
<h5>By level</h5>
60+
<div>
61+
<table id="byLevelTable" class="stack">
62+
<thead>
63+
<tr>
64+
<th width="200">Level</th>
65+
<th width="100">% progress</th>
66+
<th width="100">% words completed</th>
67+
</tr>
68+
</thead>
69+
<tbody></tbody>
70+
</table>
71+
</div>
72+
</div>
73+
</div>
74+
75+
76+
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
77+
<script
78+
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/foundation.min.js"
79+
crossorigin="anonymous"
80+
></script>
81+
<script src="https://storage.ko-fi.com/cdn/scripts/overlay-widget.js"></script>
82+
<script src="css/foundation.js"></script>
83+
<script src="js/points.js" type="module"></script>
84+
<script>
85+
$(document).foundation();
86+
</script>
87+
</body>
88+
</html>

settings.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
<li><a href="index.html">The quiz</a></li>
2424
<li><a href="#">Settings</a></li>
2525
<li class="points" style="display: none;">
26-
<span id="completeCounter" class="label secondary">0% complete</span><span id="userLevel" class="label primary">Level 0</span>
26+
<a href="points.html">
27+
<span id="completeCounter" class="label secondary">0% complete</span>
28+
<span id="userLevel" class="label primary">Level 0</span>
29+
</a>
2730
</li>
2831
</ul>
2932
</div>

0 commit comments

Comments
 (0)