JIT
Connect Teacher Student Dashboard
connect this two codes with each other: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Teacher Dashboard</title> <link rel="stylesheet" href="teacher.css"> </head> <body> <div class="navbar"> <h1>Teacher Dashboard</h1> </div> <div class="container"> <div class="button-container"> <button class="btn" id="createLessonBtn">Create Lesson</button> <button class="btn" id="createQuizBtn">Make Quiz</button> <button class="btn" id="manageScoresBtn">Manage Scores & Grades</button> <button class="btn" id="deleteLessonBtn">Delete Lesson</button> <button class="btn" id="deleteQuizBtn">Delete Quiz</button> <!-- Delete Quiz Button Re-added --> </div> <h3>Created Lessons</h3> <div id="createdLessons"></div> <h3>Created Quizzes</h3> <div id="createdQuizzes"></div> </div> <!-- Lesson Modal (Create/Edit) --> <div id="lessonModal" class="modal"> <div class="modal-content"> <span class="close" data-modal-id="lessonModal">&times;</span> <h2 id="lessonModalTitle">Create Lesson</h2> <form id="lessonForm"> <input type="hidden" id="editLessonIndex" value="-1"> <label for="lessonTitle">Lesson Title:</label> <input type="text" id="lessonTitle" name="lessonTitle" required><br><br> <label for="lessonContent">Lesson Content:</label> <textarea id="lessonContent" name="lessonContent" rows="4" required></textarea><br><br> <button type="submit" id="lessonSubmitBtn" class="btn">Create Lesson</button> </form> </div> </div> <!-- Quiz Modal (Create/Edit) --> <div id="quizModal" class="modal"> <div class="modal-content large"> <span class="close" data-modal-id="quizModal">&times;</span> <h2 id="quizModalTitle">Create Quiz</h2> <form id="quizForm"> <input type="hidden" id="editQuizIndex" value="-1"> <label for="quizType">Quiz Type:</label> <select id="quizType" name="quizType" required> <option value="multiple-choice">Multiple Choice</option> <option value="identification">Identification</option> </select><br><br> <label for="quizTitle">Quiz Title:</label> <input type="text" id="quizTitle" name="quizTitle" required><br><br> <div id="questionsContainer"></div> <button type="button" class="btn" id="addQuestionBtn">Add Question</button><br><br> <button type="submit" id="quizSubmitBtn" class="btn">Create Quiz</button> </form> </div> </div> <!-- Delete Modal (Handles both Lessons and Quizzes) --> <div id="deleteModal" class="modal"> <div class="modal-content"> <span class="close" data-modal-id="deleteModal">&times;</span> <h2>Delete Item</h2> <!-- Generic Title --> <label for="deleteType">Item Type:</label> <!-- Generic Label --> <select id="deleteType"> <!-- Type Select Re-added --> <option value="lesson">Lesson</option> <option value="quiz">Quiz</option> </select><br><br> <label for="deleteChoice">Select Item to Delete:</label> <!-- Generic Label --> <select id="deleteChoice"></select><br><br> <button id="deleteBtn" class="btn delete">Delete</button> </div> </div> <!-- Manage Scores Modal --> <div id="manageScoresModal" class="modal"> <div class="modal-content large"> <span class="close" data-modal-id="manageScoresModal">&times;</span> <h2>Manage Scores and Grades</h2> <div class="manage-scores-container"> <label for="quizSelectForScores">Select Quiz:</label> <select id="quizSelectForScores"> <option value="">-- Select a Quiz --</option> <!-- Options populated by JS --> </select> <div id="studentScoresDisplay" class="scores-display-area"> <p class="no-scores-message">Select a quiz to view student scores.</p> <!-- Table will be inserted here by JS --> </div> </div> </div> </div> <!-- Performance Analytics Button --> <button id="analyticsBtn" class="analytics-btn">View Performance & Analytics</button> <!-- Performance Analytics Fullscreen Modal --> <div id="analyticsModal" class="modal fullscreen"> <div class="modal-content"> <h2>Teacher Performance & Analytics</h2> <div class="analytics-section"> <h3>Overview</h3> <p><strong>Lessons Created:</strong> <span id="lessonCount">0</span></p> <p><strong>Quizzes Created:</strong> <span id="quizCount">0</span></p> </div> <div class="analytics-section"> <h3>Class Performance (Example)</h3> <p>Average Quiz Score: <span id="averageQuizScore">N/A</span></p> </div> <div class="modal-navigation"> <button id="modalDashboardBtn" class="modal-nav-btn dashboard">Back to Dashboard</button> <button id="modalHomeBtn" class="modal-nav-btn home">Homepage</button> <button id="modalLogoutBtn" class="modal-nav-btn logout">Logout</button> </div> </div> </div> <script src="teacher.js"></script> </body> </html> body { font-family: Arial, sans-serif; background-color: #f2f2f2; padding: 0 20px 80px 20px; /* Remove top padding, ensure bottom padding for fixed button */ margin: 0; line-height: 1.6; } /* Prevent body scroll when fullscreen modal is open */ body.modal-open { overflow: hidden; } .navbar { background-color: #4CAF50; color: white; padding: 15px 20px; /* Slightly more padding */ margin-bottom: 25px; /* More space */ border-radius: 0 0 5px 5px; /* Rounded bottom corners */ box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .navbar h1 { margin: 0; text-align: center; font-size: 1.8em; } .container { background-color: #fff; padding: 25px; border-radius: 8px; /* More rounded */ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); max-width: 1000px; /* Wider container */ margin: 0 auto 20px auto; /* Center container, reduce bottom margin */ } .hidden { display: none; } /* --- Standard Modal Styles --- */ .modal:not(.fullscreen) { /* Apply only to non-fullscreen modals */ display: none; position: fixed; z-index: 100; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0, 0, 0, 0.5); /* Darker overlay */ padding-top: 50px; } .modal:not(.fullscreen) .modal-content { background-color: #fff; margin: 3% auto; /* Adjust vertical margin */ padding: 25px 30px; /* More padding */ border: 1px solid #ccc; border-radius: 8px; width: 90%; max-width: 650px; /* Default max-width */ box-shadow: 0 5px 15px rgba(0,0,0,0.2); position: relative; /* For close button */ animation-name: animatetop; animation-duration: 0.4s; } /* Larger modal variant */ .modal:not(.fullscreen) .modal-content.large { max-width: 850px; } @keyframes animatetop { from {top: -300px; opacity: 0} to {top: 0; opacity: 1} } .close { color: #aaa; position: absolute; /* Position relative to modal-content */ top: 10px; right: 15px; font-size: 30px; font-weight: bold; line-height: 1; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; } /* --- Fullscreen Modal Styles --- */ .modal.fullscreen { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; background-color: #f8f9fa; /* Light background */ } .modal.fullscreen .modal-content { background-color: transparent; margin: 0; padding: 40px; /* More padding */ border: none; width: 100%; height: 100%; max-width: none; border-radius: 0; box-shadow: none; position: relative; overflow-y: auto; box-sizing: border-box; } .modal.fullscreen h2 { text-align: center; color: #6f42c1; /* Keep purple for analytics title */ margin-top: 10px; margin-bottom: 40px; /* More space */ font-size: 2em; /* Larger title */ border-bottom: none; /* Remove border */ } .modal.fullscreen .analytics-section { margin-bottom: 30px; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px; background-color: #fff; /* White background for sections */ max-width: 900px; margin-left: auto; margin-right: auto; } .modal.fullscreen .analytics-section:last-of-type { border-bottom: 1px solid #e0e0e0; /* Keep border */ } .modal.fullscreen .analytics-section h3 { color: #555; margin-top: 0; margin-bottom: 15px; font-size: 1.4em; border-bottom: 1px solid #eee; padding-bottom: 10px; } .modal.fullscreen .analytics-section p { font-size: 1.1em; margin-bottom: 10px; } .modal.fullscreen .analytics-section span { font-weight: normal; color: #333; } /* Styles for Navigation Buttons inside Fullscreen Modal */ .modal.fullscreen .modal-navigation { margin-top: 40px; padding-top: 30px; border-top: 1px solid #ccc; text-align: center; display: flex; justify-content: center; gap: 25px; max-width: 900px; margin-left: auto; margin-right: auto; } .modal.fullscreen .modal-nav-btn { padding: 12px 30px; border: none; border-radius: 6px; cursor: pointer; font-size: 1.1em; font-weight: bold; transition: background-color 0.3s ease, transform 0.2s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .modal.fullscreen .modal-nav-btn.dashboard { background-color: #ffc107; color: #333; } .modal.fullscreen .modal-nav-btn.dashboard:hover { background-color: #e0a800; transform: translateY(-1px); } .modal.fullscreen .modal-nav-btn.home { background-color: #17a2b8; color: white; } .modal.fullscreen .modal-nav-btn.home:hover { background-color: #138496; transform: translateY(-1px); } .modal.fullscreen .modal-nav-btn.logout { background-color: #dc3545; color: white; } .modal.fullscreen .modal-nav-btn.logout:hover { background-color: #c82333; transform: translateY(-1px); } /* --- Other Styles --- */ .button-container { margin-bottom: 30px; text-align: center; /* Center buttons */ } .btn { padding: 12px 25px; /* Larger buttons */ background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 1em; /* Adjust font size */ margin: 5px; /* Use margin for spacing */ transition: background-color 0.3s ease, box-shadow 0.2s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .btn:hover { background-color: #45a049; box-shadow: 0 4px 8px rgba(0,0,0,0.15); } .btn.delete { /* Consistent naming */ background-color: #f44336; } .btn.delete:hover { background-color: #da190b; } .btn.edit { /* Style for edit buttons */ background-color: #ffc107; color: #333; padding: 5px 10px; /* Smaller edit buttons */ font-size: 0.8em; margin-left: 10px; vertical-align: middle; } .btn.edit:hover { background-color: #e0a800; } label { display: block; margin-bottom: 8px; /* More space */ font-weight: bold; color: #555; } input[type="text"], textarea, select { width: 100%; /* Use 100% width */ padding: 12px; /* More padding */ margin-bottom: 18px; /* More space */ border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; font-size: 1em; } textarea { resize: vertical; min-height: 100px; /* Minimum height */ } select { margin-bottom: 25px; } .question-container { border: 1px solid #e0e0e0; padding: 20px; margin-bottom: 20px; border-radius: 5px; background-color: #f9f9f9; } .question-container h4 { margin-top: 0; margin-bottom: 15px; color: #666; font-size: 0.9em; text-transform: uppercase; } .question-container input[type="text"] { margin-bottom: 12px; } .multiple-choice-container { margin-top: 15px; padding-left: 15px; border-left: 3px solid #4CAF50; } .multiple-choice-container label { font-weight: normal; margin-bottom: 8px; } .multiple-choice-container input[type="text"] { width: calc(100% - 15px); /* Adjust width */ margin-left: 0; /* Remove indent */ } /* Display Area Styling */ #createdLessons, #createdQuizzes { margin-top: 15px; } #createdLessons div, #createdQuizzes div { background-color: #fff; /* White background */ padding: 15px; margin-bottom: 15px; border-radius: 5px; border: 1px solid #e0e0e0; display: flex; /* Use flexbox for layout */ justify-content: space-between; /* Space out content and button */ align-items: center; /* Vertically align items */ } #createdLessons div > div, #createdQuizzes div > div { flex-grow: 1; /* Allow text content to take available space */ margin-right: 15px; /* Add space between text and button (if any) */ } #createdLessons p, #createdQuizzes p { margin: 0 0 5px 0; /* Adjust margins */ } #createdLessons p strong, #createdQuizzes p strong { font-size: 1.1em; color: #333; } /* Manage Scores Modal Specific Styles */ .manage-scores-container { padding: 10px; } .scores-display-area { margin-top: 20px; border: 1px solid #ccc; padding: 15px; min-height: 100px; max-height: 400px; /* Limit height and allow scroll */ overflow-y: auto; background-color: #f9f9f9; } .scores-display-area table { width: 100%; border-collapse: collapse; margin-top: 10px; /* Add space above table */ } .scores-display-area th, .scores-display-area td { border: 1px solid #ddd; padding: 10px 12px; /* Adjust padding */ text-align: left; font-size: 0.95em; /* Slightly smaller font */ } .scores-display-area th { background-color: #e9e9e9; font-weight: bold; position: sticky; /* Make header sticky */ top: 0; /* Stick to the top of the scrollable area */ z-index: 1; /* Ensure header stays above table content */ } .scores-display-area h4 { /* Style for the quiz title */ margin-bottom: 15px; font-size: 1.2em; color: #333; } .scores-display-area .no-scores-message { font-style: italic; color: #666; text-align: center; padding: 20px; } /* --- Analytics Button (Bottom Right, Red) --- */ .analytics-btn { position: fixed; /* Fixed position */ bottom: 20px; /* Distance from bottom */ right: 20px; /* Distance from right */ padding: 12px 25px; background-color: #dc3545; /* Red color */ color: white; border: none; border-radius: 25px; /* Pill shape */ cursor: pointer; font-size: 15px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); z-index: 999; /* Ensure it's above most content but below modals */ transition: background-color 0.3s ease, transform 0.2s ease; } .analytics-btn:hover { background-color: #c82333; /* Darker red on hover */ transform: translateY(-2px); /* Slight lift on hover */ } document.addEventListener('DOMContentLoaded', () => { // --- Login Check --- const loggedInUsername = sessionStorage.getItem('loggedInUsername'); const loggedInRole = sessionStorage.getItem('loggedInRole'); if (!loggedInUsername || !loggedInRole || loggedInRole !== 'teacher') { alert('Access denied. Please log in as a teacher.'); window.location.href = 'login.html'; // Redirect to login if not a teacher return; } // --- End Login Check --- // --- DOM Elements --- const lessonModal = document.getElementById('lessonModal'); const quizModal = document.getElementById('quizModal'); const deleteModal = document.getElementById('deleteModal'); const manageScoresModal = document.getElementById('manageScoresModal'); const analyticsModal = document.getElementById('analyticsModal'); const createLessonBtn = document.getElementById('createLessonBtn'); const createQuizBtn = document.getElementById('createQuizBtn'); const deleteLessonBtn = document.getElementById('deleteLessonBtn'); const deleteQuizBtn = document.getElementById('deleteQuizBtn'); const manageScoresBtn = document.getElementById('manageScoresBtn'); const analyticsBtn = document.getElementById('analyticsBtn'); const closeButtons = document.querySelectorAll('.close'); // Lesson Form Elements const lessonForm = document.getElementById('lessonForm'); const lessonModalTitle = document.getElementById('lessonModalTitle'); const editLessonIndexInput = document.getElementById('editLessonIndex'); const lessonTitleInput = document.getElementById('lessonTitle'); const lessonContentInput = document.getElementById('lessonContent'); const lessonSubmitBtn = document.getElementById('lessonSubmitBtn'); // Quiz Form Elements const quizForm = document.getElementById('quizForm'); const quizModalTitle = document.getElementById('quizModalTitle'); const editQuizIndexInput = document.getElementById('editQuizIndex'); const quizTypeSelect = document.getElementById('quizType'); const quizTitleInput = document.getElementById('quizTitle'); const questionsContainer = document.getElementById('questionsContainer'); const addQuestionBtn = document.getElementById('addQuestionBtn'); const quizSubmitBtn = document.getElementById('quizSubmitBtn'); // Delete Modal Elements const deleteTypeSelect = document.getElementById('deleteType'); const deleteChoiceSelect = document.getElementById('deleteChoice'); const deleteBtn = document.getElementById('deleteBtn'); // Manage Scores Modal Elements const quizSelectForScores = document.getElementById('quizSelectForScores'); const studentScoresDisplay = document.getElementById('studentScoresDisplay'); // Analytics Modal Elements const lessonCountSpan = document.getElementById('lessonCount'); const quizCountSpan = document.getElementById('quizCount'); const averageQuizScoreSpan = document.getElementById('averageQuizScore'); const modalDashboardBtn = document.getElementById('modalDashboardBtn'); const modalHomeBtn = document.getElementById('modalHomeBtn'); const modalLogoutBtn = document.getElementById('modalLogoutBtn'); // Display Areas const createdLessonsDiv = document.getElementById('createdLessons'); const createdQuizzesDiv = document.getElementById('createdQuizzes'); let questionCount = 0; const storageKeys = { lessons: 'createdLessons', quizzes: 'createdQuizzes', studentResultPrefix: 'studentQuizResults_', // Prefix for student results keys registeredUsers: 'registeredUsers' // Key for all registered users }; // --- Utility Functions --- const openModal = (modal) => { modal.style.display = "block"; if (modal.classList.contains('fullscreen')) { document.body.classList.add('modal-open'); } }; const closeModal = (modal) => { modal.style.display = "none"; if (modal.classList.contains('fullscreen')) { document.body.classList.remove('modal-open'); } // Reset forms/content on modal close if (modal.id === 'lessonModal') resetLessonForm(); if (modal.id === 'quizModal') resetQuizForm(); if (modal.id === 'manageScoresModal') { studentScoresDisplay.innerHTML = '<p class="no-scores-message">Select a quiz to view student scores.</p>'; quizSelectForScores.value = ""; } if (modal.id === 'deleteModal') { deleteTypeSelect.value = 'lesson'; deleteChoiceSelect.innerHTML = '<option value="">-- Select --</option>'; } }; // Gets array data (lessons, quizzes) const getData = (key) => { const data = localStorage.getItem(key); if (data && data.startsWith('[')) { try { return JSON.parse(data); } catch (e) { console.error("Error parsing JSON array from localStorage for key:", key, e); return []; } } return []; }; // Gets object data (registered users, student results) const getObjectData = (key) => { const data = localStorage.getItem(key); if (data && data.startsWith('{')) { try { return JSON.parse(data); } catch (e) { console.error("Error parsing JSON object from localStorage for key:", key, e); return {}; } } return {}; }; const setData = (key, data) => { try { localStorage.setItem(key, JSON.stringify(data)); } catch (e) { console.error("Error setting data to localStorage for key:", key, e); } }; // --- Lesson Functions --- const resetLessonForm = () => { lessonForm.reset(); editLessonIndexInput.value = "-1"; lessonModalTitle.textContent = "Create Lesson"; lessonSubmitBtn.textContent = "Create Lesson"; }; const updateCreatedLessons = () => { const lessons = getData(storageKeys.lessons); createdLessonsDiv.innerHTML = ''; lessons.forEach((lesson, index) => { const lessonDiv = document.createElement('div'); const contentDiv = document.createElement('div'); contentDiv.innerHTML = `<p><strong>${lesson.title}</strong></p><p>${lesson.content.substring(0, 100)}${lesson.content.length > 100 ? '...' : ''}</p>`; lessonDiv.appendChild(contentDiv); const editBtn = document.createElement('button'); editBtn.textContent = 'Edit'; editBtn.classList.add('btn', 'edit'); editBtn.dataset.index = index; editBtn.addEventListener('click', () => editLesson(index)); lessonDiv.appendChild(editBtn); createdLessonsDiv.appendChild(lessonDiv); }); updateDeleteChoices(); // Update delete dropdown after lessons update }; const editLesson = (index) => { const lessons = getData(storageKeys.lessons); if (index >= 0 && index < lessons.length) { const lesson = lessons[index]; resetLessonForm(); editLessonIndexInput.value = index; lessonTitleInput.value = lesson.title; lessonContentInput.value = lesson.content; lessonModalTitle.textContent = "Edit Lesson"; lessonSubmitBtn.textContent = "Save Changes"; openModal(lessonModal); } }; const handleLessonFormSubmit = (event) => { event.preventDefault(); const lessonData = { title: lessonTitleInput.value, content: lessonContentInput.value, }; const editIndex = parseInt(editLessonIndexInput.value, 10); let lessons = getData(storageKeys.lessons); if (editIndex > -1 && editIndex < lessons.length) { lessons[editIndex] = lessonData; alert('Lesson Updated!'); } else { lessons.push(lessonData); alert('Lesson Created!'); } setData(storageKeys.lessons, lessons); closeModal(lessonModal); updateCreatedLessons(); }; // --- Quiz Functions --- const resetQuizForm = () => { quizForm.reset(); editQuizIndexInput.value = "-1"; questionsContainer.innerHTML = ''; questionCount = 0; quizModalTitle.textContent = "Create Quiz"; quizSubmitBtn.textContent = "Create Quiz"; quizTypeSelect.disabled = false; // Re-enable type select toggleMultipleChoiceFields(); // Ensure fields match default type }; const toggleMultipleChoiceFields = () => { const selectedType = quizTypeSelect.value; const allQuestionContainers = questionsContainer.querySelectorAll('.question-container'); allQuestionContainers.forEach(qContainer => { const mcContainer = qContainer.querySelector('.multiple-choice-container'); const choiceInputs = mcContainer ? mcContainer.querySelectorAll('input[type="text"]') : []; const answerInput = qContainer.querySelector('input[name$="-correct-answer"]'); const answerLabel = answerInput ? answerInput.previousElementSibling : null; if (mcContainer) { mcContainer.style.display = selectedType === 'multiple-choice' ? 'block' : 'none'; // Set required only if multiple choice is selected choiceInputs.forEach(input => input.required = (selectedType === 'multiple-choice')); } if (answerLabel && answerLabel.tagName === 'LABEL') { answerLabel.textContent = selectedType === 'identification' ? 'Correct Answer:' : 'Correct Answer (must match one choice):'; } }); }; const addQuestion = (questionData = null) => { const currentQIndex = questionData ? questionData.qIndex : ++questionCount; const questionDiv = document.createElement('div'); questionDiv.classList.add('question-container'); questionDiv.dataset.qIndex = currentQIndex; const qText = questionData ? questionData.questionText : ''; const qAnswer = questionData ? questionData.correctAnswer : ''; const qChoices = questionData ? questionData.choices : ['', '', '', '']; // Default empty choices questionDiv.innerHTML = ` <h4>Question ${currentQIndex}</h4> <label for="question-${currentQIndex}">Question Text:</label> <input type="text" id="question-${currentQIndex}" name="question-${currentQIndex}" value="${qText}" required><br> <div class="multiple-choice-container" style="display: ${quizTypeSelect.value === 'multiple-choice' ? 'block' : 'none'};"> <label>Choices:</label><br> <input type="text" name="question-${currentQIndex}-choice-1" placeholder="Choice 1" value="${qChoices[0] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br> <input type="text" name="question-${currentQIndex}-choice-2" placeholder="Choice 2" value="${qChoices[1] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br> <input type="text" name="question-${currentQIndex}-choice-3" placeholder="Choice 3" value="${qChoices[2] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br> <input type="text" name="question-${currentQIndex}-choice-4" placeholder="Choice 4" value="${qChoices[3] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br> </div> <label for="question-${currentQIndex}-correct-answer">${quizTypeSelect.value === 'identification' ? 'Correct Answer:' : 'Correct Answer (must match one choice):'}</label> <input type="text" name="question-${currentQIndex}-correct-answer" value="${qAnswer}" required><br> `; questionsContainer.appendChild(questionDiv); if (!questionData) questionCount = currentQIndex; // Update global count only for new questions // No need to call toggleMultipleChoiceFields here as it's called on type change and form reset }; const updateCreatedQuizzes = () => { const quizzes = getData(storageKeys.quizzes); createdQuizzesDiv.innerHTML = ''; quizzes.forEach((quiz, index) => { const quizDiv = document.createElement('div'); const contentDiv = document.createElement('div'); // Basic validation before displaying const title = quiz.quizTitle || 'Untitled Quiz'; const type = quiz.quizType || 'N/A'; const numQuestions = Array.isArray(quiz.questions) ? quiz.questions.length : 0; contentDiv.innerHTML = `<p><strong>${title}</strong></p><p>(Type: ${type}, Questions: ${numQuestions})</p>`; quizDiv.appendChild(contentDiv); // No Edit button for quizzes currently createdQuizzesDiv.appendChild(quizDiv); }); updateDeleteChoices(); // Update delete dropdown after quizzes update populateQuizSelectForScores(); // Update scores dropdown after quizzes update }; // Edit Quiz function remains but is not called from UI const editQuiz = (index) => { const quizzes = getData(storageKeys.quizzes); if (index >= 0 && index < quizzes.length) { const quiz = quizzes[index]; resetQuizForm(); editQuizIndexInput.value = index; quizTitleInput.value = quiz.quizTitle; quizTypeSelect.value = quiz.quizType; quizTypeSelect.disabled = true; // Disable type change when editing questionCount = 0; // Reset count for adding existing questions quiz.questions.forEach((q, qIndex) => { addQuestion({ ...q, qIndex: qIndex + 1 }); // Pass existing data }); quizModalTitle.textContent = "Edit Quiz"; quizSubmitBtn.textContent = "Save Changes"; openModal(quizModal); toggleMultipleChoiceFields(); // Ensure fields match loaded quiz type } }; const handleQuizFormSubmit = (event) => { event.preventDefault(); const editIndex = parseInt(editQuizIndexInput.value, 10); const quizType = quizTypeSelect.value; const quizTitle = quizTitleInput.value; const questions = []; const questionElements = questionsContainer.querySelectorAll('.question-container'); const currentQuestionCount = questionElements.length; // Use actual number of question divs for (let i = 0; i < currentQuestionCount; i++) { const qContainer = questionElements[i]; const qIndex = qContainer.dataset.qIndex; // Get index from data attribute const questionText = qContainer.querySelector(`[name='question-${qIndex}']`)?.value.trim(); const correctAnswer = qContainer.querySelector(`[name='question-${qIndex}-correct-answer']`)?.value.trim(); const choices = []; if (!questionText || correctAnswer === undefined || correctAnswer === null || correctAnswer === "") { alert(`Please fill out question text and correct answer for Question ${qIndex}.`); return; } if (quizType === 'multiple-choice') { const choiceInputs = qContainer.querySelectorAll(`.multiple-choice-container input[type="text"]`); let choicesComplete = true; choiceInputs.forEach(input => { const choiceValue = input.value.trim(); if (!choiceValue) choicesComplete = false; choices.push(choiceValue); }); if (!choicesComplete) { alert(`Please fill out all choices for Question ${qIndex}.`); return; } // Ensure the correct answer is one of the choices provided if (!choices.includes(correctAnswer)) { alert(`The correct answer for Question ${qIndex} ("${correctAnswer}") must exactly match one of the provided choices.`); return; } } questions.push({ questionText, choices: quizType === 'multiple-choice' ? choices : [], correctAnswer }); } if (questions.length === 0) { alert('Please add at least one question to the quiz.'); return; } const quizData = { quizType, quizTitle, questions }; let quizzes = getData(storageKeys.quizzes); if (editIndex > -1 && editIndex < quizzes.length) { quizzes[editIndex] = quizData; alert('Quiz Updated!'); } else { quizzes.push(quizData); alert('Quiz Created!'); } setData(storageKeys.quizzes, quizzes); closeModal(quizModal); updateCreatedQuizzes(); }; // --- Delete Functions (Handles both Lessons and Quizzes) --- const updateDeleteChoices = () => { const deleteType = deleteTypeSelect.value; // Read the selected type deleteChoiceSelect.innerHTML = '<option value="">-- Select --</option>'; const items = getData(deleteType === "lesson" ? storageKeys.lessons : storageKeys.quizzes); items.forEach((item, index) => { const option = document.createElement('option'); option.value = index; // Use 'title' for lessons and 'quizTitle' for quizzes, provide fallback option.textContent = item.title || item.quizTitle || `${deleteType.charAt(0).toUpperCase() + deleteType.slice(1)} ${index + 1}`; deleteChoiceSelect.appendChild(option); }); deleteBtn.disabled = items.length === 0; // Disable button if no items }; const handleDelete = () => { const selectedIndex = deleteChoiceSelect.value; const deleteType = deleteTypeSelect.value; // Get the type from the dropdown if (selectedIndex === "") { alert('Please select an item to delete.'); return; } const storageKey = deleteType === 'lesson' ? storageKeys.lessons : storageKeys.quizzes; let items = getData(storageKey); const itemToDelete = items[selectedIndex]; const itemName = itemToDelete?.title || itemToDelete?.quizTitle || `${deleteType} ${parseInt(selectedIndex)+1}`; if (confirm(`Are you sure you want to delete ${deleteType} "${itemName}"? This cannot be undone.`)) { items.splice(selectedIndex, 1); setData(storageKey, items); alert(`${deleteType.charAt(0).toUpperCase() + deleteType.slice(1)} Deleted!`); // Update the correct display area if (deleteType === 'lesson') { updateCreatedLessons(); } else { updateCreatedQuizzes(); // This also updates score/delete dropdowns } closeModal(deleteModal); // Close and reset the modal } }; // --- Manage Scores Functions --- const populateQuizSelectForScores = () => { const quizzes = getData(storageKeys.quizzes); quizSelectForScores.innerHTML = '<option value="">-- Select a Quiz --</option>'; quizzes.forEach((quiz, index) => { const option = document.createElement('option'); option.value = index; // Use the index as the value option.textContent = quiz.quizTitle || `Quiz ${index + 1}`; // Fallback title quizSelectForScores.appendChild(option); }); }; // =============================================================== // START: Enhanced displayStudentScores with Debugging // =============================================================== const displayStudentScores = () => { const selectedQuizIndex = quizSelectForScores.value; studentScoresDisplay.innerHTML = ''; // Clear previous content console.log(`[DEBUG] displayStudentScores called. Selected Quiz Index: '${selectedQuizIndex}'`); if (selectedQuizIndex === "") { studentScoresDisplay.innerHTML = '<p class="no-scores-message">Select a quiz to view student scores.</p>'; console.log("[DEBUG] No quiz selected. Aborting."); return; } const quizzes = getData(storageKeys.quizzes); const selectedQuiz = quizzes[selectedQuizIndex]; if (!selectedQuiz) { console.error(`[DEBUG] Error: Could not find quiz data for index ${selectedQuizIndex}`); studentScoresDisplay.innerHTML = '<p class="no-scores-message">Error: Could not find selected quiz data.</p>'; return; } console.log("[DEBUG] Selected Quiz Data:", selectedQuiz); // --- Get ALL registered users --- const registeredUsers = getObjectData(storageKeys.registeredUsers); console.log("[DEBUG] Raw Registered Users Data from localStorage:", registeredUsers); if (Object.keys(registeredUsers).length === 0) { console.warn("[DEBUG] No registered users found in localStorage key:", storageKeys.registeredUsers); studentScoresDisplay.innerHTML = '<p class="no-scores-message">No registered users found.</p>'; return; } // --- Filter for users with role 'student' --- const studentUsernames = Object.keys(registeredUsers).filter(username => { const user = registeredUsers[username]; // Check if user exists and has a role property equal to 'student' const isStudent = user && user.role === 'student'; if (!isStudent) { console.log(`[DEBUG] Filtering out user '${username}'. Role is not 'student' or user data is malformed. User data:`, user); } return isStudent; }); console.log("[DEBUG] Filtered Student Usernames:", studentUsernames); if (studentUsernames.length === 0) { console.warn("[DEBUG] No users with role 'student' found after filtering."); studentScoresDisplay.innerHTML = '<p class="no-scores-message">No registered students found.</p>'; return; } let tableHTML = ` <h4>Scores for: ${selectedQuiz.quizTitle || 'Untitled Quiz'}</h4> <table> <thead> <tr> <th>Student</th> <th>Score</th> <th>Percentage</th> <th>Date Taken</th> </tr> </thead> <tbody> `; let scoresFound = false; // --- Iterate through each student username --- studentUsernames.forEach(username => { const studentResultKey = `${storageKeys.studentResultPrefix}${username}`; console.log(`[DEBUG] Checking results for student: '${username}' using key: '${studentResultKey}'`); // Get the results object for THIS specific student const studentResults = getObjectData(studentResultKey); console.log(`[DEBUG] Results object fetched for '${username}':`, studentResults); if (Object.keys(studentResults).length === 0) { console.log(`[DEBUG] No results object found for student '${username}' at key '${studentResultKey}'. Skipping.`); return; // Skip to the next student if no results object exists } // Check if THIS student has a result for the SPECIFICALLY selected quiz index const result = studentResults[selectedQuizIndex]; // Use bracket notation console.log(`[DEBUG] Result for quiz index '${selectedQuizIndex}' for student '${username}':`, result); // Validate the result structure before using it if (result && typeof result.score === 'number' && typeof result.total === 'number') { scoresFound = true; const score = result.score; const total = result.total; let percentage = 'N/A'; if (total > 0) { percentage = ((score / total) * 100).toFixed(1) + '%'; } else if (total === 0) { percentage = 'N/A (0 questions)'; } const dateTaken = result.timestamp ? new Date(result.timestamp).toLocaleString() : 'N/A'; console.log(`[DEBUG] Adding row for '${username}': Score=${score}, Total=${total}, Percentage=${percentage}, Date=${dateTaken}`); tableHTML += ` <tr> <td>${username}</td> <td>${score} / ${total}</td> <td>${percentage}</td> <td>${dateTaken}</td> </tr> `; } else { console.log(`[DEBUG] No valid result found for quiz index '${selectedQuizIndex}' for student '${username}' or result format is incorrect.`); } }); // End of studentUsernames.forEach if (!scoresFound) { console.warn("[DEBUG] No scores found for any student for this specific quiz index:", selectedQuizIndex); tableHTML += '<tr><td colspan="4" class="no-scores-message">No students have taken this quiz yet or results are missing.</td></tr>'; } tableHTML += '</tbody></table>'; studentScoresDisplay.innerHTML = tableHTML; console.log("[DEBUG] displayStudentScores finished."); }; // --- Analytics Modal Functions --- const openAnalyticsModal = () => { populateTeacherAnalytics(); openModal(analyticsModal); }; const closeAnalyticsModal = () => { closeModal(analyticsModal); }; const populateTeacherAnalytics = () => { const lessons = getData(storageKeys.lessons); const quizzes = getData(storageKeys.quizzes); lessonCountSpan.textContent = lessons.length; quizCountSpan.textContent = quizzes.length; let totalPercentageSum = 0; let totalQuizzesTakenCount = 0; const registeredUsers = getObjectData(storageKeys.registeredUsers); const studentUsernames = Object.keys(registeredUsers).filter(username => registeredUsers[username]?.role === 'student'); studentUsernames.forEach(username => { const studentResultKey = `${storageKeys.studentResultPrefix}${username}`; const studentResults = getObjectData(studentResultKey); // Iterate through results for this student Object.values(studentResults).forEach(result => { if (result && typeof result.score === 'number' && typeof result.total === 'number' && result.total > 0) { totalPercentageSum += (result.score / result.total) * 100; totalQuizzesTakenCount++; } }); }); if (totalQuizzesTakenCount > 0) { averageQuizScoreSpan.textContent = (totalPercentageSum / totalQuizzesTakenCount).toFixed(1) + '%'; } else { averageQuizScoreSpan.textContent = 'N/A'; } }; // --- Navigation Logic --- function goToHomepage() { window.location.href = 'homepage.html'; // Assuming homepage.html exists } function logout() { sessionStorage.removeItem('loggedInUsername'); sessionStorage.removeItem('loggedInRole'); alert('You have been logged out.'); window.location.href = 'login.html'; // Redirect to login page } // --- Event Listeners --- // Standard Modals Open/Close createLessonBtn.addEventListener('click', () => { resetLessonForm(); openModal(lessonModal); }); createQuizBtn.addEventListener('click', () => { resetQuizForm(); addQuestion(); openModal(quizModal); }); // Add one question by default deleteLessonBtn.addEventListener('click', () => { deleteTypeSelect.value = "lesson"; // Set type updateDeleteChoices(); // Populate choices for lessons openModal(deleteModal); }); deleteQuizBtn.addEventListener('click', () => { deleteTypeSelect.value = "quiz"; // Set type updateDeleteChoices(); // Populate choices for quizzes openModal(deleteModal); }); manageScoresBtn.addEventListener('click', () => { populateQuizSelectForScores(); // Ensure dropdown is up-to-date studentScoresDisplay.innerHTML='<p class="no-scores-message">Select a quiz to view student scores.</p>'; // Reset display openModal(manageScoresModal); }); closeButtons.forEach(button => { button.addEventListener('click', () => { const modalId = button.getAttribute('data-modal-id'); if (modalId) { const modalToClose = document.getElementById(modalId); if (modalToClose) closeModal(modalToClose); } }); }); // Close modal if clicking outside the content (but not on fullscreen modals) window.addEventListener('click', (event) => { if (event.target.classList.contains('modal') && !event.target.classList.contains('fullscreen')) { closeModal(event.target); } }); // Form Submissions lessonForm.addEventListener('submit', handleLessonFormSubmit); quizForm.addEventListener('submit', handleQuizFormSubmit); // Quiz Form - Add Question & Type Change addQuestionBtn.addEventListener('click', () => addQuestion()); quizTypeSelect.addEventListener('change', toggleMultipleChoiceFields); // Delete Modal - Type Change & Delete Button deleteTypeSelect.addEventListener('change', updateDeleteChoices); // Update choices when type changes deleteBtn.addEventListener('click', handleDelete); // Manage Scores Modal - Quiz Selection Change quizSelectForScores.addEventListener('change', displayStudentScores); // Analytics Modal Open/Close/Navigation analyticsBtn.addEventListener('click', openAnalyticsModal); modalDashboardBtn.addEventListener('click', closeAnalyticsModal); modalHomeBtn.addEventListener('click', goToHomepage); modalLogoutBtn.addEventListener('click', logout); // --- Initial Load --- updateCreatedLessons(); updateCreatedQuizzes(); // Load existing quizzes on page load }); (student) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Student Dashboard</title> <link rel="stylesheet" href="student.css"> </head> <body> <!-- Navbar Removed --> <div class="container"> <h1>Student Dashboard</h1> <!-- Quiz Completion Status Message --> <div id="quiz-completion-status" class="completion-notice hidden"> <p>Please complete all available quizzes to view your performance analytics.</p> </div> <!-- Display Created Lessons --> <section id="lessons-section"> <h2>Available Lessons</h2> <!-- Container for lessons where event listener will be attached --> <div id="createdLessons"> <p>Loading lessons...</p> </div> </section> <!-- Display Created Quizzes --> <section id="quizzes-section"> <h2>Available Quizzes</h2> <!-- Container for quizzes where event listener will be attached --> <div id="createdQuizzes"> <p>Loading quizzes...</p> </div> </section> </div> <!-- Performance Analytics Button --> <button id="analyticsBtn" class="analytics-btn" disabled>View Performance & Analytics</button> <!-- Performance Analytics Modal --> <div id="analyticsModal" class="modal"> <div class="modal-content"> <!-- Close Button Removed --> <h2>Performance & Analytics</h2> <div class="analytics-section"> <h3>Activity</h3> <p><strong>Last Accessed:</strong> <span id="lastAccessed">N/A</span></p> </div> <div class="analytics-section"> <h3>Lesson Progress</h3> <ul id="lessonProgressList"> <li>Loading lesson status...</li> </ul> </div> <div class="analytics-section"> <h3>Quiz Scores</h3> <ul id="quizScoresList"> <li>No quizzes taken yet.</li> </ul> </div> <div class="analytics-section"> <h3>Overall Grade</h3> <p><strong id="overallGrade">N/A</strong></p> </div> <!-- Navigation Buttons Inside Modal --> <div class="modal-navigation"> <button id="modalDashboardBtn" class="modal-nav-btn dashboard">Back to Dashboard</button> <button id="modalHomeBtn" class="modal-nav-btn home">Homepage</button> <button id="modalLogoutBtn" class="modal-nav-btn logout">Logout</button> </div> </div> </div> <script src="login.js"></script> <!-- Include for getUsers/saveUsers --> <script src="student.js"></script> </body> </html> /* Navbar Styles Removed */ /* Existing styles below... */ body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 20px 20px 80px 20px; /* Re-added top padding, kept side/bottom */ line-height: 1.6; } /* Prevent body scroll when modal is open */ body.modal-open { overflow: hidden; } .container { max-width: 900px; margin: 20px auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } h1, h2, h3, h4 { color: #333; } h1 { text-align: center; color: #4CAF50; margin-bottom: 30px; } h2 { border-bottom: 2px solid #4CAF50; padding-bottom: 5px; margin-top: 30px; } section { margin-bottom: 30px; } /* Quiz Completion Notice */ .completion-notice { background-color: #fff3cd; color: #856404; border: 1px solid #ffeeba; padding: 15px; margin-bottom: 20px; border-radius: 5px; text-align: center; } .completion-notice p { margin: 0; font-weight: bold; } .lesson, .quiz { border: 1px solid #ddd; background-color: #f9f9f9; padding: 15px; margin-bottom: 15px; border-radius: 5px; position: relative; /* Needed for absolute positioning of button if desired */ } .lesson h4, .quiz h4 { margin-top: 0; color: #555; } /* Lesson Read Button */ .mark-read-btn { padding: 6px 12px; background-color: #17a2b8; /* Teal */ color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; margin-top: 10px; transition: background-color 0.3s ease, opacity 0.3s ease; display: inline-block; /* Or block if needed */ } .mark-read-btn:hover:not(:disabled) { background-color: #138496; } .mark-read-btn:disabled { background-color: #a6d8de; /* Lighter teal */ cursor: not-allowed; opacity: 0.7; } .btn { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; margin-top: 10px; transition: background-color 0.3s ease; } .btn:hover:not(:disabled) { /* Ensure hover only applies when not disabled */ background-color: #45a049; } .btn:disabled { background-color: #ccc; cursor: not-allowed; opacity: 0.6; /* Slightly adjust opacity */ } .submit-quiz-btn { background-color: #007bff; } .submit-quiz-btn:hover:not(:disabled) { background-color: #0056b3; } .quiz-question { margin-top: 20px; padding-top: 15px; border-top: 1px solid #eee; } .quiz-question p strong { display: inline-block; /* Allow span to sit next to it */ margin-bottom: 10px; } /* Answer Input Styling */ .quiz-question input[type="text"] { width: calc(100% - 22px); padding: 10px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .quiz-question .choices label { display: block; margin-bottom: 8px; cursor: pointer; padding: 8px; border-radius: 4px; background-color: #e9e9e9; transition: background-color 0.2s ease; } .quiz-question .choices label:hover { background-color: #dcdcdc; } .quiz-question .choices input[type="radio"] { margin-right: 10px; vertical-align: middle; } /* Score Display */ .quiz-score-area { margin-top: 20px; padding: 15px; background-color: #e3f2fd; border: 1px solid #bbdefb; border-radius: 5px; text-align: center; } .quiz-score-area h3 { margin: 0; color: #0d47a1; } /* Hide elements */ .hidden { display: none; } /* --- Feedback Styles --- */ .feedback-mark { /* Container for the mark */ display: inline-block; /* Allows margin */ margin-left: 8px; font-size: 1.2em; font-weight: bold; vertical-align: middle; /* Align with text */ } .correct-mark { color: green; } .incorrect-mark { color: red; } .correct-answer-highlight { background-color: #c8e6c9 !important; border: 1px solid #a5d6a7; font-weight: bold; } .correct-answer-text { display: block; margin-top: 5px; color: #2e7d32; font-style: italic; font-size: 0.9em; } .incorrect-answer-input { border-color: #e57373 !important; background-color: #ffebee; } .incorrect-choice-selected { background-color: #ffcdd2 !important; border: 1px solid #ef9a9a; text-decoration: line-through; } .quiz-question .choices label.correct-answer-highlight, .quiz-question .choices label.incorrect-choice-selected { opacity: 1; color: #333; } /* --- Analytics Button Style --- */ .analytics-btn { position: fixed; bottom: 20px; right: 20px; padding: 12px 25px; background-color: #6f42c1; /* Purple color */ color: white; border: none; border-radius: 25px; /* Pill shape */ cursor: pointer; font-size: 15px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); z-index: 1000; /* Ensure it's above other content */ transition: background-color 0.3s ease, transform 0.2s ease, opacity 0.3s ease; } .analytics-btn:hover:not(:disabled) { background-color: #5a379b; transform: translateY(-2px); /* Slight lift on hover */ } .analytics-btn:disabled { background-color: #b3a1d1; /* Lighter purple when disabled */ cursor: not-allowed; opacity: 0.7; transform: none; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } /* --- Fullscreen Modal Styles --- */ .modal { display: none; /* Hidden by default */ position: fixed; z-index: 1001; /* Above the button */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: hidden; /* Prevent body scroll when modal is open */ background-color: #fefefe; /* Use solid background instead of overlay */ } .modal-content { background-color: transparent; /* Make content background transparent */ margin: 0; /* Remove margin */ padding: 30px; /* Adjust padding for fullscreen */ border: none; /* Remove border */ width: 100%; /* Full width */ height: 100%; /* Full height */ max-width: none; /* Remove max-width */ border-radius: 0; /* Remove border-radius */ box-shadow: none; /* Remove box-shadow */ position: relative; overflow-y: auto; /* Allow content scrolling */ box-sizing: border-box; /* Include padding in height/width */ } /* Close Button Styles Removed */ /* .close-btn { ... } */ .modal h2 { text-align: center; color: #6f42c1; margin-top: 10px; /* Add some top margin */ margin-bottom: 30px; /* Increase bottom margin */ font-size: 1.8em; /* Larger title */ } .analytics-section { margin-bottom: 25px; /* Increase spacing */ padding-bottom: 20px; border-bottom: 1px solid #eee; max-width: 800px; /* Limit width of content sections */ margin-left: auto; /* Center content sections */ margin-right: auto; } .analytics-section:last-of-type { /* Remove border from last section before nav */ border-bottom: none; } .analytics-section h3 { color: #444; margin-bottom: 15px; font-size: 1.3em; /* Larger section titles */ } #quizScoresList, #lessonProgressList { /* Apply to both lists */ list-style: none; padding: 0; max-height: 30vh; /* Adjust max height relative to viewport */ overflow-y: auto; } #quizScoresList li, #lessonProgressList li { /* Apply to both lists */ background-color: #f9f9f9; padding: 10px 15px; /* Increase padding */ margin-bottom: 8px; /* Increase spacing */ border-radius: 4px; border: 1px solid #eee; font-size: 1em; /* Slightly larger font */ display: flex; /* Use flex for alignment */ justify-content: space-between; /* Space out title and status/score */ align-items: center; } #quizScoresList li strong, #lessonProgressList li strong { /* Apply to both lists */ color: #333; margin-right: 10px; /* Add space between title and value */ } /* Lesson Progress Specific Styles in Modal */ #lessonProgressList .status-completed, #lessonProgressList .status-read { color: green; font-weight: bold; } #lessonProgressList .status-not-started { color: grey; } #overallGrade { font-size: 1.4em; /* Larger grade font */ font-weight: bold; color: #28a745; } /* Styles for Navigation Buttons inside Modal */ .modal-navigation { margin-top: 30px; /* Increase space */ padding-top: 25px; border-top: 1px solid #ccc; /* Slightly darker border */ text-align: center; display: flex; justify-content: center; gap: 20px; /* Increase gap */ max-width: 800px; /* Limit width */ margin-left: auto; margin-right: auto; } .modal-nav-btn { padding: 12px 25px; /* Larger buttons */ border: none; border-radius: 5px; cursor: pointer; font-size: 1em; /* Larger font */ font-weight: bold; transition: background-color 0.3s ease, transform 0.2s ease; } .modal-nav-btn.dashboard { /* Style for the new dashboard button */ background-color: #ffc107; /* Yellow/Orange color */ color: #333; } .modal-nav-btn.dashboard:hover { background-color: #e0a800; transform: translateY(-1px); } .modal-nav-btn.home { background-color: #17a2b8; color: white; } .modal-nav-btn.home:hover { background-color: #138496; transform: translateY(-1px); } .modal-nav-btn.logout { background-color: #dc3545; color: white; } .modal-nav-btn.logout:hover { background-color: #c82333; transform: translateY(-1px); } if (!loggedInUsername || !loggedInRole || loggedInRole !== 'student') { alert('Access denied. Please log in as a student.'); // Ensure login.js is loaded if redirecting to index.html which might be the login page window.location.href = 'index.html'; // Redirect if not a student return; } // --- End Login Check --- // --- DOM Elements --- const createdLessonsDiv = document.getElementById('createdLessons'); const createdQuizzesDiv = document.getElementById('createdQuizzes'); const quizCompletionStatusDiv = document.getElementById('quiz-completion-status'); // Analytics Elements const analyticsBtn = document.getElementById('analyticsBtn'); const analyticsModal = document.getElementById('analyticsModal'); const lastAccessedSpan = document.getElementById('lastAccessed'); const lessonProgressListUl = document.getElementById('lessonProgressList'); // Added for modal const quizScoresListUl = document.getElementById('quizScoresList'); const overallGradeSpan = document.getElementById('overallGrade'); // Modal Navigation Elements const modalDashboardBtn = document.getElementById('modalDashboardBtn'); const modalHomeBtn = document.getElementById('modalHomeBtn'); const modalLogoutBtn = document.getElementById('modalLogoutBtn'); // --- Storage Keys --- const storageKeys = { users: 'users', // Key for the main user object containing all users lessons: 'createdLessons', // Global lessons created by teacher quizzes: 'createdQuizzes', // Global quizzes created by teacher lastAccessed: `studentLastAccessed_${loggedInUsername}` // Student-specific last access }; // --- Utility Functions (Ensure login.js is included for getUsers/saveUsers) --- // getUsers() and saveUsers() are assumed to be available from login.js if (typeof getUsers !== 'function' || typeof saveUsers !== 'function') { console.error("Error: getUsers or saveUsers function not found. Make sure login.js is included before student.js"); alert("A critical error occurred. Please try refreshing the page or logging in again."); // Optionally redirect or disable functionality return; } // --- Get Current Student Data --- // Helper to safely get the current student's data object from the main users store function getCurrentStudentData() { const users = getUsers(); const studentData = users[loggedInUsername]; if (studentData && studentData.role === 'student') { // Initialize progress arrays if they don't exist (robustness) if (!Array.isArray(studentData.quizScores)) { studentData.quizScores = []; } if (!Array.isArray(studentData.lessonProgress)) { studentData.lessonProgress = []; } return studentData; } console.error("Could not find valid student data for username:", loggedInUsername); // Maybe redirect or show error if student data is corrupted/missing alert("Error: Could not load your data. Please try logging in again."); logout(); // Log out if data is missing return null; // Return null to indicate failure } // --- Track Last Accessed --- function recordLastAccessed() { const now = new Date(); localStorage.setItem(storageKeys.lastAccessed, now.toISOString()); } // --- Lesson Display & Tracking --- function updateCreatedLessons() { const globalLessons = JSON.parse(localStorage.getItem(storageKeys.lessons) || '[]'); const studentData = getCurrentStudentData(); if (!studentData) return; // Stop if student data failed to load createdLessonsDiv.innerHTML = ''; // Clear existing lessons if (globalLessons.length === 0) { createdLessonsDiv.innerHTML = '<p>No lessons available.</p>'; return; } globalLessons.forEach((lesson, index) => { // Basic validation const title = lesson.title || 'Untitled Lesson'; const content = lesson.content || 'No content.'; const lessonId = `lesson-${index}`; // Simple ID based on index // Check student's progress for this lesson const progressEntry = studentData.lessonProgress.find(p => p.lessonName === title); const isRead = progressEntry && (progressEntry.status === 'read' || progressEntry.status === 'completed'); // Consider both 'read' and 'completed' as read const lessonDiv = document.createElement('div'); lessonDiv.classList.add('lesson'); lessonDiv.innerHTML = ` <h4>${title}</h4> <p>${content}</p> <button class="mark-read-btn" data-lesson-title="${title}" ${isRead ? 'disabled' : ''}> ${isRead ? 'Read' : 'Mark as Read'} </button> `; createdLessonsDiv.appendChild(lessonDiv); }); } // --- Event Delegation for Lesson Buttons --- createdLessonsDiv.addEventListener('click', (event) => { const target = event.target; if (target.classList.contains('mark-read-btn') && !target.disabled) { const lessonTitle = target.dataset.lessonTitle; markLessonAsRead(lessonTitle, target); } }); function markLessonAsRead(lessonTitle, buttonElement) { const users = getUsers(); const studentData = users[loggedInUsername]; // Get current data again if (!studentData) { alert("Error updating lesson status."); return; } // Ensure lessonProgress array exists if (!Array.isArray(studentData.lessonProgress)) { studentData.lessonProgress = []; } // Find the progress entry or create it let progressEntry = studentData.lessonProgress.find(p => p.lessonName === lessonTitle); if (progressEntry) { progressEntry.status = 'read'; // Update status to 'read' } else { // Add new entry if it doesn't exist studentData.lessonProgress.push({ lessonName: lessonTitle, status: 'read' }); } // Save the updated users object saveUsers(users); // Update the button state buttonElement.disabled = true; buttonElement.textContent = 'Read'; console.log(`Lesson "${lessonTitle}" marked as read for ${loggedInUsername}`); // Optionally, update the analytics modal if it's open if (analyticsModal.style.display === 'block') { populateAnalyticsData(); } } // --- Quiz Display and Taking Logic --- function updateCreatedQuizzes() { console.log("Updating created quizzes display for student:", loggedInUsername); const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]'); const studentData = getCurrentStudentData(); if (!studentData) return; // Stop if student data failed to load createdQuizzesDiv.innerHTML = ''; // Clear previous content if (globalQuizzes.length === 0) { createdQuizzesDiv.innerHTML = '<p>No quizzes available.</p>'; checkAndEnforceQuizCompletion(); // Check even if no quizzes return; } globalQuizzes.forEach((quiz, index) => { // Basic validation of quiz structure if (!quiz || typeof quiz.quizTitle === 'undefined' || !Array.isArray(quiz.questions)) { console.warn(`Skipping invalid quiz data at index ${index}:`, quiz); return; // Skip rendering this invalid quiz } const quizTitle = quiz.quizTitle || 'Untitled Quiz'; // Check if this student has taken this quiz by looking in their main data const resultData = studentData.quizScores.find(score => score.quizName === quizTitle); const hasTaken = !!resultData; // True if resultData is found console.log(`Quiz Index: ${index}, Title: ${quizTitle}, Has Taken: ${hasTaken}`); const quizDiv = document.createElement('div'); quizDiv.classList.add('quiz'); quizDiv.id = `quiz-${index}`; quizDiv.innerHTML = ` <h4>${quizTitle}</h4> <p>Type: ${quiz.quizType || 'N/A'}</p> <p>Number of questions: ${quiz.questions.length}</p> <button class="btn take-quiz-btn" data-quiz-index="${index}" ${hasTaken ? 'disabled' : ''}>${hasTaken ? 'Quiz Taken' : 'Take Quiz'}</button> <div class="quiz-questions-area" id="quiz-area-${index}" style="display: none;"></div> <div class="quiz-score-area" id="score-area-${index}" style="display: ${hasTaken ? 'block' : 'none'};"> ${hasTaken && resultData ? `<h3>Your Score: ${resultData.score}%</h3>` : ''} </div> `; createdQuizzesDiv.appendChild(quizDiv); }); checkAndEnforceQuizCompletion(); // Check completion after rendering quizzes } // --- Event Delegation for Quiz Buttons --- createdQuizzesDiv.addEventListener('click', (event) => { const target = event.target; // The element that was actually clicked // Check if the clicked element is a "take-quiz-btn" or inside one const takeButton = target.closest('.take-quiz-btn'); if (takeButton && !takeButton.disabled) { console.log("Take Quiz button clicked via delegation for index:", takeButton.dataset.quizIndex); startQuiz(takeButton); // Pass the button element itself return; // Stop further processing for this click } // Check if the clicked element is a "submit-quiz-btn" or inside one const submitButton = target.closest('.submit-quiz-btn'); if (submitButton && !submitButton.disabled) { console.log("Submit Quiz button clicked via delegation for index:", submitButton.dataset.quizIndex); submitQuiz(submitButton); // Pass the button element itself return; // Stop further processing for this click } }); function startQuiz(buttonElement) { // Accepts the button element directly const quizIndex = buttonElement.dataset.quizIndex; console.log('startQuiz called for index:', quizIndex); const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]'); // Validate quiz index and data if (quizIndex === undefined || !globalQuizzes[quizIndex] || !Array.isArray(globalQuizzes[quizIndex].questions)) { console.error(`Invalid quiz index or data for index ${quizIndex}`); alert("Error: Could not load quiz data."); return; } const quiz = globalQuizzes[quizIndex]; const questionsArea = document.getElementById(`quiz-area-${quizIndex}`); const scoreArea = document.getElementById(`score-area-${quizIndex}`); const takeQuizButton = buttonElement; // The button that was clicked if (!questionsArea || !scoreArea) { console.error(`Could not find questionsArea or scoreArea for quiz index ${quizIndex}`); alert("Error: Could not display quiz."); return; } // Hide other open quiz forms if any, and show their "Take Quiz" buttons document.querySelectorAll('.quiz-questions-area').forEach(area => { if (area.id !== `quiz-area-${quizIndex}`) { area.style.display = 'none'; const otherQuizIndex = area.id.split('-')[2]; const otherTakeButton = document.querySelector(`.take-quiz-btn[data-quiz-index="${otherQuizIndex}"]`); // Check if the other quiz has been taken using the main student data const studentData = getCurrentStudentData(); const otherQuizTitle = globalQuizzes[otherQuizIndex]?.quizTitle; const otherQuizTaken = studentData?.quizScores.some(s => s.quizName === otherQuizTitle); if (otherTakeButton && !otherQuizTaken) { // Only show if not already taken otherTakeButton.style.display = 'inline-block'; } } }); questionsArea.innerHTML = ''; // Clear previous content if any scoreArea.innerHTML = ''; // Clear score area scoreArea.style.display = 'none'; // Hide score area questionsArea.style.display = 'block'; // Show questions area takeQuizButton.style.display = 'none'; // Hide the clicked "Take Quiz" button quiz.questions.forEach((question, qIndex) => { // Basic validation of question structure if (!question || typeof question.questionText === 'undefined') { console.warn(`Skipping invalid question data at qIndex ${qIndex} for quiz ${quizIndex}:`, question); return; // Skip rendering invalid question } const questionDiv = document.createElement('div'); questionDiv.classList.add('quiz-question'); let answerHtml = ''; if (quiz.quizType === 'identification') { answerHtml = `<label for="answer-${quizIndex}-${qIndex}">Your Answer:</label><input type="text" id="answer-${quizIndex}-${qIndex}" name="answer-${quizIndex}-${qIndex}" required>`; } else if (quiz.quizType === 'multiple-choice') { answerHtml = '<div class="choices">'; const choices = Array.isArray(question.choices) ? question.choices : []; if (choices.length === 0) { console.warn(`No choices found for multiple-choice question qIndex ${qIndex} in quiz ${quizIndex}`); } // Shuffle choices before displaying (optional, but good practice) const shuffledChoices = [...choices].sort(() => Math.random() - 0.5); shuffledChoices.forEach((choice, cIndex) => { // Ensure choice text is displayed correctly, even if null/undefined const choiceText = (choice !== null && choice !== undefined) ? choice : `Choice ${cIndex + 1}`; // Use the original choice value for the radio button's value attribute const choiceValue = (choice !== null && choice !== undefined) ? choice : `__choice_${cIndex}__`; // Handle potential null/undefined values answerHtml += `<label><input type="radio" name="answer-${quizIndex}-${qIndex}" value="${choiceValue}" id="choice-${quizIndex}-${qIndex}-${cIndex}" required> ${choiceText}</label>`; }); answerHtml += '</div>'; } else { console.warn(`Unsupported quiz type "${quiz.quizType}" for question qIndex ${qIndex} in quiz ${quizIndex}`); answerHtml = '<p><em>Unsupported question type.</em></p>'; } questionDiv.innerHTML = `<p><strong>${qIndex + 1}. ${question.questionText}</strong></p>${answerHtml}`; questionsArea.appendChild(questionDiv); }); // Add submit button only if valid questions were rendered if (questionsArea.children.length > 0 && !questionsArea.querySelector('.submit-quiz-btn')) { const submitButton = document.createElement('button'); submitButton.textContent = 'Submit Quiz'; submitButton.classList.add('btn', 'submit-quiz-btn'); submitButton.dataset.quizIndex = quizIndex; // Listener is handled by delegation, no need to add here questionsArea.appendChild(submitButton); } else if (questionsArea.children.length === 0) { // Handle case where a quiz has no valid questions questionsArea.innerHTML = '<p><em>No valid questions found for this quiz. Cannot submit.</em></p>'; // Optionally re-display the "Take Quiz" button or show a message takeQuizButton.style.display = 'inline-block'; // Show button again takeQuizButton.disabled = true; // Disable it as it's problematic takeQuizButton.textContent = 'Quiz Error'; } } function submitQuiz(buttonElement) { // Accepts the button element directly const quizIndex = buttonElement.dataset.quizIndex; console.log('submitQuiz called for index:', quizIndex); const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]'); // Validate quiz index and data if (quizIndex === undefined || !globalQuizzes[quizIndex] || !Array.isArray(globalQuizzes[quizIndex].questions)) { console.error(`Invalid quiz index or data for submission: ${quizIndex}`); alert("Error: Could not submit quiz data."); return; } const quiz = globalQuizzes[quizIndex]; const questionsArea = buttonElement.closest('.quiz-questions-area'); // Find parent question area const scoreArea = document.getElementById(`score-area-${quizIndex}`); if (!questionsArea || !scoreArea) { console.error("Could not find questions or score area for quiz index:", quizIndex); alert("Error submitting quiz. Please try again."); return; } let score = 0; let allAnswered = true; // Filter out potentially invalid questions from the quiz data before counting/iterating const validQuestions = quiz.questions.filter(q => q && typeof q.questionText !== 'undefined'); const totalValidQuestions = validQuestions.length; // Clear previous feedback before evaluating questionsArea.querySelectorAll('.feedback-mark, .correct-answer-text').forEach(el => el.remove()); questionsArea.querySelectorAll('.correct-answer-highlight, .incorrect-choice-selected, .incorrect-answer-input').forEach(el => { el.classList.remove('correct-answer-highlight', 'incorrect-choice-selected', 'incorrect-answer-input'); if (el.tagName === 'LABEL') { el.style.textDecoration = 'none'; } }); // Re-enable inputs temporarily for validation, disable later questionsArea.querySelectorAll('input[type="text"], input[type="radio"]').forEach(input => input.disabled = false); // Iterate through each *valid* question defined in the quiz data validQuestions.forEach((question, qIndex) => { let studentAnswer = null; const correctAnswer = question.correctAnswer; // Find the corresponding question element in the DOM based on its position among valid questions const questionElement = questionsArea.querySelector(`.quiz-question:nth-child(${qIndex + 1})`); // Assumes DOM order matches validQuestions order const questionNumberElement = questionElement ? questionElement.querySelector('p strong') : null; if (!questionElement || !questionNumberElement) { console.warn(`Could not find question element in DOM for valid qIndex ${qIndex} during submission in quiz ${quizIndex}`); allAnswered = false; // Consider it unanswered if the element is missing return; // Skip this question } // --- Get Student Answer and Validate --- if (quiz.quizType === 'identification') { const inputElement = questionElement.querySelector(`input[type="text"]`); if (!inputElement) { console.warn(`Missing input element for identification qIndex ${qIndex}`); allAnswered = false; return; } studentAnswer = inputElement.value.trim(); if (studentAnswer === "") allAnswered = false; else if (correctAnswer !== undefined && correctAnswer !== null && studentAnswer.toLowerCase() === String(correctAnswer).toLowerCase()) score++; } else if (quiz.quizType === 'multiple-choice') { const checkedRadio = questionElement.querySelector(`input[type="radio"]:checked`); if (!checkedRadio) allAnswered = false; else { studentAnswer = checkedRadio.value; if (studentAnswer === String(correctAnswer)) score++; } } }); // End of validQuestions.forEach for validation // --- Check if all questions were answered --- if (!allAnswered) { alert('Please answer all questions before submitting.'); questionsArea.querySelectorAll('input[type="text"], input[type="radio"]').forEach(input => input.disabled = false); // Re-enable return; // Stop submission } // --- If all answered, proceed to show feedback and save --- // Disable all inputs now that submission is final questionsArea.querySelectorAll('input[type="text"], input[type="radio"]').forEach(input => input.disabled = true); // Iterate again through valid questions to apply feedback styles validQuestions.forEach((question, qIndex) => { const questionElement = questionsArea.querySelector(`.quiz-question:nth-child(${qIndex + 1})`); if (!questionElement) return; const questionNumberElement = questionElement.querySelector('p strong'); const correctAnswer = question.correctAnswer; let studentAnswer = null; let isCorrect = false; // Re-evaluate for feedback if (quiz.quizType === 'identification') { const inputElement = questionElement.querySelector(`input[type="text"]`); studentAnswer = inputElement ? inputElement.value.trim() : ''; isCorrect = (correctAnswer !== undefined && correctAnswer !== null && studentAnswer.toLowerCase() === String(correctAnswer).toLowerCase()); if (!isCorrect && inputElement) { inputElement.classList.add('incorrect-answer-input'); if (correctAnswer !== undefined && correctAnswer !== null) { const correctAnswerSpan = document.createElement('span'); correctAnswerSpan.classList.add('correct-answer-text'); correctAnswerSpan.textContent = `Correct answer: ${correctAnswer}`; inputElement.parentNode.insertBefore(correctAnswerSpan, inputElement.nextSibling); } } } else if (quiz.quizType === 'multiple-choice') { const radioButtons = questionElement.querySelectorAll(`input[type="radio"]`); const checkedRadio = questionElement.querySelector(`input[type="radio"]:checked`); studentAnswer = checkedRadio ? checkedRadio.value : null; isCorrect = (studentAnswer === String(correctAnswer)); radioButtons.forEach(radio => { const choiceLabel = radio.closest('label'); if (!choiceLabel) return; // Highlight the correct answer's label if (radio.value === String(correctAnswer)) { choiceLabel.classList.add('correct-answer-highlight'); } // If this radio was checked and it's incorrect, style it if (radio.checked && !isCorrect) { choiceLabel.classList.add('incorrect-choice-selected'); choiceLabel.style.textDecoration = 'line-through'; // Add line-through } }); } // Add checkmark or cross if (questionNumberElement) { const feedbackMark = document.createElement('span'); feedbackMark.classList.add('feedback-mark'); feedbackMark.textContent = isCorrect ? '✓' : '✗'; feedbackMark.classList.add(isCorrect ? 'correct-mark' : 'incorrect-mark'); // Ensure no duplicate marks const existingMark = questionNumberElement.querySelector('.feedback-mark'); if (existingMark) existingMark.remove(); questionNumberElement.appendChild(feedbackMark); } }); // End of feedback loop // --- Display Final Score and Save --- const percentageScore = totalValidQuestions > 0 ? Math.round((score / totalValidQuestions) * 100) : 0; scoreArea.innerHTML = `<h3>Your Score: ${percentageScore}%</h3>`; // Show percentage scoreArea.style.display = 'block'; buttonElement.disabled = true; // Disable the submit button permanently buttonElement.textContent = 'Submitted'; // Find the original "Take Quiz" button again and ensure it's disabled and text updated const originalTakeButton = document.querySelector(`.take-quiz-btn[data-quiz-index="${quizIndex}"]`); if (originalTakeButton) { originalTakeButton.disabled = true; originalTakeButton.textContent = 'Quiz Taken'; originalTakeButton.style.display = 'inline-block'; // Ensure it's visible again } // Save the result (percentage score) to the main student data saveQuizResult(quiz.quizTitle || 'Untitled Quiz', percentageScore); checkAndEnforceQuizCompletion(); // Update analytics button status } function saveQuizResult(quizTitle, percentageScore) { const users = getUsers(); const studentData = users[loggedInUsername]; if (!studentData) { console.error("Cannot save quiz result: Student data not found."); return; } // Ensure quizScores array exists if (!Array.isArray(studentData.quizScores)) { studentData.quizScores = []; } // Find if a result for this quiz already exists const existingResultIndex = studentData.quizScores.findIndex(q => q.quizName === quizTitle); const newResult = { quizName: quizTitle, score: percentageScore, // Store the percentage score timestamp: new Date().toISOString() }; if (existingResultIndex > -1) { // Update existing result studentData.quizScores[existingResultIndex] = newResult; console.log("Quiz result updated for:", quizTitle, "for student:", loggedInUsername); } else { // Add new result studentData.quizScores.push(newResult); console.log("Quiz result saved for:", quizTitle, "for student:", loggedInUsername); } // Save the entire updated users object back to localStorage saveUsers(users); } // --- Quiz Completion Enforcement --- function checkAndEnforceQuizCompletion() { const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]'); const studentData = getCurrentStudentData(); if (!studentData) return; // Can't check if data is missing let allValidQuizzesTaken = true; // Filter global quizzes to only include valid ones const validGlobalQuizzes = globalQuizzes.filter(quiz => quiz && typeof quiz.quizTitle !== 'undefined' && Array.isArray(quiz.questions)); if (validGlobalQuizzes.length === 0) { allValidQuizzesTaken = true; // No valid quizzes to take } else { for (const quiz of validGlobalQuizzes) { const quizTitle = quiz.quizTitle; // Check if THIS student has taken this VALID quiz by looking in their data const hasTaken = studentData.quizScores.some(score => score.quizName === quizTitle); if (!hasTaken) { allValidQuizzesTaken = false; break; // Found an untaken, valid quiz } } } console.log("All valid quizzes taken by", loggedInUsername, ":", allValidQuizzesTaken); if (allValidQuizzesTaken) { quizCompletionStatusDiv.classList.add('hidden'); analyticsBtn.disabled = false; // Enable button console.log("Analytics button enabled for", loggedInUsername); } else { quizCompletionStatusDiv.classList.remove('hidden'); analyticsBtn.disabled = true; // Disable button console.log("Analytics button disabled for", loggedInUsername); } } // --- Analytics Modal Logic --- function openAnalyticsModal() { checkAndEnforceQuizCompletion(); // Re-check before opening if (analyticsBtn.disabled) { alert("Please complete all available quizzes before viewing analytics."); return; } populateAnalyticsData(); analyticsModal.style.display = 'block'; document.body.classList.add('modal-open'); // Prevent body scroll } function closeAnalyticsModal() { analyticsModal.style.display = 'none'; document.body.classList.remove('modal-open'); // Allow body scroll again } function populateAnalyticsData() { const studentData = getCurrentStudentData(); if (!studentData) return; // Stop if data is missing // Get last accessed time for this student const lastAccessedISO = localStorage.getItem(storageKeys.lastAccessed); lastAccessedSpan.textContent = lastAccessedISO ? new Date(lastAccessedISO).toLocaleString() : 'Not recorded yet.'; // --- Populate Lesson Progress --- lessonProgressListUl.innerHTML = ''; // Clear previous list const globalLessons = JSON.parse(localStorage.getItem(storageKeys.lessons) || '[]'); if (globalLessons.length > 0) { // Ensure studentData.lessonProgress exists const lessonProgress = Array.isArray(studentData.lessonProgress) ? studentData.lessonProgress : []; globalLessons.forEach(lesson => { const title = lesson.title || 'Untitled Lesson'; const progressEntry = lessonProgress.find(p => p.lessonName === title); const status = progressEntry ? progressEntry.status : 'not started'; const statusClass = `status-${status.toLowerCase().replace(' ', '-')}`; const listItem = document.createElement('li'); listItem.innerHTML = `<strong>${title}:</strong> <span class="${statusClass}">${status}</span>`; lessonProgressListUl.appendChild(listItem); }); } else { lessonProgressListUl.innerHTML = '<li>No lessons available.</li>'; } // --- Populate Quiz Scores --- quizScoresListUl.innerHTML = ''; // Clear previous list const quizScores = studentData.quizScores; // Get scores directly from student data if (quizScores.length === 0) { quizScoresListUl.innerHTML = '<li>No quizzes taken yet.</li>'; overallGradeSpan.textContent = 'N/A'; return; // Exit early if no scores } let totalPercentage = 0; let numberOfQuizzesTaken = 0; // Sort scores alphabetically by quiz name for consistent display quizScores.sort((a, b) => a.quizName.localeCompare(b.quizName)); quizScores.forEach(result => { // Ensure result has expected properties before calculating if (result && typeof result.quizName !== 'undefined' && typeof result.score === 'number') { const listItem = document.createElement('li'); listItem.innerHTML = `<strong>${result.quizName}:</strong> ${result.score}%`; quizScoresListUl.appendChild(listItem); totalPercentage += result.score; numberOfQuizzesTaken++; } else { console.warn(`Invalid score data found in student results:`, result); } }); // Calculate overall grade as the average of the percentage scores of quizzes taken overallGradeSpan.textContent = numberOfQuizzesTaken > 0 ? `${(totalPercentage / numberOfQuizzesTaken).toFixed(1)}%` : 'N/A'; } // --- Navigation Logic --- function goToHomepage() { // Determine homepage based on role if necessary, or assume a general one window.location.href = 'homepage.html'; // Assuming homepage.html exists } function logout() { sessionStorage.removeItem('loggedInUsername'); sessionStorage.removeItem('loggedInRole'); // Also clear student-specific items if desired localStorage.removeItem(storageKeys.lastAccessed); alert('You have been logged out.'); window.location.href = 'index.html'; // Redirect to login page (index.html) } // --- Event Listeners --- if (analyticsBtn) analyticsBtn.addEventListener('click', openAnalyticsModal); if (modalDashboardBtn) modalDashboardBtn.addEventListener('click', closeAnalyticsModal); if (modalHomeBtn) modalHomeBtn.addEventListener('click', goToHomepage); if (modalLogoutBtn) modalLogoutBtn.addEventListener('click', logout); // --- Initial Load --- recordLastAccessed(); // Record access time on load updateCreatedLessons(); updateCreatedQuizzes(); // Initial population and completion check for this student

Okay, I will set up the project structure with the provided HTML, CSS, and JavaScript code for the Teacher and Student dashboards. I'll also create placeholder files for login.html, login.js, and homepage.html as they are referenced in the code.

This setup uses localStorage to share data (lessons, quizzes, user information) between the teacher and student views and sessionStorage to manage the logged-in user's state.

<jitProject id="teacher-student-dashboard" title="Teacher and Student Dashboards"> <jitFile type="file" filePath="teacher.html"> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Teacher Dashboard</title> <link rel="stylesheet" href="teacher.css"> </head> <body>
    <div class="navbar">
        <h1>Teacher Dashboard</h1>
    </div>

    <div class="container">
        <div class="button-container">
            <button class="btn" id="createLessonBtn">Create Lesson</button>
            <button class="btn" id="createQuizBtn">Make Quiz</button>
            <button class="btn" id="manageScoresBtn">Manage Scores & Grades</button>
            <button class="btn" id="deleteLessonBtn">Delete Lesson</button>
            <button class="btn" id="deleteQuizBtn">Delete Quiz</button> <!-- Delete Quiz Button Re-added -->
        </div>

        <h3>Created Lessons</h3>
        <div id="createdLessons"></div>

        <h3>Created Quizzes</h3>
        <div id="createdQuizzes"></div>
    </div>

    <!-- Lesson Modal (Create/Edit) -->
    <div id="lessonModal" class="modal">
        <div class="modal-content">
            <span class="close" data-modal-id="lessonModal">&times;</span>
            <h2 id="lessonModalTitle">Create Lesson</h2>
            <form id="lessonForm">
                <input type="hidden" id="editLessonIndex" value="-1">
                <label for="lessonTitle">Lesson Title:</label>
                <input type="text" id="lessonTitle" name="lessonTitle" required><br><br>
                <label for="lessonContent">Lesson Content:</label>
                <textarea id="lessonContent" name="lessonContent" rows="4" required></textarea><br><br>
                <button type="submit" id="lessonSubmitBtn" class="btn">Create Lesson</button>
            </form>
        </div>
    </div>

    <!-- Quiz Modal (Create/Edit) -->
    <div id="quizModal" class="modal">
        <div class="modal-content large">
            <span class="close" data-modal-id="quizModal">&times;</span>
            <h2 id="quizModalTitle">Create Quiz</h2>
            <form id="quizForm">
                 <input type="hidden" id="editQuizIndex" value="-1">
                <label for="quizType">Quiz Type:</label>
                <select id="quizType" name="quizType" required>
                    <option value="multiple-choice">Multiple Choice</option>
                    <option value="identification">Identification</option>
                </select><br><br>
                <label for="quizTitle">Quiz Title:</label>
                <input type="text" id="quizTitle" name="quizTitle" required><br><br>
                <div id="questionsContainer"></div>
                <button type="button" class="btn" id="addQuestionBtn">Add Question</button><br><br>
                <button type="submit" id="quizSubmitBtn" class="btn">Create Quiz</button>
            </form>
        </div>
    </div>

    <!-- Delete Modal (Handles both Lessons and Quizzes) -->
    <div id="deleteModal" class="modal">
        <div class="modal-content">
            <span class="close" data-modal-id="deleteModal">&times;</span>
            <h2>Delete Item</h2> <!-- Generic Title -->
            <label for="deleteType">Item Type:</label> <!-- Generic Label -->
            <select id="deleteType"> <!-- Type Select Re-added -->
                <option value="lesson">Lesson</option>
                <option value="quiz">Quiz</option>
            </select><br><br>
            <label for="deleteChoice">Select Item to Delete:</label> <!-- Generic Label -->
            <select id="deleteChoice"></select><br><br>
            <button id="deleteBtn" class="btn delete">Delete</button>
        </div>
    </div>

    <!-- Manage Scores Modal -->
    <div id="manageScoresModal" class="modal">
        <div class="modal-content large">
             <span class="close" data-modal-id="manageScoresModal">&times;</span>
             <h2>Manage Scores and Grades</h2>
             <div class="manage-scores-container">
                 <label for="quizSelectForScores">Select Quiz:</label>
                 <select id="quizSelectForScores">
                     <option value="">-- Select a Quiz --</option>
                     <!-- Options populated by JS -->
                 </select>

                 <div id="studentScoresDisplay" class="scores-display-area">
                     <p class="no-scores-message">Select a quiz to view student scores.</p>
                     <!-- Table will be inserted here by JS -->
                 </div>
             </div>
        </div>
    </div>


    <!-- Performance Analytics Button -->
    <button id="analyticsBtn" class="analytics-btn">View Performance & Analytics</button>

    <!-- Performance Analytics Fullscreen Modal -->
    <div id="analyticsModal" class="modal fullscreen">
        <div class="modal-content">
            <h2>Teacher Performance & Analytics</h2>
            <div class="analytics-section">
                <h3>Overview</h3>
                <p><strong>Lessons Created:</strong> <span id="lessonCount">0</span></p>
                <p><strong>Quizzes Created:</strong> <span id="quizCount">0</span></p>
            </div>
            <div class="analytics-section">
                 <h3>Class Performance (Example)</h3>
                 <p>Average Quiz Score: <span id="averageQuizScore">N/A</span></p>
                 <!-- More detailed class performance could go here -->
            </div>
            <div class="modal-navigation">
                <button id="modalDashboardBtn" class="modal-nav-btn dashboard">Back to Dashboard</button>
                <button id="modalHomeBtn" class="modal-nav-btn home">Homepage</button>
                <button id="modalLogoutBtn" class="modal-nav-btn logout">Logout</button>
            </div>
        </div>
    </div>

    <script src="login.js"></script> <!-- Include for getUsers -->
    <script src="teacher.js"></script>
</body>
</html>
</jitFile> <jitFile type="file" filePath="teacher.css"> body { font-family: Arial, sans-serif; background-color: #f2f2f2; padding: 0 20px 80px 20px; /* Remove top padding, ensure bottom padding for fixed button */ margin: 0; line-height: 1.6; } /* Prevent body scroll when fullscreen modal is open */ body.modal-open { overflow: hidden; }
.navbar {
    background-color: #4CAF50;
    color: white;
    padding: 15px 20px; /* Slightly more padding */
    margin-bottom: 25px; /* More space */
    border-radius: 0 0 5px 5px; /* Rounded bottom corners */
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.navbar h1 {
    margin: 0;
    text-align: center;
    font-size: 1.8em;
}
.container {
    background-color: #fff;
    padding: 25px;
    border-radius: 8px; /* More rounded */
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    max-width: 1000px; /* Wider container */
    margin: 0 auto 20px auto; /* Center container, reduce bottom margin */
}
.hidden {
    display: none;
}

/* --- Standard Modal Styles --- */
.modal:not(.fullscreen) { /* Apply only to non-fullscreen modals */
    display: none;
    position: fixed;
    z-index: 100;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0, 0, 0, 0.5); /* Darker overlay */
    padding-top: 50px;
}

.modal:not(.fullscreen) .modal-content {
    background-color: #fff;
    margin: 3% auto; /* Adjust vertical margin */
    padding: 25px 30px; /* More padding */
    border: 1px solid #ccc;
    border-radius: 8px;
    width: 90%;
    max-width: 650px; /* Default max-width */
    box-shadow: 0 5px 15px rgba(0,0,0,0.2);
    position: relative; /* For close button */
    animation-name: animatetop;
    animation-duration: 0.4s;
}
 /* Larger modal variant */
.modal:not(.fullscreen) .modal-content.large {
    max-width: 850px;
}


@keyframes animatetop {
  from {top: -300px; opacity: 0}
  to {top: 0; opacity: 1}
}

.close {
    color: #aaa;
    position: absolute; /* Position relative to modal-content */
    top: 10px;
    right: 15px;
    font-size: 30px;
    font-weight: bold;
    line-height: 1;
}
.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}

/* --- Fullscreen Modal Styles --- */
.modal.fullscreen {
    display: none;
    position: fixed;
    z-index: 1001;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #f8f9fa; /* Light background */
}

.modal.fullscreen .modal-content {
    background-color: transparent;
    margin: 0;
    padding: 40px; /* More padding */
    border: none;
    width: 100%;
    height: 100%;
    max-width: none;
    border-radius: 0;
    box-shadow: none;
    position: relative;
    overflow-y: auto;
    box-sizing: border-box;
}

.modal.fullscreen h2 {
    text-align: center;
    color: #6f42c1; /* Keep purple for analytics title */
    margin-top: 10px;
    margin-bottom: 40px; /* More space */
    font-size: 2em; /* Larger title */
    border-bottom: none; /* Remove border */
}

.modal.fullscreen .analytics-section {
    margin-bottom: 30px;
    padding: 20px;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    background-color: #fff; /* White background for sections */
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
}
 .modal.fullscreen .analytics-section:last-of-type {
     border-bottom: 1px solid #e0e0e0; /* Keep border */
 }


.modal.fullscreen .analytics-section h3 {
    color: #555;
    margin-top: 0;
    margin-bottom: 15px;
    font-size: 1.4em;
    border-bottom: 1px solid #eee;
    padding-bottom: 10px;
}
 .modal.fullscreen .analytics-section p {
     font-size: 1.1em;
     margin-bottom: 10px;
 }
 .modal.fullscreen .analytics-section span {
     font-weight: normal;
     color: #333;
 }


/* Styles for Navigation Buttons inside Fullscreen Modal */
.modal.fullscreen .modal-navigation {
    margin-top: 40px;
    padding-top: 30px;
    border-top: 1px solid #ccc;
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 25px;
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
}

.modal.fullscreen .modal-nav-btn {
    padding: 12px 30px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1.1em;
    font-weight: bold;
    transition: background-color 0.3s ease, transform 0.2s ease;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.modal.fullscreen .modal-nav-btn.dashboard {
    background-color: #ffc107;
    color: #333;
}
.modal.fullscreen .modal-nav-btn.dashboard:hover {
    background-color: #e0a800;
    transform: translateY(-1px);
}

.modal.fullscreen .modal-nav-btn.home {
    background-color: #17a2b8;
    color: white;
}
.modal.fullscreen .modal-nav-btn.home:hover {
    background-color: #138496;
    transform: translateY(-1px);
}

.modal.fullscreen .modal-nav-btn.logout {
    background-color: #dc3545;
    color: white;
}
.modal.fullscreen .modal-nav-btn.logout:hover {
    background-color: #c82333;
    transform: translateY(-1px);
}


/* --- Other Styles --- */
.button-container {
    margin-bottom: 30px;
    text-align: center; /* Center buttons */
}
.btn {
    padding: 12px 25px; /* Larger buttons */
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1em; /* Adjust font size */
    margin: 5px; /* Use margin for spacing */
    transition: background-color 0.3s ease, box-shadow 0.2s ease;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.btn:hover {
    background-color: #45a049;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.btn.delete { /* Consistent naming */
    background-color: #f44336;
}
.btn.delete:hover {
    background-color: #da190b;
}
.btn.edit { /* Style for edit buttons */
    background-color: #ffc107;
    color: #333;
    padding: 5px 10px; /* Smaller edit buttons */
    font-size: 0.8em;
    margin-left: 10px;
    vertical-align: middle;
}
.btn.edit:hover {
    background-color: #e0a800;
}


label {
    display: block;
    margin-bottom: 8px; /* More space */
    font-weight: bold;
    color: #555;
}

input[type="text"],
textarea,
select {
    width: 100%; /* Use 100% width */
    padding: 12px; /* More padding */
    margin-bottom: 18px; /* More space */
    border: 1px solid #ccc;
    border-radius: 5px;
    box-sizing: border-box;
    font-size: 1em;
}
textarea {
    resize: vertical;
    min-height: 100px; /* Minimum height */
}

select {
   margin-bottom: 25px;
}

.question-container {
    border: 1px solid #e0e0e0;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 5px;
    background-color: #f9f9f9;
}
 .question-container h4 {
     margin-top: 0;
     margin-bottom: 15px;
     color: #666;
     font-size: 0.9em;
     text-transform: uppercase;
 }

.question-container input[type="text"] {
    margin-bottom: 12px;
}
.multiple-choice-container {
    margin-top: 15px;
    padding-left: 15px;
    border-left: 3px solid #4CAF50;
}
.multiple-choice-container label {
    font-weight: normal;
    margin-bottom: 8px;
}
.multiple-choice-container input[type="text"] {
    width: calc(100% - 15px); /* Adjust width */
    margin-left: 0; /* Remove indent */
}

/* Display Area Styling */
#createdLessons, #createdQuizzes {
    margin-top: 15px;
}

#createdLessons div, #createdQuizzes div {
    background-color: #fff; /* White background */
    padding: 15px;
    margin-bottom: 15px;
    border-radius: 5px;
    border: 1px solid #e0e0e0;
    display: flex; /* Use flexbox for layout */
    justify-content: space-between; /* Space out content and button */
    align-items: center; /* Vertically align items */
}
 #createdLessons div > div, #createdQuizzes div > div {
     flex-grow: 1; /* Allow text content to take available space */
     margin-right: 15px; /* Add space between text and button (if any) */
 }

