diff --git a/public/js/admin.js b/public/js/admin.js
index 8e33bf3..fbc2050 100644
--- a/public/js/admin.js
+++ b/public/js/admin.js
@@ -390,7 +390,6 @@ window.loadStudentResults = async function() {
userResults.forEach((result, index) => {
const li = document.createElement("li");
let answersHTML = '';
-
// Check if result and answers exist and are valid
if (result && result.answers && Array.isArray(result.answers)) {
result.answers.forEach(entry => {
@@ -402,8 +401,15 @@ window.loadStudentResults = async function() {
}
const timestamp = result.timestamp ? new Date(result.timestamp).toLocaleString() : 'Unknown time';
+ // Label result type
+ let typeLabel = '';
+ if (result.type === 'typing') {
+ typeLabel = '[Typing Practice] ';
+ } else {
+ typeLabel = '[Game] ';
+ }
li.innerHTML = `
- ${username} (Session ${index + 1}) — Score: ${result?.score || 'N/A'}, Completed: ${result?.completed ? '✅' : '❌'}
+ ${typeLabel}${username} (Session ${index + 1}) — Score: ${result?.score || 'N/A'}, Completed: ${result?.completed ? '✅' : '❌'}
Date: ${timestamp}
Answers:
${answersHTML}
diff --git a/public/js/typing.js b/public/js/typing.js
index 2030662..3fc4f17 100644
--- a/public/js/typing.js
+++ b/public/js/typing.js
@@ -40,7 +40,11 @@ window.startTypingPractice = async function() {
}
}
-window.showNextWord = function() {
+
+// Track answers for results
+typingState.answers = [];
+
+window.showNextWord = async function() {
const promptEl = document.getElementById('typingPrompt');
const inputEl = document.getElementById('typingInput');
if (!promptEl || !inputEl) return;
@@ -48,6 +52,8 @@ window.showNextWord = function() {
if (!typingState.words.length) {
promptEl.textContent = '🎉 Practice complete!';
inputEl.disabled = true;
+ // Save results to backend
+ await saveTypingPracticeResults();
return;
}
@@ -64,13 +70,36 @@ window.showNextWord = function() {
inputEl.focus();
}
+async function saveTypingPracticeResults() {
+ const user = JSON.parse(localStorage.getItem('loggedInUser'));
+ if (!user) return;
+ const result = {
+ score: typingState.answers.filter(a => a.correct).length,
+ completed: true,
+ answers: typingState.answers
+ };
+ try {
+ await fetch('/saveTypingResults', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ username: user.username, result })
+ });
+ console.log('Typing practice results saved');
+ } catch (e) {
+ console.error('Failed to save typing results', e);
+ }
+}
+
window.submitTyping = function() {
const input = document.getElementById('typingInput')?.value.trim() || '';
const feedback = document.getElementById('typingFeedback');
if (!feedback) return;
-
- if (input.toLowerCase() === typingState.currentWord.toLowerCase()) {
+
+ const correct = input.toLowerCase() === typingState.currentWord.toLowerCase();
+ typingState.answers.push({ word: typingState.currentWord, input, correct });
+
+ if (correct) {
feedback.textContent = '✅ Correct!';
feedback.style.color = 'green';
typingState.words.shift();
diff --git a/server.js b/server.js
index d4c1cf8..6776c48 100644
--- a/server.js
+++ b/server.js
@@ -407,6 +407,30 @@ app.post('/saveResults', (req, res) => {
});
// 👥 Get users
+// --- Typing Practice Results ---
+// Save typing practice results for a user
+app.post('/saveTypingResults', (req, res) => {
+ const { username, result } = req.body;
+ if (
+ typeof username !== 'string' ||
+ typeof result !== 'object' ||
+ typeof result.score !== 'number' ||
+ typeof result.completed !== 'boolean' ||
+ !Array.isArray(result.answers)
+ ) return res.status(400).send("Invalid result format");
+
+ const resultsPath = path.join(DATA_DIR, files.results);
+ const allResults = readJsonSafe(resultsPath);
+ if (!allResults[username]) allResults[username] = [];
+
+ allResults[username].push({
+ ...result,
+ timestamp: new Date().toISOString(),
+ type: 'typing' // Mark as typing practice result
+ });
+ fs.writeFileSync(resultsPath, JSON.stringify(allResults, null, 2));
+ res.send(`✅ Typing results archived for ${username}`);
+});
app.get('/getUsers', (req, res) => {
const users = readJsonSafe(path.join(DATA_DIR, files.users), []);
res.json(users);