Merge pull request 'analytics' (#1) from analytics into main

Reviewed-on: nmemmert/Spelling#1
This commit is contained in:
nmemmert committed 2025-07-03 14:09:49 +00:00
commit c4844eecff
2 files changed
+68

No files matched your search

+16
View File
@@ -49,6 +49,7 @@
<div id="adminTabs"> <div id="adminTabs">
<button onclick="switchTab('tabUsers')" class="active">👤 Manage Users</button> <button onclick="switchTab('tabUsers')" class="active">👤 Manage Users</button>
<button onclick="switchTab('tabWords')">📝 Word Lists</button> <button onclick="switchTab('tabWords')">📝 Word Lists</button>
<button onclick="switchTab('tabAnalytics')">📊 Analytics</button>
<button onclick="switchTab('tabResults')">📊 Results</button> <button onclick="switchTab('tabResults')">📊 Results</button>
<button onclick="switchTab('tabTheme')">🎨 Theme</button> <button onclick="switchTab('tabTheme')">🎨 Theme</button>
</div> </div>
@@ -104,6 +105,21 @@
<ul id="resultsList"></ul> <ul id="resultsList"></ul>
</div> </div>
<!-- 📊 Analytics Tab -->
<div id="tabAnalytics" class="adminTab hidden">
<h3>Smart Analytics Overview</h3>
<ul id="analyticsSummary">
<li><strong>Average Score:</strong> –</li>
<li><strong>Total Completed Sessions:</strong> –</li>
<li><strong>Most Missed Word:</strong> –</li>
</ul>
<h4>Per-Student Breakdown</h4>
<ul id="studentBreakdown"></ul>
<button onclick="refreshAnalytics()">🔄 Refresh</button>
</div>
<!-- 🎨 Theme Tab --> <!-- 🎨 Theme Tab -->
<div id="tabTheme" class="adminTab hidden"> <div id="tabTheme" class="adminTab hidden">
<h3>🎨 Select Theme</h3> <h3>🎨 Select Theme</h3>
+52
View File
@@ -225,4 +225,56 @@ async function loadUserDropdowns() {
} catch (err) { } catch (err) {
console.error("⚠️ Failed to load user list:", err); console.error("⚠️ Failed to load user list:", err);
} }
}
async function refreshAnalytics() {
const summary = document.getElementById("analyticsSummary");
const breakdown = document.getElementById("studentBreakdown");
summary.innerHTML = "<li>Loading...</li>";
breakdown.innerHTML = "";
try {
const res = await fetch('/getResults');
const data = await res.json();
let totalScore = 0, sessionCount = 0;
const missMap = {};
for (const username in data) {
const { score, completed, answers } = data[username];
if (!completed || !Array.isArray(answers)) continue;
totalScore += score;
sessionCount++;
// Count missed words
answers.forEach(({ word, correct }) => {
if (!correct) {
missMap[word] = (missMap[word] || 0) + 1;
}
});
// Per-student breakdown
const li = document.createElement("li");
li.innerHTML = `<strong>${username}</strong>: ${score}/${answers.length} correct`;
breakdown.appendChild(li);
}
const avgScore = sessionCount ? (totalScore / sessionCount).toFixed(2) : "0";
let mostMissed = "-", highestMisses = 0;
for (const word in missMap) {
if (missMap[word] > highestMisses) {
highestMisses = missMap[word];
mostMissed = word;
}
}
summary.innerHTML = `
<li><strong>Average Score:</strong> ${avgScore}</li>
<li><strong>Total Completed Sessions:</strong> ${sessionCount}</li>
<li><strong>Most Missed Word:</strong> ${mostMissed} (${highestMisses} misses)</li>
`;
} catch (err) {
console.error("📉 Failed to refresh analytics:", err);
summary.innerHTML = '<li style="color:red">Error loading analytics.</li>';
}
} }