#createdLessons p, #createdQuizzes p {
    margin: 0 0 5px 0; /* Adjust margins */
}
 #createdLessons p strong, #createdQuizzes p strong {
     font-size: 1.1em;
     color: #333;
 }

/* Manage Scores Modal Specific Styles */
.manage-scores-container {
    padding: 10px;
}
.scores-display-area {
    margin-top: 20px;
    border: 1px solid #ccc;
    padding: 15px;
    min-height: 100px;
    max-height: 400px; /* Limit height and allow scroll */
    overflow-y: auto;
    background-color: #f9f9f9;
}
.scores-display-area table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 10px; /* Add space above table */
}
.scores-display-area th, .scores-display-area td {
    border: 1px solid #ddd;
    padding: 10px 12px; /* Adjust padding */
    text-align: left;
    font-size: 0.95em; /* Slightly smaller font */
}
.scores-display-area th {
    background-color: #e9e9e9;
    font-weight: bold;
    position: sticky; /* Make header sticky */
    top: 0; /* Stick to the top of the scrollable area */
    z-index: 1; /* Ensure header stays above table content */
}
.scores-display-area h4 { /* Style for the quiz title */
    margin-bottom: 15px;
    font-size: 1.2em;
    color: #333;
}
.scores-display-area .no-scores-message {
    font-style: italic;
    color: #666;
    text-align: center;
    padding: 20px;
}


