adding results

This commit is contained in:
nate@necloud.us committed 2025-07-02 14:15:45 -04:00
1 parent 49e2d58fae
commit 3e6c02e4d2
6 files changed
+152 -39

No files matched your search

+64 -39
View File
@@ -30,51 +30,41 @@
<button onclick="logoutUser()">Log Out</button>
</div>
<!-- 👨‍🏫 Admin Panel -->
<div id="adminPanel" class="hidden">
<h2>Add New User</h2>
<h2>👨‍🏫 Admin Panel</h2>
<form onsubmit="event.preventDefault(); addNewUser();">
<input type="text" id="newUsername" placeholder="Username" required />
<input type="password" id="newPassword" placeholder="Password" required />
<select id="newRole">
<option value="student">Student</option>
<option value="admin">Admin</option>
</select>
<button type="submit">Add User</button>
</form>
<!-- Tab Controls -->
<div id="adminTabs">
<button onclick="switchTab('tabUsers')" class="active">👤 Manage Users</button>
<button onclick="switchTab('tabWords')">📝 Word Lists</button>
<button onclick="switchTab('tabResults')">📊 Results</button>
<button onclick="switchTab('tabTheme')">🎨 Theme</button>
</div>
<!-- Manage Users -->
<h3>Delete Users</h3>
<select id="userDropdown" onchange="selectUserAction(this.value)">
<option value="">-- Select a user --</option>
<!-- Manage Users -->
<div id="tabUsers" class="adminTab">
<h3>Add New User</h3>
<form onsubmit="event.preventDefault(); addNewUser();">
<input type="text" id="newUsername" placeholder="Username" required />
<input type="password" id="newPassword" placeholder="Password" required />
<select id="newRole">
<option value="student">Student</option>
<option value="admin">Admin</option>
</select>
<!-- Edit words -->
<h3>Edit Word List for:</h3>
<select id="wordUserSelect" class="word-user-dropdown" onchange="loadWordsForSelectedUser()">
<option value="">-- Select a user --</option>
</select>
<!-- View Word List by User -->
<h3>📋 View Word List by User:</h3>
<select id="viewUserSelect" class="word-user-dropdown" onchange="displayWordListForSelectedUser()">
<option value="">-- Select a user --</option>
</select>
<ul id="userWordListDisplay"></ul>
<!-- Theme -->
<div style="margin: 1em 0;">
<label for="themeSelect"><strong>Select Theme:</strong></label><br/>
<select id="themeSelect" onchange="changeTheme(this.value)">
<option value="playground">Playground</option>
<option value="chalkboard">Chalkboard</option>
<option value="galaxy">Galaxy</option>
<option value="nature">Nature</option>
</select>
</div>
<button type="submit">Add User</button>
</form>
<h3>Delete Users</h3>
<select id="userDropdown" onchange="selectUserAction(this.value)">
<option value="">-- Select a user --</option>
</select>
</div>
<!-- Word Lists -->
<div id="tabWords" class="adminTab hidden">
<h3>Edit Word List for:</h3>
<select id="wordUserSelect" class="word-user-dropdown" onchange="loadWordsForSelectedUser()">
<option value="">-- Select a user --</option>
<h2>Enter Spelling Words</h2>
<textarea id="wordInput" placeholder="Enter one word per line..."></textarea><br/>
<button onclick="saveWords()">Save Word List</button>
@@ -84,6 +74,41 @@
<input type="file" accept=".txt,.csv" onchange="handleFileUpload(event)" />
<p><strong>Current Word List:</strong></p>
<ul id="wordListDisplay"></ul>
</select>
<h3>📋 View Word List by User:</h3>
<select id="viewUserSelect" class="word-user-dropdown" onchange="displayWordListForSelectedUser()">
<option value="">-- Select a user --</option>
</select>
<ul id="userWordListDisplay"></ul>
<h3>Enter Spelling Words</h3>
<textarea id="wordInput" placeholder="Enter one word per line..."></textarea><br/>
<button onclick="saveWords()">Save Word List</button>
<button onclick="clearWords()">Clear Saved Words</button>
<h3>Or Upload a Word File</h3>
<input type="file" accept=".txt,.csv" onchange="handleFileUpload(event)" />
<ul id="wordListDisplay"></ul>
</div>
<!-- Student Results -->
<div id="tabResults" class="adminTab hidden">
<h3>🧾 Student Results Overview</h3>
<button onclick="loadStudentResults()">Refresh Results</button>
<ul id="resultsList"></ul>
</div>
<!-- Theme Selection -->
<div id="tabTheme" class="adminTab hidden">
<h3>🎨 Select Theme</h3>
<select id="themeSelect" onchange="changeTheme(this.value)">
<option value="playground">Playground</option>
<option value="chalkboard">Chalkboard</option>
<option value="galaxy">Galaxy</option>
<option value="nature">Nature</option>
</select>
</div>
<!-- 👩‍🎓 Student Panel -->
+4
View File
@@ -0,0 +1,4 @@
{
"student1": { "score": 8, "completed": true, "answers": ["cat", "dog", "fish"] },
"nate": { "score": 10, "completed": true, "answers": ["grace", "truth", "peace"] }
}
+42
View File
@@ -439,4 +439,46 @@ async function displayWordListForSelectedUser() {
list.innerHTML = `<li style="color:red">❌ Error loading words: ${err.message}</li>`
console.error("Failed to load word list for user:", username, err)
}
}
async function loadStudentResults() {
const list = document.getElementById("resultsList")
list.innerHTML = ''
try {
const res = await fetch('/getResults')
const results = await res.json()
if (!Object.keys(results).length) {
list.innerHTML = '<li><em>No results available yet.</em></li>'
return
}
for (const [username, result] of Object.entries(results)) {
const li = document.createElement('li')
li.innerHTML = `<strong>${username}</strong> — Score: ${result.score}, Completed: ${result.completed ? '✅' : '❌'}<br>
Answers: ${result.answers.join(', ')}`
list.appendChild(li)
}
} catch (err) {
console.error("🔴 Failed to load results:", err)
list.innerHTML = '<li style="color:red">Error loading results.</li>'
}
}
function switchTab(targetId) {
// Hide all tabs
document.querySelectorAll('.adminTab').forEach(tab => tab.classList.add('hidden'))
// Remove active class from buttons
document.querySelectorAll('#adminTabs button').forEach(btn => btn.classList.remove('active'))
// Show the selected tab
document.getElementById(targetId).classList.remove('hidden')
// Highlight active tab button
const buttons = document.querySelectorAll('#adminTabs button')
buttons.forEach(btn => {
if (btn.getAttribute('onclick')?.includes(targetId)) {
btn.classList.add('active')
}
})
}
+33
View File
@@ -122,4 +122,37 @@ body.nature button {
.toast.show {
opacity: 1;
pointer-events: auto;
}
#adminTabs {
margin: 1em 0;
}
#adminTabs button {
margin-right: 8px;
padding: 10px 16px;
background-color: #f0f0f0;
border: 1px solid #ccc;
border-bottom: none;
border-radius: 6px 6px 0 0;
font-weight: 600;
color: #333;
cursor: pointer;
transition: background-color 0.2s, color 0.2s;
}
#adminTabs button:hover {
background-color: #e0f2ff;
color: #000;
}
#adminTabs button.active {
background-color: #ffffff;
color: #000;
border-bottom: 2px solid #fff;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
}
.adminTab {
display: none;
}
.adminTab:not(.hidden) {
display: block;
}
+5
View File
@@ -8,5 +8,10 @@
"username": "student1",
"hash": "8d969eef6ecad3c29a3a629280e686cf",
"role": "student"
},
{
"username": "nate",
"hash": "5a2a558c78d3717db731600c4f354fa1d9c84b556f108091a891f444f1bdec40",
"role": "student"
}
]
+4
View File
@@ -49,5 +49,9 @@ app.post('/saveWordList', (req, res) => {
fs.writeFileSync('public/wordlists.json', JSON.stringify(data, null, 2))
res.send(`✅ Word list saved for ${username}`)
})
app.get('/getResults', (req, res) => {
const results = JSON.parse(fs.readFileSync('public/results.json', 'utf-8'))
res.json(results)
})
app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`))