adding results
This commit is contained in:
1 parent
49e2d58fae
commit
3e6c02e4d2
6 files changed
+139
-26
No files matched your search
+51
-26
@@ -30,10 +30,20 @@
|
||||
<button onclick="logoutUser()">Log Out</button>
|
||||
</div>
|
||||
|
||||
<!-- 👨🏫 Admin Panel -->
|
||||
<div id="adminPanel" class="hidden">
|
||||
<h2>Add New User</h2>
|
||||
<h2>👨🏫 Admin Panel</h2>
|
||||
|
||||
<!-- 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 -->
|
||||
<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 />
|
||||
@@ -44,37 +54,17 @@
|
||||
<button type="submit">Add User</button>
|
||||
</form>
|
||||
|
||||
<!-- Manage Users -->
|
||||
<h3>Delete Users</h3>
|
||||
<select id="userDropdown" onchange="selectUserAction(this.value)">
|
||||
<option value="">-- Select a user --</option>
|
||||
</select>
|
||||
<!-- Edit words -->
|
||||
</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>
|
||||
</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>
|
||||
|
||||
|
||||
<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 -->
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"student1": { "score": 8, "completed": true, "answers": ["cat", "dog", "fish"] },
|
||||
"nate": { "score": 10, "completed": true, "answers": ["grace", "truth", "peace"] }
|
||||
}
|
||||
@@ -440,3 +440,45 @@ async function displayWordListForSelectedUser() {
|
||||
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')
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -123,3 +123,36 @@ body.nature button {
|
||||
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;
|
||||
}
|
||||
@@ -8,5 +8,10 @@
|
||||
"username": "student1",
|
||||
"hash": "8d969eef6ecad3c29a3a629280e686cf",
|
||||
"role": "student"
|
||||
},
|
||||
{
|
||||
"username": "nate",
|
||||
"hash": "5a2a558c78d3717db731600c4f354fa1d9c84b556f108091a891f444f1bdec40",
|
||||
"role": "student"
|
||||
}
|
||||
]
|
||||
@@ -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}`))
|
||||
Reference in new issue
Block a user