/* --- Analytics Button (Bottom Right, Red) --- */
.analytics-btn {
    position: fixed; /* Fixed position */
    bottom: 20px; /* Distance from bottom */
    right: 20px; /* Distance from right */
    padding: 12px 25px;
    background-color: #dc3545; /* Red color */
    color: white;
    border: none;
    border-radius: 25px; /* Pill shape */
    cursor: pointer;
    font-size: 15px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    z-index: 999; /* Ensure it's above most content but below modals */
    transition: background-color 0.3s ease, transform 0.2s ease;
}

.analytics-btn:hover {
    background-color: #c82333; /* Darker red on hover */
    transform: translateY(-2px); /* Slight lift on hover */
}
</jitFile> <jitFile type="file" filePath="teacher.js"> document.addEventListener('DOMContentLoaded', () => { // --- Login Check --- const loggedInUsername = sessionStorage.getItem('loggedInUsername'); const loggedInRole = sessionStorage.getItem('loggedInRole');
    if (!loggedInUsername || !loggedInRole || loggedInRole !== 'teacher') {
        alert('Access denied. Please log in as a teacher.');
        window.location.href = 'login.html'; // Redirect to login if not a teacher
        return;
    }
    // --- End Login Check ---

    // --- DOM Elements ---
    const lessonModal = document.getElementById('lessonModal');
    const quizModal = document.getElementById('quizModal');
    const deleteModal = document.getElementById('deleteModal');
    const manageScoresModal = document.getElementById('manageScoresModal');
    const analyticsModal = document.getElementById('analyticsModal');

    const createLessonBtn = document.getElementById('createLessonBtn');
    const createQuizBtn = document.getElementById('createQuizBtn');
    const deleteLessonBtn = document.getElementById('deleteLessonBtn');
    const deleteQuizBtn = document.getElementById('deleteQuizBtn');
    const manageScoresBtn = document.getElementById('manageScoresBtn');
    const analyticsBtn = document.getElementById('analyticsBtn');

    const closeButtons = document.querySelectorAll('.close');

    // Lesson Form Elements
    const lessonForm = document.getElementById('lessonForm');
    const lessonModalTitle = document.getElementById('lessonModalTitle');
    const editLessonIndexInput = document.getElementById('editLessonIndex');
    const lessonTitleInput = document.getElementById('lessonTitle');
    const lessonContentInput = document.getElementById('lessonContent');
    const lessonSubmitBtn = document.getElementById('lessonSubmitBtn');

    // Quiz Form Elements
    const quizForm = document.getElementById('quizForm');
    const quizModalTitle = document.getElementById('quizModalTitle');
    const editQuizIndexInput = document.getElementById('editQuizIndex');
    const quizTypeSelect = document.getElementById('quizType');
    const quizTitleInput = document.getElementById('quizTitle');
    const questionsContainer = document.getElementById('questionsContainer');
    const addQuestionBtn = document.getElementById('addQuestionBtn');
    const quizSubmitBtn = document.getElementById('quizSubmitBtn');

    // Delete Modal Elements
    const deleteTypeSelect = document.getElementById('deleteType');
    const deleteChoiceSelect = document.getElementById('deleteChoice');
    const deleteBtn = document.getElementById('deleteBtn');

    // Manage Scores Modal Elements
    const quizSelectForScores = document.getElementById('quizSelectForScores');
    const studentScoresDisplay = document.getElementById('studentScoresDisplay');

    // Analytics Modal Elements
    const lessonCountSpan = document.getElementById('lessonCount');
    const quizCountSpan = document.getElementById('quizCount');
    const averageQuizScoreSpan = document.getElementById('averageQuizScore');
    const modalDashboardBtn = document.getElementById('modalDashboardBtn');
    const modalHomeBtn = document.getElementById('modalHomeBtn');
    const modalLogoutBtn = document.getElementById('modalLogoutBtn');


    // Display Areas
    const createdLessonsDiv = document.getElementById('createdLessons');
    const createdQuizzesDiv = document.getElementById('createdQuizzes');

    let questionCount = 0;
    const storageKeys = {
        lessons: 'createdLessons',
        quizzes: 'createdQuizzes',
        users: 'registeredUsers' // Key for all registered users (replaces studentResultPrefix)
    };

    // --- Utility Functions ---
    const openModal = (modal) => {
        modal.style.display = "block";
        if (modal.classList.contains('fullscreen')) {
            document.body.classList.add('modal-open');
        }
    };

    const closeModal = (modal) => {
        modal.style.display = "none";
        if (modal.classList.contains('fullscreen')) {
            document.body.classList.remove('modal-open');
        }
        // Reset forms/content on modal close
        if (modal.id === 'lessonModal') resetLessonForm();
        if (modal.id === 'quizModal') resetQuizForm();
        if (modal.id === 'manageScoresModal') {
             studentScoresDisplay.innerHTML = '<p class="no-scores-message">Select a quiz to view student scores.</p>';
             quizSelectForScores.value = "";
        }
        if (modal.id === 'deleteModal') {
            deleteTypeSelect.value = 'lesson';
            deleteChoiceSelect.innerHTML = '<option value="">-- Select --</option>';
        }
    };

    // Gets array data (lessons, quizzes)
    const getData = (key) => {
        const data = localStorage.getItem(key);
        if (data && data.startsWith('[')) {
            try {
                return JSON.parse(data);
            } catch (e) {
                console.error("Error parsing JSON array from localStorage for key:", key, e);
                return [];
            }
        }
        return [];
    };

    // Gets object data (registered users) - Reusing getUsers from login.js
    // const getObjectData = (key) => { ... } // Replaced by getUsers() from login.js

    const setData = (key, data) => {
        try {
            localStorage.setItem(key, JSON.stringify(data));
        } catch (e) {
             console.error("Error setting data to localStorage for key:", key, e);
        }
    };

    // --- Lesson Functions ---
    const resetLessonForm = () => {
        lessonForm.reset();
        editLessonIndexInput.value = "-1";
        lessonModalTitle.textContent = "Create Lesson";
        lessonSubmitBtn.textContent = "Create Lesson";
    };

    const updateCreatedLessons = () => {
        const lessons = getData(storageKeys.lessons);
        createdLessonsDiv.innerHTML = '';
        lessons.forEach((lesson, index) => {
            const lessonDiv = document.createElement('div');
            const contentDiv = document.createElement('div');
            contentDiv.innerHTML = `<p><strong>${lesson.title}</strong></p><p>${lesson.content.substring(0, 100)}${lesson.content.length > 100 ? '...' : ''}</p>`;
            lessonDiv.appendChild(contentDiv);

            const editBtn = document.createElement('button');
            editBtn.textContent = 'Edit';
            editBtn.classList.add('btn', 'edit');
            editBtn.dataset.index = index;
            editBtn.addEventListener('click', () => editLesson(index));
            lessonDiv.appendChild(editBtn);

            createdLessonsDiv.appendChild(lessonDiv);
        });
        updateDeleteChoices(); // Update delete dropdown after lessons update
    };

    const editLesson = (index) => {
        const lessons = getData(storageKeys.lessons);
        if (index >= 0 && index < lessons.length) {
            const lesson = lessons[index];
            resetLessonForm();
            editLessonIndexInput.value = index;
            lessonTitleInput.value = lesson.title;
            lessonContentInput.value = lesson.content;
            lessonModalTitle.textContent = "Edit Lesson";
            lessonSubmitBtn.textContent = "Save Changes";
            openModal(lessonModal);
        }
    };

    const handleLessonFormSubmit = (event) => {
        event.preventDefault();
        const lessonData = {
            title: lessonTitleInput.value,
            content: lessonContentInput.value,
        };
        const editIndex = parseInt(editLessonIndexInput.value, 10);
        let lessons = getData(storageKeys.lessons);

        if (editIndex > -1 && editIndex < lessons.length) {
            lessons[editIndex] = lessonData;
            alert('Lesson Updated!');
        } else {
            lessons.push(lessonData);
            alert('Lesson Created!');
        }

        setData(storageKeys.lessons, lessons);
        closeModal(lessonModal);
        updateCreatedLessons();
    };

    // --- Quiz Functions ---
    const resetQuizForm = () => {
        quizForm.reset();
        editQuizIndexInput.value = "-1";
        questionsContainer.innerHTML = '';
        questionCount = 0;
        quizModalTitle.textContent = "Create Quiz";
        quizSubmitBtn.textContent = "Create Quiz";
        quizTypeSelect.disabled = false; // Re-enable type select
        toggleMultipleChoiceFields(); // Ensure fields match default type
    };

    const toggleMultipleChoiceFields = () => {
        const selectedType = quizTypeSelect.value;
        const allQuestionContainers = questionsContainer.querySelectorAll('.question-container');

        allQuestionContainers.forEach(qContainer => {
            const mcContainer = qContainer.querySelector('.multiple-choice-container');
            const choiceInputs = mcContainer ? mcContainer.querySelectorAll('input[type="text"]') : [];
            const answerInput = qContainer.querySelector('input[name$="-correct-answer"]');
            const answerLabel = answerInput ? answerInput.previousElementSibling : null;

            if (mcContainer) {
                mcContainer.style.display = selectedType === 'multiple-choice' ? 'block' : 'none';
                // Set required only if multiple choice is selected
                choiceInputs.forEach(input => input.required = (selectedType === 'multiple-choice'));
            }
             if (answerLabel && answerLabel.tagName === 'LABEL') {
                 answerLabel.textContent = selectedType === 'identification' ? 'Correct Answer:' : 'Correct Answer (must match one choice):';
             }
        });
    };


    const addQuestion = (questionData = null) => {
        const currentQIndex = questionData ? questionData.qIndex : ++questionCount;
        const questionDiv = document.createElement('div');
        questionDiv.classList.add('question-container');
        questionDiv.dataset.qIndex = currentQIndex;

        const qText = questionData ? questionData.questionText : '';
        const qAnswer = questionData ? questionData.correctAnswer : '';
        const qChoices = questionData ? questionData.choices : ['', '', '', '']; // Default empty choices

        questionDiv.innerHTML = `
            <h4>Question ${currentQIndex}</h4>
            <label for="question-${currentQIndex}">Question Text:</label>
            <input type="text" id="question-${currentQIndex}" name="question-${currentQIndex}" value="${qText}" required><br>

            <div class="multiple-choice-container" style="display: ${quizTypeSelect.value === 'multiple-choice' ? 'block' : 'none'};">
                <label>Choices:</label><br>
                <input type="text" name="question-${currentQIndex}-choice-1" placeholder="Choice 1" value="${qChoices[0] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
                <input type="text" name="question-${currentQIndex}-choice-2" placeholder="Choice 2" value="${qChoices[1] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
                <input type="text" name="question-${currentQIndex}-choice-3" placeholder="Choice 3" value="${qChoices[2] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
                <input type="text" name="question-${currentQIndex}-choice-4" placeholder="Choice 4" value="${qChoices[3] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
            </div>

            <label for="question-${currentQIndex}-correct-answer">${quizTypeSelect.value === 'identification' ? 'Correct Answer:' : 'Correct Answer (must match one choice):'}</label>
            <input type="text" name="question-${currentQIndex}-correct-answer" value="${qAnswer}" required><br>
        `;
        questionsContainer.appendChild(questionDiv);
        if (!questionData) questionCount = currentQIndex; // Update global count only for new questions
        // No need to call toggleMultipleChoiceFields here as it's called on type change and form reset
    };

    const updateCreatedQuizzes = () => {
        const quizzes = getData(storage
Updated files
v1
give the full code

Okay, here is the complete code for the Teacher and Student dashboards, including the full JavaScript files and the necessary placeholder files for login and homepage functionality.

<jitProject id="teacher-student-dashboard-full" title="Teacher and Student Dashboards (Full Code)"> <jitFile type="file" filePath="teacher.html"> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Teacher Dashboard</title> <link rel="stylesheet" href="teacher.css"> </head> <body>
    <div class="navbar">
        <h1>Teacher Dashboard</h1>
    </div>

    <div class="container">
        <div class="button-container">
            <button class="btn" id="createLessonBtn">Create Lesson</button>
            <button class="btn" id="createQuizBtn">Make Quiz</button>
            <button class="btn" id="manageScoresBtn">Manage Scores & Grades</button>
            <button class="btn" id="deleteLessonBtn">Delete Lesson</button>
            <button class="btn" id="deleteQuizBtn">Delete Quiz</button> <!-- Delete Quiz Button Re-added -->
        </div>

        <h3>Created Lessons</h3>
        <div id="createdLessons"></div>

        <h3>Created Quizzes</h3>
        <div id="createdQuizzes"></div>
    </div>

    <!-- Lesson Modal (Create/Edit) -->
    <div id="lessonModal" class="modal">
        <div class="modal-content">
            <span class="close" data-modal-id="lessonModal">&times;</span>
            <h2 id="lessonModalTitle">Create Lesson</h2>
            <form id="lessonForm">
                <input type="hidden" id="editLessonIndex" value="-1">
                <label for="lessonTitle">Lesson Title:</label>
                <input type="text" id="lessonTitle" name="lessonTitle" required><br><br>
                <label for="lessonContent">Lesson Content:</label>
                <textarea id="lessonContent" name="lessonContent" rows="4" required></textarea><br><br>
                <button type="submit" id="lessonSubmitBtn" class="btn">Create Lesson</button>
            </form>
        </div>
    </div>

    <!-- Quiz Modal (Create/Edit) -->
    <div id="quizModal" class="modal">
        <div class="modal-content large">
            <span class="close" data-modal-id="quizModal">&times;</span>
            <h2 id="quizModalTitle">Create Quiz</h2>
            <form id="quizForm">
                 <input type="hidden" id="editQuizIndex" value="-1">
                <label for="quizType">Quiz Type:</label>
                <select id="quizType" name="quizType" required>
                    <option value="multiple-choice">Multiple Choice</option>
                    <option value="identification">Identification</option>
                </select><br><br>
                <label for="quizTitle">Quiz Title:</label>
                <input type="text" id="quizTitle" name="quizTitle" required><br><br>
                <div id="questionsContainer"></div>
                <button type="button" class="btn" id="addQuestionBtn">Add Question</button><br><br>
                <button type="submit" id="quizSubmitBtn" class="btn">Create Quiz</button>
            </form>
        </div>
    </div>

    <!-- Delete Modal (Handles both Lessons and Quizzes) -->
    <div id="deleteModal" class="modal">
        <div class="modal-content">
            <span class="close" data-modal-id="deleteModal">&times;</span>
            <h2>Delete Item</h2> <!-- Generic Title -->
            <label for="deleteType">Item Type:</label> <!-- Generic Label -->
            <select id="deleteType"> <!-- Type Select Re-added -->
                <option value="lesson">Lesson</option>
                <option value="quiz">Quiz</option>
            </select><br><br>
            <label for="deleteChoice">Select Item to Delete:</label> <!-- Generic Label -->
            <select id="deleteChoice"></select><br><br>
            <button id="deleteBtn" class="btn delete">Delete</button>
        </div>
    </div>

    <!-- Manage Scores Modal -->
    <div id="manageScoresModal" class="modal">
        <div class="modal-content large">
             <span class="close" data-modal-id="manageScoresModal">&times;</span>
             <h2>Manage Scores and Grades</h2>
             <div class="manage-scores-container">
                 <label for="quizSelectForScores">Select Quiz:</label>
                 <select id="quizSelectForScores">
                     <option value="">-- Select a Quiz --</option>
                     <!-- Options populated by JS -->
                 </select>

                 <div id="studentScoresDisplay" class="scores-display-area">
                     <p class="no-scores-message">Select a quiz to view student scores.</p>
                     <!-- Table will be inserted here by JS -->
                 </div>
             </div>
        </div>
    </div>


    <!-- Performance Analytics Button -->
    <button id="analyticsBtn" class="analytics-btn">View Performance & Analytics</button>

    <!-- Performance Analytics Fullscreen Modal -->
    <div id="analyticsModal" class="modal fullscreen">
        <div class="modal-content">
            <h2>Teacher Performance & Analytics</h2>
            <div class="analytics-section">
                <h3>Overview</h3>
                <p><strong>Lessons Created:</strong> <span id="lessonCount">0</span></p>
                <p><strong>Quizzes Created:</strong> <span id="quizCount">0</span></p>
            </div>
            <div class="analytics-section">
                 <h3>Class Performance</h3>
                 <p>Average Quiz Score (across all students/quizzes): <span id="averageQuizScore">N/A</span></p>
                 <!-- More detailed class performance could go here -->
            </div>
            <div class="modal-navigation">
                <button id="modalDashboardBtn" class="modal-nav-btn dashboard">Back to Dashboard</button>
                <button id="modalHomeBtn" class="modal-nav-btn home">Homepage</button>
                <button id="modalLogoutBtn" class="modal-nav-btn logout">Logout</button>
            </div>
        </div>
    </div>

    <script src="login.js"></script> <!-- Include for getUsers -->
    <script src="teacher.js"></script>
</body>
</html>
</jitFile> <jitFile type="file" filePath="teacher.css"> body { font-family: Arial, sans-serif; background-color: #f2f2f2; padding: 0 20px 80px 20px; /* Remove top padding, ensure bottom padding for fixed button */ margin: 0; line-height: 1.6; } /* Prevent body scroll when fullscreen modal is open */ body.modal-open { overflow: hidden; }
.navbar {
    background-color: #4CAF50;
    color: white;
    padding: 15px 20px; /* Slightly more padding */
    margin-bottom: 25px; /* More space */
    border-radius: 0 0 5px 5px; /* Rounded bottom corners */
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.navbar h1 {
    margin: 0;
    text-align: center;
    font-size: 1.8em;
}
.container {
    background-color: #fff;
    padding: 25px;
    border-radius: 8px; /* More rounded */
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    max-width: 1000px; /* Wider container */
    margin: 0 auto 20px auto; /* Center container, reduce bottom margin */
}
.hidden {
    display: none;
}

/* --- Standard Modal Styles --- */
.modal:not(.fullscreen) { /* Apply only to non-fullscreen modals */
    display: none;
    position: fixed;
    z-index: 100;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0, 0, 0, 0.5); /* Darker overlay */
    padding-top: 50px;
}

.modal:not(.fullscreen) .modal-content {
    background-color: #fff;
    margin: 3% auto; /* Adjust vertical margin */
    padding: 25px 30px; /* More padding */
    border: 1px solid #ccc;
    border-radius: 8px;
    width: 90%;
    max-width: 650px; /* Default max-width */
    box-shadow: 0 5px 15px rgba(0,0,0,0.2);
    position: relative; /* For close button */
    animation-name: animatetop;
    animation-duration: 0.4s;
}
 /* Larger modal variant */
.modal:not(.fullscreen) .modal-content.large {
    max-width: 850px;
}


@keyframes animatetop {
  from {top: -300px; opacity: 0}
  to {top: 0; opacity: 1}
}

.close {
    color: #aaa;
    position: absolute; /* Position relative to modal-content */
    top: 10px;
    right: 15px;
    font-size: 30px;
    font-weight: bold;
    line-height: 1;
}
.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}

/* --- Fullscreen Modal Styles --- */
.modal.fullscreen {
    display: none;
    position: fixed;
    z-index: 1001;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #f8f9fa; /* Light background */
}

.modal.fullscreen .modal-content {
    background-color: transparent;
    margin: 0;
    padding: 40px; /* More padding */
    border: none;
    width: 100%;
    height: 100%;
    max-width: none;
    border-radius: 0;
    box-shadow: none;
    position: relative;
    overflow-y: auto;
    box-sizing: border-box;
}

.modal.fullscreen h2 {
    text-align: center;
    color: #6f42c1; /* Keep purple for analytics title */
    margin-top: 10px;
    margin-bottom: 40px; /* More space */
    font-size: 2em; /* Larger title */
    border-bottom: none; /* Remove border */
}

.modal.fullscreen .analytics-section {
    margin-bottom: 30px;
    padding: 20px;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    background-color: #fff; /* White background for sections */
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
}
 .modal.fullscreen .analytics-section:last-of-type {
     border-bottom: 1px solid #e0e0e0; /* Keep border */
 }


.modal.fullscreen .analytics-section h3 {
    color: #555;
    margin-top: 0;
    margin-bottom: 15px;
    font-size: 1.4em;
    border-bottom: 1px solid #eee;
    padding-bottom: 10px;
}
 .modal.fullscreen .analytics-section p {
     font-size: 1.1em;
     margin-bottom: 10px;
 }
 .modal.fullscreen .analytics-section span {
     font-weight: normal;
     color: #333;
 }


/* Styles for Navigation Buttons inside Fullscreen Modal */
.modal.fullscreen .modal-navigation {
    margin-top: 40px;
    padding-top: 30px;
    border-top: 1px solid #ccc;
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 25px;
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
}

.modal.fullscreen .modal-nav-btn {
    padding: 12px 30px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1.1em;
    font-weight: bold;
    transition: background-color 0.3s ease, transform 0.2s ease;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.modal.fullscreen .modal-nav-btn.dashboard {
    background-color: #ffc107;
    color: #333;
}
.modal.fullscreen .modal-nav-btn.dashboard:hover {
    background-color: #e0a800;
    transform: translateY(-1px);
}

.modal.fullscreen .modal-nav-btn.home {
    background-color: #17a2b8;
    color: white;
}
.modal.fullscreen .modal-nav-btn.home:hover {
    background-color: #138496;
    transform: translateY(-1px);
}

.modal.fullscreen .modal-nav-btn.logout {
    background-color: #dc3545;
    color: white;
}
.modal.fullscreen .modal-nav-btn.logout:hover {
    background-color: #c82333;
    transform: translateY(-1px);
}


/* --- Other Styles --- */
.button-container {
    margin-bottom: 30px;
    text-align: center; /* Center buttons */
}
.btn {
    padding: 12px 25px; /* Larger buttons */
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1em; /* Adjust font size */
    margin: 5px; /* Use margin for spacing */
    transition: background-color 0.3s ease, box-shadow 0.2s ease;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.btn:hover {
    background-color: #45a049;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.btn.delete { /* Consistent naming */
    background-color: #f44336;
}
.btn.delete:hover {
    background-color: #da190b;
}
.btn.edit { /* Style for edit buttons */
    background-color: #ffc107;
    color: #333;
    padding: 5px 10px; /* Smaller edit buttons */
    font-size: 0.8em;
    margin-left: 10px;
    vertical-align: middle;
}
.btn.edit:hover {
    background-color: #e0a800;
}


label {
    display: block;
    margin-bottom: 8px; /* More space */
    font-weight: bold;
    color: #555;
}

input[type="text"],
textarea,
select {
    width: 100%; /* Use 100% width */
    padding: 12px; /* More padding */
    margin-bottom: 18px; /* More space */
    border: 1px solid #ccc;
    border-radius: 5px;
    box-sizing: border-box;
    font-size: 1em;
}
textarea {
    resize: vertical;
    min-height: 100px; /* Minimum height */
}

select {
   margin-bottom: 25px;
}

.question-container {
    border: 1px solid #e0e0e0;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 5px;
    background-color: #f9f9f9;
}
 .question-container h4 {
     margin-top: 0;
     margin-bottom: 15px;
     color: #666;
     font-size: 0.9em;
     text-transform: uppercase;
 }

.question-container input[type="text"] {
    margin-bottom: 12px;
}
.multiple-choice-container {
    margin-top: 15px;
    padding-left: 15px;
    border-left: 3px solid #4CAF50;
}
.multiple-choice-container label {
    font-weight: normal;
    margin-bottom: 8px;
}
.multiple-choice-container input[type="text"] {
    width: calc(100% - 15px); /* Adjust width */
    margin-left: 0; /* Remove indent */
}

/* Display Area Styling */
#createdLessons, #createdQuizzes {
    margin-top: 15px;
}

#createdLessons div, #createdQuizzes div {
    background-color: #fff; /* White background */
    padding: 15px;
    margin-bottom: 15px;
    border-radius: 5px;
    border: 1px solid #e0e0e0;
    display: flex; /* Use flexbox for layout */
    justify-content: space-between; /* Space out content and button */
    align-items: center; /* Vertically align items */
}
 #createdLessons div > div, #createdQuizzes div > div {
     flex-grow: 1; /* Allow text content to take available space */
     margin-right: 15px; /* Add space between text and button (if any) */
 }

#createdLessons p, #createdQuizzes p {
    margin: 0 0 5px 0; /* Adjust margins */
}
 #createdLessons p strong, #createdQuizzes p strong {
     font-size: 1.1em;
     color: #333;
 }

/* Manage Scores Modal Specific Styles */
.manage-scores-container {
    padding: 10px;
}
.scores-display-area {
    margin-top: 20px;
    border: 1px solid #ccc;
    padding: 15px;
    min-height: 100px;
    max-height: 400px; /* Limit height and allow scroll */
    overflow-y: auto;
    background-color: #f9f9f9;
}
.scores-display-area table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 10px; /* Add space above table */
}
.scores-display-area th, .scores-display-area td {
    border: 1px solid #ddd;
    padding: 10px 12px; /* Adjust padding */
    text-align: left;
    font-size: 0.95em; /* Slightly smaller font */
}
.scores-display-area th {
    background-color: #e9e9e9;
    font-weight: bold;
    position: sticky; /* Make header sticky */
    top: 0; /* Stick to the top of the scrollable area */
    z-index: 1; /* Ensure header stays above table content */
}
.scores-display-area h4 { /* Style for the quiz title */
    margin-bottom: 15px;
    font-size: 1.2em;
    color: #333;
}
.scores-display-area .no-scores-message {
    font-style: italic;
    color: #666;
    text-align: center;
    padding: 20px;
}


/* --- Analytics Button (Bottom Right, Red) --- */
.analytics-btn {
    position: fixed; /* Fixed position */
    bottom: 20px; /* Distance from bottom */
    right: 20px; /* Distance from right */
    padding: 12px 25px;
    background-color: #dc3545; /* Red color */
    color: white;
    border: none;
    border-radius: 25px; /* Pill shape */
    cursor: pointer;
    font-size: 15px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    z-index: 999; /* Ensure it's above most content but below modals */
    transition: background-color 0.3s ease, transform 0.2s ease;
}

.analytics-btn:hover {
    background-color: #c82333; /* Darker red on hover */
    transform: translateY(-2px); /* Slight lift on hover */
}
</jitFile> <jitFile type="file" filePath="teacher.js"> document.addEventListener('DOMContentLoaded', () => { // --- Login Check --- const loggedInUsername = sessionStorage.getItem('loggedInUsername'); const loggedInRole = sessionStorage.getItem('loggedInRole');
    if (!loggedInUsername || !loggedInRole || loggedInRole !== 'teacher') {
        alert('Access denied. Please log in as a teacher.');
        window.location.href = 'login.html'; // Redirect to login if not a teacher
        return;
    }
    // --- End Login Check ---

    // --- DOM Elements ---
    const lessonModal = document.getElementById('lessonModal');
    const quizModal = document.getElementById('quizModal');
    const deleteModal = document.getElementById('deleteModal');
    const manageScoresModal = document.getElementById('manageScoresModal');
    const analyticsModal = document.getElementById('analyticsModal');

    const createLessonBtn = document.getElementById('createLessonBtn');
    const createQuizBtn = document.getElementById('createQuizBtn');
    const deleteLessonBtn = document.getElementById('deleteLessonBtn');
    const deleteQuizBtn = document.getElementById('deleteQuizBtn');
    const manageScoresBtn = document.getElementById('manageScoresBtn');
    const analyticsBtn = document.getElementById('analyticsBtn');

    const closeButtons = document.querySelectorAll('.close');

    // Lesson Form Elements
    const lessonForm = document.getElementById('lessonForm');
    const lessonModalTitle = document.getElementById('lessonModalTitle');
    const editLessonIndexInput = document.getElementById('editLessonIndex');
    const lessonTitleInput = document.getElementById('lessonTitle');
    const lessonContentInput = document.getElementById('lessonContent');
    const lessonSubmitBtn = document.getElementById('lessonSubmitBtn');

    // Quiz Form Elements
    const quizForm = document.getElementById('quizForm');
    const quizModalTitle = document.getElementById('quizModalTitle');
    const editQuizIndexInput = document.getElementById('editQuizIndex');
    const quizTypeSelect = document.getElementById('quizType');
    const quizTitleInput = document.getElementById('quizTitle');
    const questionsContainer = document.getElementById('questionsContainer');
    const addQuestionBtn = document.getElementById('addQuestionBtn');
    const quizSubmitBtn = document.getElementById('quizSubmitBtn');

    // Delete Modal Elements
    const deleteTypeSelect = document.getElementById('deleteType');
    const deleteChoiceSelect = document.getElementById('deleteChoice');
    const deleteBtn = document.getElementById('deleteBtn');

    // Manage Scores Modal Elements
    const quizSelectForScores = document.getElementById('quizSelectForScores');
    const studentScoresDisplay = document.getElementById('studentScoresDisplay');

    // Analytics Modal Elements
    const lessonCountSpan = document.getElementById('lessonCount');
    const quizCountSpan = document.getElementById('quizCount');
    const averageQuizScoreSpan = document.getElementById('averageQuizScore');
    const modalDashboardBtn = document.getElementById('modalDashboardBtn');
    const modalHomeBtn = document.getElementById('modalHomeBtn');
    const modalLogoutBtn = document.getElementById('modalLogoutBtn');


    // Display Areas
    const createdLessonsDiv = document.getElementById('createdLessons');
    const createdQuizzesDiv = document.getElementById('createdQuizzes');

    let questionCount = 0;
    const storageKeys = {
        lessons: 'createdLessons',
        quizzes: 'createdQuizzes',
        users: 'registeredUsers' // Key for all registered users (replaces studentResultPrefix)
    };

    // --- Utility Functions ---
    const openModal = (modal) => {
        modal.style.display = "block";
        if (modal.classList.contains('fullscreen')) {
            document.body.classList.add('modal-open');
        }
    };

    const closeModal = (modal) => {
        modal.style.display = "none";
        if (modal.classList.contains('fullscreen')) {
            document.body.classList.remove('modal-open');
        }
        // Reset forms/content on modal close
        if (modal.id === 'lessonModal') resetLessonForm();
        if (modal.id === 'quizModal') resetQuizForm();
        if (modal.id === 'manageScoresModal') {
             studentScoresDisplay.innerHTML = '<p class="no-scores-message">Select a quiz to view student scores.</p>';
             quizSelectForScores.value = "";
        }
        if (modal.id === 'deleteModal') {
            deleteTypeSelect.value = 'lesson';
            deleteChoiceSelect.innerHTML = '<option value="">-- Select --</option>';
        }
    };

    // Gets array data (lessons, quizzes)
    const getData = (key) => {
        const data = localStorage.getItem(key);
        if (data && data.startsWith('[')) {
            try {
                return JSON.parse(data);
            } catch (e) {
                console.error("Error parsing JSON array from localStorage for key:", key, e);
                return [];
            }
        }
        return [];
    };

    // Gets object data (registered users) - Reusing getUsers from login.js
    // Ensure login.js is loaded first and getUsers is available globally
    if (typeof getUsers !== 'function') {
        console.error("Error: getUsers function not found. Make sure login.js is included before teacher.js");
        alert("A critical error occurred. Please try refreshing the page or logging in again.");
        // Optionally disable functionality or redirect
        return;
    }

    const setData = (key, data) => {
        try {
            localStorage.setItem(key, JSON.stringify(data));
        } catch (e) {
             console.error("Error setting data to localStorage for key:", key, e);
        }
    };

    // --- Lesson Functions ---
    const resetLessonForm = () => {
        lessonForm.reset();
        editLessonIndexInput.value = "-1";
        lessonModalTitle.textContent = "Create Lesson";
        lessonSubmitBtn.textContent = "Create Lesson";
    };

    const updateCreatedLessons = () => {
        const lessons = getData(storageKeys.lessons);
        createdLessonsDiv.innerHTML = '';
        lessons.forEach((lesson, index) => {
            const lessonDiv = document.createElement('div');
            const contentDiv = document.createElement('div');
            contentDiv.innerHTML = `<p><strong>${lesson.title}</strong></p><p>${lesson.content.substring(0, 100)}${lesson.content.length > 100 ? '...' : ''}</p>`;
            lessonDiv.appendChild(contentDiv);

            const editBtn = document.createElement('button');
            editBtn.textContent = 'Edit';
            editBtn.classList.add('btn', 'edit');
            editBtn.dataset.index = index;
            editBtn.addEventListener('click', () => editLesson(index));
            lessonDiv.appendChild(editBtn);

            createdLessonsDiv.appendChild(lessonDiv);
        });
        updateDeleteChoices(); // Update delete dropdown after lessons update
    };

    const editLesson = (index) => {
        const lessons = getData(storageKeys.lessons);
        if (index >= 0 && index < lessons.length) {
            const lesson = lessons[index];
            resetLessonForm();
            editLessonIndexInput.value = index;
            lessonTitleInput.value = lesson.title;
            lessonContentInput.value = lesson.content;
            lessonModalTitle.textContent = "Edit Lesson";
            lessonSubmitBtn.textContent = "Save Changes";
            openModal(lessonModal);
        }
    };

    const handleLessonFormSubmit = (event) => {
        event.preventDefault();
        const lessonData = {
            title: lessonTitleInput.value,
            content: lessonContentInput.value,
        };
        const editIndex = parseInt(editLessonIndexInput.value, 10);
        let lessons = getData(storageKeys.lessons);

        if (editIndex > -1 && editIndex < lessons.length) {
            lessons[editIndex] = lessonData;
            alert('Lesson Updated!');
        } else {
            lessons.push(lessonData);
            alert('Lesson Created!');
        }

        setData(storageKeys.lessons, lessons);
        closeModal(lessonModal);
        updateCreatedLessons();
    };

    // --- Quiz Functions ---
    const resetQuizForm = () => {
        quizForm.reset();
        editQuizIndexInput.value = "-1";
        questionsContainer.innerHTML = '';
        questionCount = 0;
        quizModalTitle.textContent = "Create Quiz";
        quizSubmitBtn.textContent = "Create Quiz";
        quizTypeSelect.disabled = false; // Re-enable type select
        toggleMultipleChoiceFields(); // Ensure fields match default type
    };

    const toggleMultipleChoiceFields = () => {
        const selectedType = quizTypeSelect.value;
        const allQuestionContainers = questionsContainer.querySelectorAll('.question-container');

        allQuestionContainers.forEach(qContainer => {
            const mcContainer = qContainer.querySelector('.multiple-choice-container');
            const choiceInputs = mcContainer ? mcContainer.querySelectorAll('input[type="text"]') : [];
            const answerInput = qContainer.querySelector('input[name$="-correct-answer"]');
            const answerLabel = answerInput ? answerInput.previousElementSibling : null;

            if (mcContainer) {
                mcContainer.style.display = selectedType === 'multiple-choice' ? 'block' : 'none';
                // Set required only if multiple choice is selected
                choiceInputs.forEach(input => input.required = (selectedType === 'multiple-choice'));
            }
             if (answerLabel && answerLabel.tagName === 'LABEL') {
                 answerLabel.textContent = selectedType === 'identification' ? 'Correct Answer:' : 'Correct Answer (must match one choice):';
             }
        });
    };


    const addQuestion = (questionData = null) => {
        const currentQIndex = questionData ? questionData.qIndex : ++questionCount;
        const questionDiv = document.createElement('div');
        questionDiv.classList.add('question-container');
        questionDiv.dataset.qIndex = currentQIndex;

        const qText = questionData ? questionData.questionText : '';
        const qAnswer = questionData ? questionData.correctAnswer : '';
        const qChoices = questionData ? questionData.choices : ['', '', '', '']; // Default empty choices

        questionDiv.innerHTML = `
            <h4>Question ${currentQIndex}</h4>
            <label for="question-${currentQIndex}">Question Text:</label>
            <input type="text" id="question-${currentQIndex}" name="question-${currentQIndex}" value="${qText}" required><br>

            <div class="multiple-choice-container" style="display: ${quizTypeSelect.value === 'multiple-choice' ? 'block' : 'none'};">
                <label>Choices:</label><br>
                <input type="text" name="question-${currentQIndex}-choice-1" placeholder="Choice 1" value="${qChoices[0] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
                <input type="text" name="question-${currentQIndex}-choice-2" placeholder="Choice 2" value="${qChoices[1] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
                <input type="text" name="question-${currentQIndex}-choice-3" placeholder="Choice 3" value="${qChoices[2] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
                <input type="text" name="question-${currentQIndex}-choice-4" placeholder="Choice 4" value="${qChoices[3] || ''}" ${quizTypeSelect.value === 'multiple-choice' ? 'required' : ''}><br>
            </div>

            <label for="question-${currentQIndex}-correct-answer">${quizTypeSelect.value === 'identification' ? 'Correct Answer:' : 'Correct Answer (must match one choice):'}</label>
            <input type="text" name="question-${currentQIndex}-correct-answer" value="${qAnswer}" required><br>
        `;
        questionsContainer.appendChild(questionDiv);
        if (!questionData) questionCount = currentQIndex; // Update global count only for new questions
        // No need to call toggleMultipleChoiceFields here as it's called on type change and form reset
    };

    const updateCreatedQuizzes = () => {
        const quizzes = getData(storageKeys.quizzes);
        createdQuizzesDiv.innerHTML = '';
        quizzes.forEach((quiz, index) => {
            const quizDiv = document.createElement('div');
            const contentDiv = document.createElement('div');
            // Basic validation before displaying
            const title = quiz.quizTitle || 'Untitled Quiz';
            const type = quiz.quizType || 'N/A';
            const numQuestions = Array.isArray(quiz.questions) ? quiz.questions.length : 0;
            contentDiv.innerHTML = `<p><strong>${title}</strong></p><p>(Type: ${type}, Questions: ${numQuestions})</p>`;
            quizDiv.appendChild(contentDiv);
            // No Edit button for quizzes currently
            createdQuizzesDiv.appendChild(quizDiv);
        });
        updateDeleteChoices(); // Update delete dropdown after quizzes update
        populateQuizSelectForScores(); // Update scores dropdown after quizzes update
    };

    // Edit Quiz function remains but is not called from UI
    const editQuiz = (index) => {
         const quizzes = getData(storageKeys.quizzes);
        if (index >= 0 && index < quizzes.length) {
            const quiz = quizzes[index];
            resetQuizForm();
            editQuizIndexInput.value = index;
            quizTitleInput.value = quiz.quizTitle;
            quizTypeSelect.value = quiz.quizType;
            quizTypeSelect.disabled = true; // Disable type change when editing

            questionCount = 0; // Reset count for adding existing questions
            quiz.questions.forEach((q, qIndex) => {
                addQuestion({ ...q, qIndex: qIndex + 1 }); // Pass existing data
            });

            quizModalTitle.textContent = "Edit Quiz";
            quizSubmitBtn.textContent = "Save Changes";
            openModal(quizModal);
            toggleMultipleChoiceFields(); // Ensure fields match loaded quiz type
        }
    };


    const handleQuizFormSubmit = (event) => {
        event.preventDefault();
        const editIndex = parseInt(editQuizIndexInput.value, 10);
        const quizType = quizTypeSelect.value;
        const quizTitle = quizTitleInput.value;
        const questions = [];
        const questionElements = questionsContainer.querySelectorAll('.question-container');
        const currentQuestionCount = questionElements.length; // Use actual number of question divs

        for (let i = 0; i < currentQuestionCount; i++) {
            const qContainer = questionElements[i];
            const qIndex = qContainer.dataset.qIndex; // Get index from data attribute

            const questionText = qContainer.querySelector(`[name='question-${qIndex}']`)?.value.trim();
            const correctAnswer = qContainer.querySelector(`[name='question-${qIndex}-correct-answer']`)?.value.trim();
            const choices = [];

            if (!questionText || correctAnswer === undefined || correctAnswer === null || correctAnswer === "") {
                alert(`Please fill out question text and correct answer for Question ${qIndex}.`);
                return;
            }

            if (quizType === 'multiple-choice') {
                const choiceInputs = qContainer.querySelectorAll(`.multiple-choice-container input[type="text"]`);
                let choicesComplete = true;
                choiceInputs.forEach(input => {
                    const choiceValue = input.value.trim();
                    if (!choiceValue) choicesComplete = false;
                    choices.push(choiceValue);
                });
                if (!choicesComplete) {
                   alert(`Please fill out all choices for Question ${qIndex}.`);
                   return;
                }
                // Ensure the correct answer is one of the choices provided
                if (!choices.includes(correctAnswer)) {
                    alert(`The correct answer for Question ${qIndex} ("${correctAnswer}") must exactly match one of the provided choices.`);
                    return;
                }
            }
            questions.push({ questionText, choices: quizType === 'multiple-choice' ? choices : [], correctAnswer });
        }

        if (questions.length === 0) {
            alert('Please add at least one question to the quiz.');
            return;
        }

        const quizData = { quizType, quizTitle, questions };
        let quizzes = getData(storageKeys.quizzes);

        if (editIndex > -1 && editIndex < quizzes.length) {
            quizzes[editIndex] = quizData;
            alert('Quiz Updated!');
        } else {
            quizzes.push(quizData);
            alert('Quiz Created!');
        }

        setData(storageKeys.quizzes, quizzes);
        closeModal(quizModal);
        updateCreatedQuizzes();
    };


    // --- Delete Functions (Handles both Lessons and Quizzes) ---
     const updateDeleteChoices = () => {
        const deleteType = deleteTypeSelect.value; // Read the selected type
        deleteChoiceSelect.innerHTML = '<option value="">-- Select --</option>';
        const items = getData(deleteType === "lesson" ? storageKeys.lessons : storageKeys.quizzes);

        items.forEach((item, index) => {
            const option = document.createElement('option');
            option.value = index;
            // Use 'title' for lessons and 'quizTitle' for quizzes, provide fallback
            option.textContent = item.title || item.quizTitle || `${deleteType.charAt(0).toUpperCase() + deleteType.slice(1)} ${index + 1}`;
            deleteChoiceSelect.appendChild(option);
        });
         deleteBtn.disabled = items.length === 0; // Disable button if no items
    };

    const handleDelete = () => {
        const selectedIndex = deleteChoiceSelect.value;
        const deleteType = deleteTypeSelect.value; // Get the type from the dropdown

        if (selectedIndex === "") {
            alert('Please select an item to delete.');
            return;
        }

        const storageKey = deleteType === 'lesson' ? storageKeys.lessons : storageKeys.quizzes;
        let items = getData(storageKey);
        const itemToDelete = items[selectedIndex];
        const itemName = itemToDelete?.title || itemToDelete?.quizTitle || `${deleteType} ${parseInt(selectedIndex)+1}`;


        if (confirm(`Are you sure you want to delete ${deleteType} "${itemName}"? This cannot be undone.`)) {
            items.splice(selectedIndex, 1);
            setData(storageKey, items);
            alert(`${deleteType.charAt(0).toUpperCase() + deleteType.slice(1)} Deleted!`);

            // Update the correct display area
            if (deleteType === 'lesson') {
                updateCreatedLessons();
            } else {
                updateCreatedQuizzes(); // This also updates score/delete dropdowns
            }
            closeModal(deleteModal); // Close and reset the modal
        }
    };

    // --- Manage Scores Functions ---
    const populateQuizSelectForScores = () => {
        const quizzes = getData(storageKeys.quizzes);
        quizSelectForScores.innerHTML = '<option value="">-- Select a Quiz --</option>';
        quizzes.forEach((quiz, index) => {
            const option = document.createElement('option');
            option.value = index; // Use the index as the value
            option.textContent = quiz.quizTitle || `Quiz ${index + 1}`; // Fallback title
            quizSelectForScores.appendChild(option);
        });
    };

    const displayStudentScores = () => {
        const selectedQuizIndex = quizSelectForScores.value;
        studentScoresDisplay.innerHTML = ''; // Clear previous content
        console.log(`[DEBUG] displayStudentScores called. Selected Quiz Index: '${selectedQuizIndex}'`);

        if (selectedQuizIndex === "") {
            studentScoresDisplay.innerHTML = '<p class="no-scores-message">Select a quiz to view student scores.</p>';
            console.log("[DEBUG] No quiz selected. Aborting.");
            return;
        }

        const quizzes = getData(storageKeys.quizzes);
        const selectedQuiz = quizzes[selectedQuizIndex];
        if (!selectedQuiz || !selectedQuiz.quizTitle) {
             console.error(`[DEBUG] Error: Could not find valid quiz data or title for index ${selectedQuizIndex}`);
             studentScoresDisplay.innerHTML = '<p class="no-scores-message">Error: Could not find selected quiz data.</p>';
             return;
        }
        const selectedQuizTitle = selectedQuiz.quizTitle;
        console.log("[DEBUG] Selected Quiz Data:", selectedQuiz);

        // --- Get ALL registered users ---
        const registeredUsers = getUsers(); // Use function from login.js
        console.log("[DEBUG] Raw Registered Users Data from getUsers():", registeredUsers);

        if (Object.keys(registeredUsers).length === 0) {
            console.warn("[DEBUG] No registered users found.");
            studentScoresDisplay.innerHTML = '<p class="no-scores-message">No registered users found.</p>';
            return;
        }

        // --- Filter for users with role 'student' ---
        const studentUsernames = Object.keys(registeredUsers).filter(username => {
            const user = registeredUsers[username];
            const isStudent = user && user.role === 'student';
            if (!isStudent) {
                console.log(`[DEBUG] Filtering out user '${username}'. Role is not 'student' or user data is malformed. User data:`, user);
            }
            return isStudent;
        });
        console.log("[DEBUG] Filtered Student Usernames:", studentUsernames);

        if (studentUsernames.length === 0) {
             console.warn("[DEBUG] No users with role 'student' found after filtering.");
             studentScoresDisplay.innerHTML = '<p class="no-scores-message">No registered students found.</p>';
             return;
        }

        let tableHTML = `
            <h4>Scores for: ${selectedQuizTitle}</h4>
            <table>
                <thead>
                    <tr>
                        <th>Student</th>
                        <th>Score (%)</th>
                        <th>Date Taken</th>
                    </tr>
                </thead>
                <tbody>
        `;
        let scoresFound = false;

        // --- Iterate through each student username ---
        studentUsernames.forEach(username => {
            const studentData = registeredUsers[username];
            console.log(`[DEBUG] Checking results for student: '${username}'`);

            // Check if the student has a quizScores array
            if (studentData && Array.isArray(studentData.quizScores)) {
                // Find the result for the SPECIFICALLY selected quiz TITLE
                const result = studentData.quizScores.find(score => score.quizName === selectedQuizTitle);
                console.log(`[DEBUG] Result for quiz title '${selectedQuizTitle}' for student '${username}':`, result);

                // Validate the result structure before using it
                if (result && typeof result.score === 'number') {
                    scoresFound = true;
                    const scorePercentage = result.score; // Score is already stored as percentage
                    const dateTaken = result.timestamp ? new Date(result.timestamp).toLocaleString() : 'N/A';

                    console.log(`[DEBUG] Adding row for '${username}': Score=${scorePercentage}%, Date=${dateTaken}`);
                    tableHTML += `
                        <tr>
                            <td>${username}</td>
                            <td>${scorePercentage}%</td>
                            <td>${dateTaken}</td>
                        </tr>
                    `;
                } else {
                    console.log(`[DEBUG] No valid result found for quiz title '${selectedQuizTitle}' for student '${username}' or result format is incorrect.`);
                }
            } else {
                console.log(`[DEBUG] No quizScores array found for student '${username}'. Skipping.`);
            }
        }); // End of studentUsernames.forEach

        if (!scoresFound) {
            console.warn("[DEBUG] No scores found for any student for this specific quiz title:", selectedQuizTitle);
            tableHTML += '<tr><td colspan="3" class="no-scores-message">No students have taken this quiz yet or results are missing.</td></tr>';
        }

        tableHTML += '</tbody></table>';
        studentScoresDisplay.innerHTML = tableHTML;
        console.log("[DEBUG] displayStudentScores finished.");
    };


    // --- Analytics Modal Functions ---
    const openAnalyticsModal = () => {
        populateTeacherAnalytics();
        openModal(analyticsModal);
    };

    const closeAnalyticsModal = () => {
        closeModal(analyticsModal);
    };

    const populateTeacherAnalytics = () => {
        const lessons = getData(storageKeys.lessons);
        const quizzes = getData(storageKeys.quizzes);

        lessonCountSpan.textContent = lessons.length;
        quizCountSpan.textContent = quizzes.length;

        let totalPercentageSum = 0;
        let totalQuizzesTakenCount = 0;
        const registeredUsers = getUsers(); // Use function from login.js
        const studentUsernames = Object.keys(registeredUsers).filter(username => registeredUsers[username]?.role === 'student');

        studentUsernames.forEach(username => {
             const studentData = registeredUsers[username];
             if (studentData && Array.isArray(studentData.quizScores)) {
                 // Iterate through results for this student
                 studentData.quizScores.forEach(result => {
                     if (result && typeof result.score === 'number') { // Score is already percentage
                         totalPercentageSum += result.score;
                         totalQuizzesTakenCount++;
                     }
                 });
             }
        });

        if (totalQuizzesTakenCount > 0) {
            averageQuizScoreSpan.textContent = (totalPercentageSum / totalQuizzesTakenCount).toFixed(1) + '%';
        } else {
             averageQuizScoreSpan.textContent = 'N/A';
        }
    };

    // --- Navigation Logic ---
    function goToHomepage() {
        window.location.href = 'homepage.html'; // Assuming homepage.html exists
    }

    function logout() {
        sessionStorage.removeItem('loggedInUsername');
        sessionStorage.removeItem('loggedInRole');
        alert('You have been logged out.');
        window.location.href = 'login.html'; // Redirect to login page
    }


    // --- Event Listeners ---

    // Standard Modals Open/Close
    createLessonBtn.addEventListener('click', () => { resetLessonForm(); openModal(lessonModal); });
    createQuizBtn.addEventListener('click', () => { resetQuizForm(); addQuestion(); openModal(quizModal); }); // Add one question by default
    deleteLessonBtn.addEventListener('click', () => {
        deleteTypeSelect.value = "lesson"; // Set type
        updateDeleteChoices(); // Populate choices for lessons
        openModal(deleteModal);
    });
     deleteQuizBtn.addEventListener('click', () => {
        deleteTypeSelect.value = "quiz"; // Set type
        updateDeleteChoices(); // Populate choices for quizzes
        openModal(deleteModal);
    });
    manageScoresBtn.addEventListener('click', () => {
        populateQuizSelectForScores(); // Ensure dropdown is up-to-date
        studentScoresDisplay.innerHTML='<p class="no-scores-message">Select a quiz to view student scores.</p>'; // Reset display
        openModal(manageScoresModal);
    });

    closeButtons.forEach(button => {
        button.addEventListener('click', () => {
            const modalId = button.getAttribute('data-modal-id');
            if (modalId) {
                const modalToClose = document.getElementById(modalId);
                if (modalToClose) closeModal(modalToClose);
            }
        });
    });
    // Close modal if clicking outside the content (but not on fullscreen modals)
    window.addEventListener('click', (event) => {
        if (event.target.classList.contains('modal') && !event.target.classList.contains('fullscreen')) {
            closeModal(event.target);
        }
    });

    // Form Submissions
    lessonForm.addEventListener('submit', handleLessonFormSubmit);
    quizForm.addEventListener('submit', handleQuizFormSubmit);

    // Quiz Form - Add Question & Type Change
    addQuestionBtn.addEventListener('click', () => addQuestion());
    quizTypeSelect.addEventListener('change', toggleMultipleChoiceFields);

    // Delete Modal - Type Change & Delete Button
    deleteTypeSelect.addEventListener('change', updateDeleteChoices); // Update choices when type changes
    deleteBtn.addEventListener('click', handleDelete);

    // Manage Scores Modal - Quiz Selection Change
    quizSelectForScores.addEventListener('change', displayStudentScores);

    // Analytics Modal Open/Close/Navigation
    analyticsBtn.addEventListener('click', openAnalyticsModal);
    modalDashboardBtn.addEventListener('click', closeAnalyticsModal);
    modalHomeBtn.addEventListener('click', goToHomepage);
    modalLogoutBtn.addEventListener('click', logout);


    // --- Initial Load ---
    updateCreatedLessons();
    updateCreatedQuizzes(); // Load existing quizzes on page load

});
</jitFile> <jitFile type="file" filePath="student.html"> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Student Dashboard</title> <link rel="stylesheet" href="student.css"> </head> <body> <!-- Navbar Removed -->
    <div class="container">
        <h1>Student Dashboard</h1>

        <!-- Quiz Completion Status Message -->
        <div id="quiz-completion-status" class="completion-notice hidden">
            <p>Please complete all available quizzes to view your performance analytics.</p>
        </div>

        <!-- Display Created Lessons -->
        <section id="lessons-section">
            <h2>Available Lessons</h2>
            <!-- Container for lessons where event listener will be attached -->
            <div id="createdLessons">
                <p>Loading lessons...</p>
            </div>
        </section>

        <!-- Display Created Quizzes -->
        <section id="quizzes-section">
            <h2>Available Quizzes</h2>
            <!-- Container for quizzes where event listener will be attached -->
            <div id="createdQuizzes">
                <p>Loading quizzes...</p>
            </div>
        </section>
    </div>

    <!-- Performance Analytics Button -->
    <button id="analyticsBtn" class="analytics-btn" disabled>View Performance & Analytics</button>

    <!-- Performance Analytics Modal -->
    <div id="analyticsModal" class="modal"> <!-- Removed fullscreen class -->
        <div class="modal-content">
            <!-- Close Button Removed -->
            <h2>Performance & Analytics</h2>

            <div class="analytics-section">
                <h3>Activity</h3>
                <p><strong>Last Accessed:</strong> <span id="lastAccessed">N/A</span></p>
            </div>

             <div class="analytics-section">
                <h3>Lesson Progress</h3>
                <ul id="lessonProgressList">
                    <li>Loading lesson status...</li>
                </ul>
            </div>

            <div class="analytics-section">
                <h3>Quiz Scores</h3>
                <ul id="quizScoresList">
                    <li>No quizzes taken yet.</li>
                </ul>
            </div>

            <div class="analytics-section">
                <h3>Overall Grade</h3>
                <p><strong id="overallGrade">N/A</strong></p>
            </div>

            <!-- Navigation Buttons Inside Modal -->
            <div class="modal-navigation">
                <button id="modalDashboardBtn" class="modal-nav-btn dashboard">Back to Dashboard</button>
                <button id="modalHomeBtn" class="modal-nav-btn home">Homepage</button>
                <button id="modalLogoutBtn" class="modal-nav-btn logout">Logout</button>
            </div>
        </div>
    </div>

    <script src="login.js"></script> <!-- Include for getUsers/saveUsers -->
    <script src="student.js"></script>
</body>
</html>
</jitFile> <jitFile type="file" filePath="student.css"> /* Navbar Styles Removed */
/* Existing styles below... */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 20px 20px 80px 20px; /* Re-added top padding, kept side/bottom */
    line-height: 1.6;
}
/* Prevent body scroll when modal is open */
body.modal-open {
    overflow: hidden;
}

.container {
    max-width: 900px;
    margin: 20px auto;
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

h1, h2, h3, h4 {
    color: #333;
}

h1 {
    text-align: center;
    color: #4CAF50;
    margin-bottom: 30px;
}

h2 {
    border-bottom: 2px solid #4CAF50;
    padding-bottom: 5px;
    margin-top: 30px;
}

section {
    margin-bottom: 30px;
}

/* Quiz Completion Notice */
.completion-notice {
    background-color: #fff3cd;
    color: #856404;
    border: 1px solid #ffeeba;
    padding: 15px;
    margin-bottom: 20px;
    border-radius: 5px;
    text-align: center;
}
.completion-notice p {
    margin: 0;
    font-weight: bold;
}


.lesson, .quiz {
    border: 1px solid #ddd;
    background-color: #f9f9f9;
    padding: 15px;
    margin-bottom: 15px;
    border-radius: 5px;
    position: relative; /* Needed for absolute positioning of button if desired */
}

.lesson h4, .quiz h4 {
    margin-top: 0;
    color: #555;
}

/* Lesson Read Button */
.mark-read-btn {
    padding: 6px 12px;
    background-color: #17a2b8; /* Teal */
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    margin-top: 10px;
    transition: background-color 0.3s ease, opacity 0.3s ease;
    display: inline-block; /* Or block if needed */
}

.mark-read-btn:hover:not(:disabled) {
    background-color: #138496;
}

.mark-read-btn:disabled {
    background-color: #a6d8de; /* Lighter teal */
    cursor: not-allowed;
    opacity: 0.7;
}


.btn {
    padding: 10px 20px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
    margin-top: 10px;
    transition: background-color 0.3s ease;
}

.btn:hover:not(:disabled) { /* Ensure hover only applies when not disabled */
    background-color: #45a049;
}

.btn:disabled {
    background-color: #ccc;
    cursor: not-allowed;
    opacity: 0.6; /* Slightly adjust opacity */
}

.submit-quiz-btn {
    background-color: #007bff;
}
.submit-quiz-btn:hover:not(:disabled) {
    background-color: #0056b3;
}


.quiz-question {
    margin-top: 20px;
    padding-top: 15px;
    border-top: 1px solid #eee;
}
.quiz-question p strong {
    display: inline-block; /* Allow span to sit next to it */
    margin-bottom: 10px;
}

/* Answer Input Styling */
.quiz-question input[type="text"] {
    width: calc(100% - 22px);
    padding: 10px;
    margin-top: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

.quiz-question .choices label {
    display: block;
    margin-bottom: 8px;
    cursor: pointer;
    padding: 8px;
    border-radius: 4px;
    background-color: #e9e9e9;
    transition: background-color 0.2s ease;
}
.quiz-question .choices label:hover {
    background-color: #dcdcdc;
}

.quiz-question .choices input[type="radio"] {
    margin-right: 10px;
    vertical-align: middle;
}

/* Score Display */
.quiz-score-area {
    margin-top: 20px;
    padding: 15px;
    background-color: #e3f2fd;
    border: 1px solid #bbdefb;
    border-radius: 5px;
    text-align: center;
}
.quiz-score-area h3 {
    margin: 0;
    color: #0d47a1;
}

/* Hide elements */
.hidden {
    display: none;
}

/* --- Feedback Styles --- */
.feedback-mark { /* Container for the mark */
    display: inline-block; /* Allows margin */
    margin-left: 8px;
    font-size: 1.2em;
    font-weight: bold;
    vertical-align: middle; /* Align with text */
}
.correct-mark {
    color: green;
}

.incorrect-mark {
    color: red;
}

.correct-answer-highlight {
    background-color: #c8e6c9 !important;
    border: 1px solid #a5d6a7;
    font-weight: bold;
}

.correct-answer-text {
    display: block;
    margin-top: 5px;
    color: #2e7d32;
    font-style: italic;
    font-size: 0.9em;
}

.incorrect-answer-input {
    border-color: #e57373 !important;
    background-color: #ffebee;
}

.incorrect-choice-selected {
     background-color: #ffcdd2 !important;
     border: 1px solid #ef9a9a;
     text-decoration: line-through;
}

.quiz-question .choices label.correct-answer-highlight,
.quiz-question .choices label.incorrect-choice-selected {
    opacity: 1;
    color: #333;
}

/* --- Analytics Button Style --- */
.analytics-btn {
    position: fixed;
    bottom: 20px;
    right: 20px;
    padding: 12px 25px;
    background-color: #6f42c1; /* Purple color */
    color: white;
    border: none;
    border-radius: 25px; /* Pill shape */
    cursor: pointer;
    font-size: 15px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    z-index: 1000; /* Ensure it's above other content */
    transition: background-color 0.3s ease, transform 0.2s ease, opacity 0.3s ease;
}

.analytics-btn:hover:not(:disabled) {
    background-color: #5a379b;
    transform: translateY(-2px); /* Slight lift on hover */
}

.analytics-btn:disabled {
    background-color: #b3a1d1; /* Lighter purple when disabled */
    cursor: not-allowed;
    opacity: 0.7;
    transform: none;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}


/* --- Fullscreen Modal Styles --- */
.modal {
    display: none; /* Hidden by default */
    position: fixed;
    z-index: 1001; /* Above the button */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: hidden; /* Prevent body scroll when modal is open */
    background-color: #fefefe; /* Use solid background instead of overlay */
}

.modal-content {
    background-color: transparent; /* Make content background transparent */
    margin: 0; /* Remove margin */
    padding: 30px; /* Adjust padding for fullscreen */
    border: none; /* Remove border */
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    max-width: none; /* Remove max-width */
    border-radius: 0; /* Remove border-radius */
    box-shadow: none; /* Remove box-shadow */
    position: relative;
    overflow-y: auto; /* Allow content scrolling */
    box-sizing: border-box; /* Include padding in height/width */
}

/* Close Button Styles Removed */
/* .close-btn { ... } */

.modal h2 {
    text-align: center;
    color: #6f42c1;
    margin-top: 10px; /* Add some top margin */
    margin-bottom: 30px; /* Increase bottom margin */
    font-size: 1.8em; /* Larger title */
}

.analytics-section {
    margin-bottom: 25px; /* Increase spacing */
    padding-bottom: 20px;
    border-bottom: 1px solid #eee;
    max-width: 800px; /* Limit width of content sections */
    margin-left: auto; /* Center content sections */
    margin-right: auto;
}
.analytics-section:last-of-type { /* Remove border from last section before nav */
     border-bottom: none;
}


.analytics-section h3 {
    color: #444;
    margin-bottom: 15px;
    font-size: 1.3em; /* Larger section titles */
}

#quizScoresList, #lessonProgressList { /* Apply to both lists */
    list-style: none;
    padding: 0;
    max-height: 30vh; /* Adjust max height relative to viewport */
    overflow-y: auto;
}

#quizScoresList li, #lessonProgressList li { /* Apply to both lists */
    background-color: #f9f9f9;
    padding: 10px 15px; /* Increase padding */
    margin-bottom: 8px; /* Increase spacing */
    border-radius: 4px;
    border: 1px solid #eee;
    font-size: 1em; /* Slightly larger font */
    display: flex; /* Use flex for alignment */
    justify-content: space-between; /* Space out title and status/score */
    align-items: center;
}
#quizScoresList li strong, #lessonProgressList li strong { /* Apply to both lists */
    color: #333;
    margin-right: 10px; /* Add space between title and value */
}

/* Lesson Progress Specific Styles in Modal */
#lessonProgressList .status-completed,
#lessonProgressList .status-read { color: green; font-weight: bold; }
#lessonProgressList .status-not-started { color: grey; }


#overallGrade {
    font-size: 1.4em; /* Larger grade font */
    font-weight: bold;
    color: #28a745;
}

/* Styles for Navigation Buttons inside Modal */
.modal-navigation {
    margin-top: 30px; /* Increase space */
    padding-top: 25px;
    border-top: 1px solid #ccc; /* Slightly darker border */
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 20px; /* Increase gap */
    max-width: 800px; /* Limit width */
    margin-left: auto;
    margin-right: auto;
}

.modal-nav-btn {
    padding: 12px 25px; /* Larger buttons */
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1em; /* Larger font */
    font-weight: bold;
    transition: background-color 0.3s ease, transform 0.2s ease;
}

.modal-nav-btn.dashboard { /* Style for the new dashboard button */
    background-color: #ffc107; /* Yellow/Orange color */
    color: #333;
}
.modal-nav-btn.dashboard:hover {
    background-color: #e0a800;
    transform: translateY(-1px);
}

.modal-nav-btn.home {
    background-color: #17a2b8;
    color: white;
}
.modal-nav-btn.home:hover {
    background-color: #138496;
    transform: translateY(-1px);
}

.modal-nav-btn.logout {
    background-color: #dc3545;
    color: white;
}
.modal-nav-btn.logout:hover {
    background-color: #c82333;
    transform: translateY(-1px);
}
</jitFile> <jitFile type="file" filePath="student.js"> document.addEventListener('DOMContentLoaded', () => { // --- Login Check --- const loggedInUsername = sessionStorage.getItem('loggedInUsername'); const loggedInRole = sessionStorage.getItem('loggedInRole');
if (!loggedInUsername || !loggedInRole || loggedInRole !== 'student') {
    alert('Access denied. Please log in as a student.');
    // Ensure login.js is loaded if redirecting to index.html which might be the login page
    window.location.href = 'login.html'; // Redirect if not a student
    return;
}
// --- End Login Check ---

// --- DOM Elements ---
const createdLessonsDiv = document.getElementById('createdLessons');
const createdQuizzesDiv = document.getElementById('createdQuizzes');
const quizCompletionStatusDiv = document.getElementById('quiz-completion-status');
// Analytics Elements
const analyticsBtn = document.getElementById('analyticsBtn');
const analyticsModal = document.getElementById('analyticsModal');
const lastAccessedSpan = document.getElementById('lastAccessed');
const lessonProgressListUl = document.getElementById('lessonProgressList'); // Added for modal
const quizScoresListUl = document.getElementById('quizScoresList');
const overallGradeSpan = document.getElementById('overallGrade');
// Modal Navigation Elements
const modalDashboardBtn = document.getElementById('modalDashboardBtn');
const modalHomeBtn = document.getElementById('modalHomeBtn');
const modalLogoutBtn = document.getElementById('modalLogoutBtn');

// --- Storage Keys ---
const storageKeys = {
    users: 'registeredUsers', // Key for the main user object containing all users
    lessons: 'createdLessons', // Global lessons created by teacher
    quizzes: 'createdQuizzes', // Global quizzes created by teacher
    lastAccessed: `studentLastAccessed_${loggedInUsername}` // Student-specific last access
};

// --- Utility Functions (Ensure login.js is included for getUsers/saveUsers) ---
// getUsers() and saveUsers() are assumed to be available from login.js
if (typeof getUsers !== 'function' || typeof saveUsers !== 'function') {
    console.error("Error: getUsers or saveUsers function not found. Make sure login.js is included before student.js");
    alert("A critical error occurred. Please try refreshing the page or logging in again.");
    // Optionally redirect or disable functionality
    return;
}

// --- Get Current Student Data ---
// Helper to safely get the current student's data object from the main users store
function getCurrentStudentData() {
    const users = getUsers();
    const studentData = users[loggedInUsername];
    if (studentData && studentData.role === 'student') {
        // Initialize progress arrays if they don't exist (robustness)
        if (!Array.isArray(studentData.quizScores)) {
            studentData.quizScores = [];
        }
        if (!Array.isArray(studentData.lessonProgress)) {
            studentData.lessonProgress = [];
        }
        return studentData;
    }
    console.error("Could not find valid student data for username:", loggedInUsername);
    // Maybe redirect or show error if student data is corrupted/missing
    alert("Error: Could not load your data. Please try logging in again.");
    logout(); // Log out if data is missing
    return null; // Return null to indicate failure
}

// --- Track Last Accessed ---
function recordLastAccessed() {
    const now = new Date();
    localStorage.setItem(storageKeys.lastAccessed, now.toISOString());
}

// --- Lesson Display & Tracking ---
function updateCreatedLessons() {
    const globalLessons = JSON.parse(localStorage.getItem(storageKeys.lessons) || '[]');
    const studentData = getCurrentStudentData();
    if (!studentData) return; // Stop if student data failed to load

    createdLessonsDiv.innerHTML = ''; // Clear existing lessons
    if (globalLessons.length === 0) {
        createdLessonsDiv.innerHTML = '<p>No lessons available.</p>';
        return;
    }

    globalLessons.forEach((lesson, index) => {
        // Basic validation
        const title = lesson.title || 'Untitled Lesson';
        const content = lesson.content || 'No content.';
        const lessonId = `lesson-${index}`; // Simple ID based on index

        // Check student's progress for this lesson
        const progressEntry = studentData.lessonProgress.find(p => p.lessonName === title);
        const isRead = progressEntry && (progressEntry.status === 'read' || progressEntry.status === 'completed'); // Consider both 'read' and 'completed' as read

        const lessonDiv = document.createElement('div');
        lessonDiv.classList.add('lesson');
        lessonDiv.innerHTML = `
            <h4>${title}</h4>
            <p>${content}</p>
            <button class="mark-read-btn" data-lesson-title="${title}" ${isRead ? 'disabled' : ''}>
                ${isRead ? 'Read' : 'Mark as Read'}
            </button>
        `;
        createdLessonsDiv.appendChild(lessonDiv);
    });
}

// --- Event Delegation for Lesson Buttons ---
createdLessonsDiv.addEventListener('click', (event) => {
    const target = event.target;
    if (target.classList.contains('mark-read-btn') && !target.disabled) {
        const lessonTitle = target.dataset.lessonTitle;
        markLessonAsRead(lessonTitle, target);
    }
});

function markLessonAsRead(lessonTitle, buttonElement) {
    const users = getUsers();
    const studentData = users[loggedInUsername]; // Get current data again

    if (!studentData) {
        alert("Error updating lesson status.");
        return;
    }

    // Ensure lessonProgress array exists
     if (!Array.isArray(studentData.lessonProgress)) {
        studentData.lessonProgress = [];
    }

    // Find the progress entry or create it
    let progressEntry = studentData.lessonProgress.find(p => p.lessonName === lessonTitle);

    if (progressEntry) {
        progressEntry.status = 'read'; // Update status to 'read'
    } else {
        // Add new entry if it doesn't exist
        studentData.lessonProgress.push({ lessonName: lessonTitle, status: 'read' });
    }

    // Save the updated users object
    saveUsers(users);

    // Update the button state
    buttonElement.disabled = true;
    buttonElement.textContent = 'Read';

    console.log(`Lesson "${lessonTitle}" marked as read for ${loggedInUsername}`);
    // Optionally, update the analytics modal if it's open
    if (analyticsModal.style.display === 'block') {
        populateAnalyticsData();
    }
}


// --- Quiz Display and Taking Logic ---
function updateCreatedQuizzes() {
    console.log("Updating created quizzes display for student:", loggedInUsername);
    const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]');
    const studentData = getCurrentStudentData();
    if (!studentData) return; // Stop if student data failed to load

    createdQuizzesDiv.innerHTML = ''; // Clear previous content

    if (globalQuizzes.length === 0) {
        createdQuizzesDiv.innerHTML = '<p>No quizzes available.</p>';
        checkAndEnforceQuizCompletion(); // Check even if no quizzes
        return;
    }

    globalQuizzes.forEach((quiz, index) => {
        // Basic validation of quiz structure
        if (!quiz || typeof quiz.quizTitle === 'undefined' || !Array.isArray(quiz.questions)) {
            console.warn(`Skipping invalid quiz data at index ${index}:`, quiz);
            return; // Skip rendering this invalid quiz
        }
        const quizTitle = quiz.quizTitle || 'Untitled Quiz';

        // Check if this student has taken this quiz by looking in their main data
        const resultData = studentData.quizScores.find(score => score.quizName === quizTitle);
        const hasTaken = !!resultData; // True if resultData is found

        console.log(`Quiz Index: ${index}, Title: ${quizTitle}, Has Taken: ${hasTaken}`);

        const quizDiv = document.createElement('div');
        quizDiv.classList.add('quiz');
        quizDiv.id = `quiz-${index}`;

        quizDiv.innerHTML = `
            <h4>${quizTitle}</h4>
            <p>Type: ${quiz.quizType || 'N/A'}</p>
            <p>Number of questions: ${quiz.questions.length}</p>
            <button class="btn take-quiz-btn" data-quiz-index="${index}" ${hasTaken ? 'disabled' : ''}>${hasTaken ? 'Quiz Taken' : 'Take Quiz'}</button>
            <div class="quiz-questions-area" id="quiz-area-${index}" style="display: none;"></div>
            <div class="quiz-score-area" id="score-area-${index}" style="display: ${hasTaken ? 'block' : 'none'};">
                ${hasTaken && resultData ? `<h3>Your Score: ${resultData.score}%</h3>` : ''}
            </div>
        `;
        createdQuizzesDiv.appendChild(quiz_
Updated files
v2
i need the student.js code

Okay, here is the complete code for student.js.

<jitProject id="teacher-student-dashboard-full" title="Teacher and Student Dashboards (Full Code)"> <jitFile type="file" filePath="student.js"> document.addEventListener('DOMContentLoaded', () => { // --- Login Check --- const loggedInUsername = sessionStorage.getItem('loggedInUsername'); const loggedInRole = sessionStorage.getItem('loggedInRole');
    if (!loggedInUsername || !loggedInRole || loggedInRole !== 'student') {
        alert('Access denied. Please log in as a student.');
        // Ensure login.js is loaded if redirecting to index.html which might be the login page
        window.location.href = 'login.html'; // Redirect if not a student
        return;
    }
    // --- End Login Check ---

    // --- DOM Elements ---
    const createdLessonsDiv = document.getElementById('createdLessons');
    const createdQuizzesDiv = document.getElementById('createdQuizzes');
    const quizCompletionStatusDiv = document.getElementById('quiz-completion-status');
    // Analytics Elements
    const analyticsBtn = document.getElementById('analyticsBtn');
    const analyticsModal = document.getElementById('analyticsModal');
    const lastAccessedSpan = document.getElementById('lastAccessed');
    const lessonProgressListUl = document.getElementById('lessonProgressList'); // Added for modal
    const quizScoresListUl = document.getElementById('quizScoresList');
    const overallGradeSpan = document.getElementById('overallGrade');
    // Modal Navigation Elements
    const modalDashboardBtn = document.getElementById('modalDashboardBtn');
    const modalHomeBtn = document.getElementById('modalHomeBtn');
    const modalLogoutBtn = document.getElementById('modalLogoutBtn');

    // --- Storage Keys ---
    const storageKeys = {
        users: 'registeredUsers', // Key for the main user object containing all users
        lessons: 'createdLessons', // Global lessons created by teacher
        quizzes: 'createdQuizzes', // Global quizzes created by teacher
        lastAccessed: `studentLastAccessed_${loggedInUsername}` // Student-specific last access
    };

    // --- Utility Functions (Ensure login.js is included for getUsers/saveUsers) ---
    // getUsers() and saveUsers() are assumed to be available from login.js
    if (typeof getUsers !== 'function' || typeof saveUsers !== 'function') {
        console.error("Error: getUsers or saveUsers function not found. Make sure login.js is included before student.js");
        alert("A critical error occurred. Please try refreshing the page or logging in again.");
        // Optionally redirect or disable functionality
        return;
    }

    // --- Get Current Student Data ---
    // Helper to safely get the current student's data object from the main users store
    function getCurrentStudentData() {
        const users = getUsers();
        const studentData = users[loggedInUsername];
        if (studentData && studentData.role === 'student') {
            // Initialize progress arrays if they don't exist (robustness)
            if (!Array.isArray(studentData.quizScores)) {
                studentData.quizScores = [];
            }
            if (!Array.isArray(studentData.lessonProgress)) {
                studentData.lessonProgress = [];
            }
            return studentData;
        }
        console.error("Could not find valid student data for username:", loggedInUsername);
        // Maybe redirect or show error if student data is corrupted/missing
        alert("Error: Could not load your data. Please try logging in again.");
        logout(); // Log out if data is missing
        return null; // Return null to indicate failure
    }

    // --- Track Last Accessed ---
    function recordLastAccessed() {
        const now = new Date();
        localStorage.setItem(storageKeys.lastAccessed, now.toISOString());
    }

    // --- Lesson Display & Tracking ---
    function updateCreatedLessons() {
        const globalLessons = JSON.parse(localStorage.getItem(storageKeys.lessons) || '[]');
        const studentData = getCurrentStudentData();
        if (!studentData) return; // Stop if student data failed to load

        createdLessonsDiv.innerHTML = ''; // Clear existing lessons
        if (globalLessons.length === 0) {
            createdLessonsDiv.innerHTML = '<p>No lessons available.</p>';
            return;
        }

        globalLessons.forEach((lesson, index) => {
            // Basic validation
            const title = lesson.title || 'Untitled Lesson';
            const content = lesson.content || 'No content.';
            const lessonId = `lesson-${index}`; // Simple ID based on index

            // Check student's progress for this lesson
            const progressEntry = studentData.lessonProgress.find(p => p.lessonName === title);
            const isRead = progressEntry && (progressEntry.status === 'read' || progressEntry.status === 'completed'); // Consider both 'read' and 'completed' as read

            const lessonDiv = document.createElement('div');
            lessonDiv.classList.add('lesson');
            lessonDiv.innerHTML = `
                <h4>${title}</h4>
                <p>${content}</p>
                <button class="mark-read-btn" data-lesson-title="${title}" ${isRead ? 'disabled' : ''}>
                    ${isRead ? 'Read' : 'Mark as Read'}
                </button>
            `;
            createdLessonsDiv.appendChild(lessonDiv);
        });
    }

    // --- Event Delegation for Lesson Buttons ---
    createdLessonsDiv.addEventListener('click', (event) => {
        const target = event.target;
        if (target.classList.contains('mark-read-btn') && !target.disabled) {
            const lessonTitle = target.dataset.lessonTitle;
            markLessonAsRead(lessonTitle, target);
        }
    });

    function markLessonAsRead(lessonTitle, buttonElement) {
        const users = getUsers();
        const studentData = users[loggedInUsername]; // Get current data again

        if (!studentData) {
            alert("Error updating lesson status.");
            return;
        }

        // Ensure lessonProgress array exists
         if (!Array.isArray(studentData.lessonProgress)) {
            studentData.lessonProgress = [];
        }

        // Find the progress entry or create it
        let progressEntry = studentData.lessonProgress.find(p => p.lessonName === lessonTitle);

        if (progressEntry) {
            progressEntry.status = 'read'; // Update status to 'read'
        } else {
            // Add new entry if it doesn't exist
            studentData.lessonProgress.push({ lessonName: lessonTitle, status: 'read' });
        }

        // Save the updated users object
        saveUsers(users);

        // Update the button state
        buttonElement.disabled = true;
        buttonElement.textContent = 'Read';

        console.log(`Lesson "${lessonTitle}" marked as read for ${loggedInUsername}`);
        // Optionally, update the analytics modal if it's open
        if (analyticsModal.style.display === 'block') {
            populateAnalyticsData();
        }
    }


    // --- Quiz Display and Taking Logic ---
    function updateCreatedQuizzes() {
        console.log("Updating created quizzes display for student:", loggedInUsername);
        const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]');
        const studentData = getCurrentStudentData();
        if (!studentData) return; // Stop if student data failed to load

        createdQuizzesDiv.innerHTML = ''; // Clear previous content

        if (globalQuizzes.length === 0) {
            createdQuizzesDiv.innerHTML = '<p>No quizzes available.</p>';
            checkAndEnforceQuizCompletion(); // Check even if no quizzes
            return;
        }

        globalQuizzes.forEach((quiz, index) => {
            // Basic validation of quiz structure
            if (!quiz || typeof quiz.quizTitle === 'undefined' || !Array.isArray(quiz.questions)) {
                console.warn(`Skipping invalid quiz data at index ${index}:`, quiz);
                return; // Skip rendering this invalid quiz
            }
            const quizTitle = quiz.quizTitle || 'Untitled Quiz';

            // Check if this student has taken this quiz by looking in their main data
            const resultData = studentData.quizScores.find(score => score.quizName === quizTitle);
            const hasTaken = !!resultData; // True if resultData is found

            console.log(`Quiz Index: ${index}, Title: ${quizTitle}, Has Taken: ${hasTaken}`);

            const quizDiv = document.createElement('div');
            quizDiv.classList.add('quiz');
            quizDiv.id = `quiz-${index}`;

            quizDiv.innerHTML = `
                <h4>${quizTitle}</h4>
                <p>Type: ${quiz.quizType || 'N/A'}</p>
                <p>Number of questions: ${quiz.questions.length}</p>
                <button class="btn take-quiz-btn" data-quiz-index="${index}" ${hasTaken ? 'disabled' : ''}>${hasTaken ? 'Quiz Taken' : 'Take Quiz'}</button>
                <div class="quiz-questions-area" id="quiz-area-${index}" style="display: none;"></div>
                <div class="quiz-score-area" id="score-area-${index}" style="display: ${hasTaken ? 'block' : 'none'};">
                    ${hasTaken && resultData ? `<h3>Your Score: ${resultData.score}%</h3>` : ''}
                </div>
            `;
            createdQuizzesDiv.appendChild(quizDiv);
        });

        checkAndEnforceQuizCompletion(); // Check completion after rendering quizzes
    }

    // --- Event Delegation for Quiz Buttons ---
    createdQuizzesDiv.addEventListener('click', (event) => {
        const target = event.target; // The element that was actually clicked

        // Check if the clicked element is a "take-quiz-btn" or inside one
        const takeButton = target.closest('.take-quiz-btn');
        if (takeButton && !takeButton.disabled) {
            console.log("Take Quiz button clicked via delegation for index:", takeButton.dataset.quizIndex);
            startQuiz(takeButton); // Pass the button element itself
            return; // Stop further processing for this click
        }

        // Check if the clicked element is a "submit-quiz-btn" or inside one
        const submitButton = target.closest('.submit-quiz-btn');
        if (submitButton && !submitButton.disabled) {
             console.log("Submit Quiz button clicked via delegation for index:", submitButton.dataset.quizIndex);
             submitQuiz(submitButton); // Pass the button element itself
             return; // Stop further processing for this click
        }
    });


    function startQuiz(buttonElement) { // Accepts the button element directly
        const quizIndex = buttonElement.dataset.quizIndex;
        console.log('startQuiz called for index:', quizIndex);
        const globalQuizzes = JSON.parse(localStorage.getItem(storageKeys.quizzes) || '[]');

        // Validate quiz index and data
        if (quizIndex === undefined || !globalQuizzes[quizIndex] || !Array.isArray(globalQuizzes[quizIndex].questions)) {
             console.error(`Invalid quiz index or data for index ${quizIndex}`);
             alert("Error: Could not load quiz data.");
             return;
        }

        const quiz = globalQuizzes[quizIndex];
        const questionsArea = document.getElementById(`quiz-area-${quizIndex}`);
        const scoreArea = document.getElementById(`score-area-${quizIndex}`);
        const takeQuizButton = buttonElement; // The button that was clicked

        if (!questionsArea || !scoreArea) {
             console.error(`Could not find questionsArea or scoreArea for quiz index ${quizIndex}`);
             alert("Error: Could not display quiz.");
             return;
        }


        // Hide other open quiz forms if any, and show their "Take Quiz" buttons
        document.querySelectorAll('.quiz-questions-area').forEach(area => {
            if (area.id !== `quiz-area-${quizIndex}`) {
                area.style.display = 'none';
                const otherQuizIndex = area.id.split('-')[2];
                const otherTakeButton = document.querySelector(`.take-quiz-btn[data-quiz-index="${otherQuizIndex}"]`);
                // Check if the other quiz has been taken using the main student data
                const studentData = getCurrentStudentData();
                const otherQuizTitle = globalQuizzes[otherQuizIndex]?.quizTitle;
                const otherQuizTaken = studentData?.quizScores.some(s => s.quizName === otherQuizTitle);

                if (otherTakeButton && !otherQuizTaken) { // Only show if not already taken
                    otherTakeButton.style.display = 'inline-block';
                }
            }
        });


        questionsArea.innerHTML = ''; // Clear previous content if any
        scoreArea.innerHTML = ''; // Clear score area
        scoreArea.style.display = 'none'; // Hide score area
        questionsArea.style.display = 'block'; // Show questions area
        takeQuizButton.style_
give the student.js code now!

Okay, here is the complete code for student.js.

This provides the complete code for student.js along with all the other necessary files (teacher.html, teacher.css, teacher.js, student.html, student.css, login.html, login.js, login.css, homepage.html) to make the application functional.

Updated files
v3
make this code: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Parent Access - Find Student</title> <link rel="stylesheet" href="parent.css"> <!-- Use parent CSS --> </head> <body> <div class="access-container"> <h2>Find Student Record</h2> <p>Please enter the student's details to view their progress.</p> <input type="text" id="studentFullName" placeholder="Enter Student's Full Name"> <input type="text" id="studentIdNumber" placeholder="Enter Student's ID Number"> <button onclick="verifyStudent()">View Dashboard</button> <p id="accessErrorMessage" class="error-message"></p> <p><a href="login.html">Back to Login</a></p> <!-- Link back to index/login --> </div> <script src="login.js"></script> <!-- Include login.js for getUsers function --> <script src="parent.js"></script> <!-- Include parent.js for verifyStudent function --> </body> </html> go this code after clicking the logout button: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> <link rel="stylesheet" href="login.css"> </head> <body> <!-- Login Form --> <div class="login-container" id="login-container"> <h2>Login</h2> <input type="text" id="username" placeholder="Enter Username"> <input type="password" id="password" placeholder="Enter Password"> <select id="role"> <option value="">Select Role</option> <option value="teacher">Teacher</option> <option value="student">Junior High School Student</option> <option value="parent">Parent</option> </select> <!-- Container for Teacher ID --> <div id="loginTeacherIdContainer" class="hidden"> <input type="text" id="loginTeacherId" placeholder="Enter Teacher ID Number"> </div> <!-- Container for Student ID --> <div id="loginStudentIdContainer" class="hidden"> <input type="text" id="loginStudentId" placeholder="Enter Student ID Number"> </div> <button onclick="login()">Login</button> <p id="errorMessage" class="error-message"></p> <p>Don't have an account? <a href="#" onclick="showSignup()">Sign up</a></p> </div> <!-- Sign Up Form --> <div class="signup-container hidden" id="signup-container"> <h2>Sign Up</h2> <input type="text" id="newUsername" placeholder="Choose a Username"> <input type="password" id="newPassword" placeholder="Choose a Password"> <select id="newRole"> <option value="">Select Role</option> <option value="teacher">Teacher</option> <option value="student">Junior High School Student</option> <option value="parent">Parent</option> </select> <!-- Container for Teacher ID --> <div id="signupTeacherIdContainer" class="hidden"> <input type="text" id="signupTeacherId" placeholder="Enter Teacher ID Number"> </div> <!-- Container for Student Info (Full Name and ID) --> <div id="signupStudentInfoContainer" class="hidden"> <input type="text" id="fullName" placeholder="Enter Full Name"> <input type="text" id="signupStudentId" placeholder="Enter Student ID Number"> </div> <button onclick="signup()">Sign Up</button> <p id="signupMessage" class="signup-message"></p> <p>Already have an account? <a href="#" onclick="showLogin()">Log in</a></p> </div> <script src="login.js"></script> </body> </html>

Okay, I understand. You want to add a "Logout" functionality to the parent's view that redirects the user back to the provided login.html page.

Since the first HTML file you provided (parent-access.html) is just for finding the student, the logout button logically belongs on the next page – the actual dashboard displaying the student's information.

I will:

  1. Keep the parent-access.html file for finding the student.
  2. Create a new parent-dashboard.html file where the student's data will be shown after successful verification. This page will contain the "Logout" button.
  3. Update parent.js to handle the verification and redirection to the dashboard.
  4. Add JavaScript to parent-dashboard.html to display data and handle the logout action.
  5. Include the necessary CSS and the updated login.html and login.js.

Here's the setup:

Explanation:

  1. parent-access.html: This remains the initial page for parents. It prompts for the student's full name and ID.
  2. parent.js:
    • The verifyStudent function now checks the entered name and ID against the registeredUsers data fetched using getUsers() from login.js.
    • It specifically looks for users with role: 'student' and matching fullName and studentId.
    • If a match is found, it stores the student's username and fullName in sessionStorage and redirects to parent-dashboard.html.
    • If no match is found, it displays an error message.
  3. parent-dashboard.html:
    • This new page is displayed after successful verification.
    • It includes a "Logout" button in the header.
    • Inline JavaScript runs on DOMContentLoaded:
      • It retrieves the verifiedStudentUsername and verifiedStudentFullName from sessionStorage. If not found, it redirects back to the access page.
      • It uses getUsers() to get all user data and finds the specific student's record.
      • It populates sections to display the student's name, lesson progress (checking against global lessons), and quiz scores (calculating an overall grade).
      • It attaches an event listener to the "Logout" button.
    • The logout function clears the relevant sessionStorage items and redirects the browser to login.html.
  4. parent.css: Basic styling is provided for both parent pages.
  5. login.html & login.js: Updated to use the versions you provided, ensuring the parent role is handled correctly during login and signup, and that student signup includes fullName and studentId. The login function now redirects parents to parent-access.html.
  6. login.css: Included for styling the login/signup page.
Updated files
v4
if i pressed logout button i will return to login page on this code: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Parent Access - Find Student</title> <link rel="stylesheet" href="parent.css"> <!-- Use new CSS --> </head> <body> <div class="access-container"> <h2>Find Student Record</h2> <p>Please enter the student's details to view their progress.</p> <input type="text" id="studentFullName" placeholder="Enter Student's Full Name"> <input type="text" id="studentIdNumber" placeholder="Enter Student's ID Number"> <button onclick="verifyStudent()">View Dashboard</button> <p id="accessErrorMessage" class="error-message"></p> <p><a href="login.html">Back to Login</a></p> </div> <script src="parent.js"></script> <!-- Use new JS --> <script src="login.js"></script> <!-- Include login.js for getUsers function --> </body> </html>

Okay, I understand you want to ensure that pressing a logout button returns the user to the login page.

However, the code you provided (parent-access.html) is the page where the parent finds the student record. Logically, a "Logout" button doesn't belong here because the parent isn't necessarily "logged in" to this specific page. They usually log in first (on login.html), might be redirected here, and then proceed to the actual dashboard after finding the student.

The "Logout" button makes the most sense on the page that displays the student's sensitive information (the parent-dashboard.html page we created in the previous step). That's where the parent's "session" of viewing the data exists.

The parent-access.html page already has a "Back to Login" link, which serves the purpose of returning to the login screen from this intermediate step.

Therefore, the logout functionality is correctly placed in the parent-dashboard.html file from the previous response. When the parent is viewing the dashboard and clicks "Logout", the JavaScript in parent-dashboard.html will clear the session storage and redirect them to login.html.

Here is the relevant part of parent-dashboard.html again, showing the logout button and its associated JavaScript:

html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Parent Dashboard</title> <link rel="stylesheet" href="parent.css"> <!-- Use parent CSS --> </head> <body> <div class="dashboard-container"> <div class="header"> <h1>Parent Dashboard</h1> <!-- LOGOUT BUTTON IS HERE --> <button id="logoutBtn" class="logout-button">Logout</button> </div>
    <h2 id="studentNameDisplay">Viewing Progress for: Loading...</h2>

    <!-- ... (sections for lesson progress, quiz scores, etc.) ... -->

</div>

<script src="login.js"></script> <!-- Include login.js for getUsers function -->
<script>
    document.addEventListener('DOMContentLoaded', () => {
        // ... (code to get student data and display it) ...

        const logoutBtn = document.getElementById('logoutBtn');

        // --- Logout Functionality ---
        logoutBtn.addEventListener('click', logout); // Attach listener

    });

    // LOGOUT FUNCTION IS HERE
    function logout() {
        // Clear relevant session storage items
        sessionStorage.removeItem('loggedInUsername'); // If parent logged in
        sessionStorage.removeItem('loggedInRole');     // If parent logged in
        sessionStorage.removeItem('verifiedStudentUsername');
        sessionStorage.removeItem('verifiedStudentFullName');

        // Redirect to the login page
        window.location.href = 'login.html';
    }
</script>
</body> </html>

So, to reiterate:

  1. Parent logs in on login.html.
  2. Parent is redirected to parent-access.html.
  3. Parent enters student details and clicks "View Dashboard".
  4. parent.js verifies the student and redirects to parent-dashboard.html.
  5. On parent-dashboard.html, the parent views the data.
  6. Parent clicks the "Logout" button on parent-dashboard.html.
  7. The logout function in parent-dashboard.html runs, clearing session data and redirecting back to login.html.
if i pressed logout button i will return to login page on this code: <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Parent Access - Find Student</title> <link rel="stylesheet" href="parent.css"> <!-- Use new CSS --> </head> <body> <div class="access-container"> <h2>Find Student Record</h2> <p>Please enter the student's details to view their progress.</p> <input type="text" id="studentFullName" placeholder="Enter Student's Full Name"> <input type="text" id="studentIdNumber" placeholder="Enter Student's ID Number"> <button onclick="verifyStudent()">View Dashboard</button> <p id="accessErrorMessage" class="error-message"></p> <p><a href="login.html">Back to Login</a></p> </div> <script src="parent.js"></script> <!-- Use new JS --> <script src="login.js"></script> <!-- Include login.js for getUsers function --> </body> </html>

Okay, I will add a "Logout" button directly to the parent-access.html code you provided and ensure clicking it redirects to login.html.

I'll modify parent-access.html to include the button and update parent.js to handle the click event for this new button.

Now, the parent-access.html page includes a "Logout" button. Clicking it will execute the logout function defined in parent.js, clear the session storage, and redirect the user to login.html.

Updated files
v5