harshdhane's picture
Upload 21 files
8ad39f4 verified
Raw
History Blame Contribute Delete
29.9 kB
<!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="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"/>
<style>
:root {
--primary: #1a4a7c;
--secondary: #3498db;
--success: #2ecc71;
--warning: #f39c12;
--info: #2980b9;
--light: #ecf0f1;
--dark: #2c3e50;
--white: #ffffff;
--gray: #bdc3c7;
--border-radius: 8px;
--font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #f0f4f8 0%, #d7e1ec 100%);
min-height: 100vh;
font-family: var(--font-main);
padding: 40px 20px;
}
.container {
max-width: 900px;
}
.dashboard-box {
background-color: var(--white);
border-radius: var(--border-radius);
padding: 35px;
width: 100%;
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
margin: 20px auto;
border-top: 4px solid var(--primary);
}
h1 {
color: var(--primary);
margin-bottom: 25px;
text-align: center;
font-weight: 600;
font-size: 2.2rem;
}
h4 {
color: var(--primary);
margin: 25px 0 15px;
font-weight: 500;
font-size: 1.4rem;
}
p {
font-size: 16px;
color: var(--dark);
margin-bottom: 15px;
}
.editable {
cursor: pointer;
color: var(--info);
font-size: 0.9rem;
text-decoration: none;
transition: color 0.3s;
display: block;
text-align: center;
margin-top: 5px;
}
.editable:hover {
color: var(--secondary);
text-decoration: underline;
}
.hidden {
display: none;
}
.btn-primary {
background: linear-gradient(to right, var(--primary), var(--secondary));
border: none;
border-radius: 50px;
font-weight: 500;
padding: 12px 25px;
transition: all 0.3s;
box-shadow: 0 4px 10px rgba(26, 74, 124, 0.3);
margin-top: 20px;
}
.btn-primary:hover {
background: linear-gradient(to right, #155785, #2980b9);
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(26, 74, 124, 0.4);
}
.btn-secondary {
background-color: var(--light);
color: var(--dark);
border: none;
border-radius: 50px;
font-weight: 500;
padding: 12px 25px;
transition: all 0.3s;
margin-top: 10px;
}
.btn-secondary:hover {
background-color: var(--gray);
transform: translateY(-2px);
}
.btn-success {
background: linear-gradient(to right, var(--success), var(--info));
border: none;
border-radius: 50px;
font-weight: 500;
padding: 12px 25px;
transition: all 0.3s;
box-shadow: 0 4px 10px rgba(46, 204, 113, 0.3);
margin-right: 10px;
}
.btn-success:hover {
background: linear-gradient(to right, #27ae60, var(--success));
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(46, 204, 113, 0.4);
}
.btn-link {
color: var(--gray);
text-decoration: none;
padding: 10px;
display: block;
text-align: center;
transition: color 0.3s;
font-weight: 500;
}
.btn-link:hover {
color: var(--primary);
text-decoration: none;
}
.profile-info {
background-color: var(--light);
border-radius: var(--border-radius);
padding: 25px;
margin-bottom: 25px;
border-left: 4px solid var(--primary);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}
.profile-info p {
margin-bottom: 15px;
display: flex;
align-items: center;
line-height: 1.6;
}
.profile-info p strong {
min-width: 130px;
display: inline-block;
}
.profile-info p strong i {
width: 20px;
color: var(--primary);
margin-right: 8px;
}
.form-group label {
font-weight: 500;
color: var(--dark);
margin-bottom: 8px;
}
.form-control {
border-radius: var(--border-radius);
border: 1px solid var(--gray);
padding: 12px;
transition: border 0.3s, box-shadow 0.3s;
margin-bottom: 15px;
}
.form-control:focus {
border-color: var(--secondary);
box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25);
}
select.form-control {
cursor: pointer;
height: 46px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'%3E%3Cpath fill='%231a4a7c' d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 10px center;
padding-right: 30px;
background-size: 20px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.table {
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: 0 4px 10px rgba(0,0,0,0.05);
margin-top: 20px;
margin-bottom: 25px;
border: none;
}
.table thead th {
background-color: rgba(26, 74, 124, 0.1);
color: var(--primary);
border-bottom: 2px solid var(--primary);
font-weight: 600;
padding: 15px;
text-transform: uppercase;
font-size: 0.85rem;
letter-spacing: 0.5px;
}
.table tbody td {
padding: 15px;
border-top: 1px solid #e9ecef;
vertical-align: middle;
}
.table-striped tbody tr:nth-of-type(odd) {
background-color: rgba(248, 249, 250, 0.7);
}
hr {
border-top: 1px solid #e9ecef;
margin: 30px 0;
}
.section-title {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid rgba(26, 74, 124, 0.2);
}
.section-title i {
margin-right: 10px;
color: var(--primary);
font-size: 1.2rem;
}
.action-buttons {
display: flex;
justify-content: space-between;
margin-top: 25px;
}
.action-buttons button {
width: 48%;
}
.alert-info {
background-color: rgba(26, 74, 124, 0.1);
border-color: rgba(26, 74, 124, 0.2);
color: var(--primary);
border-radius: var(--border-radius);
padding: 15px;
margin-bottom: 25px;
}
.alert-info i {
color: var(--primary);
margin-right: 8px;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background-color: var(--white);
border-radius: var(--border-radius);
margin:15% auto;
padding: 30px;
border: none;
width: 90%;
max-width: 500px;
box-shadow: 0 15px 30px rgba(0,0,0,0.2);
position: relative;
}
.close-modal {
position: absolute;
top: 15px;
right: 20px;
color: var(--gray);
font-size: 24px;
font-weight: bold;
cursor: pointer;
transition: color 0.3s;
}
.close-modal:hover {
color: var(--dark);
}
.modal h3 {
color: var(--primary);
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e9ecef;
}
.modal button {
background: linear-gradient(to right, var(--primary), var(--secondary));
color: var(--white);
border: none;
border-radius: 50px;
padding: 12px 25px;
margin-top: 20px;
cursor: pointer;
transition: all 0.3s;
font-weight: 500;
box-shadow: 0 4px 10px rgba(26, 74, 124, 0.3);
display: block;
width: 100%;
}
.modal button:hover {
background: linear-gradient(to right, #155785, #2980b9);
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(26, 74, 124, 0.4);
}
.modal label {
display: block;
margin: 10px 0;
font-weight: 500;
}
.modal select {
width: 100%;
padding: 10px;
border-radius: var(--border-radius);
border: 1px solid var(--gray);
margin-bottom: 20px;
}
#regularSubjectsList,
#specializationSubjectsList,
#practicalsList {
max-height: 300px;
overflow-y: auto;
padding: 10px;
border: 1px solid #eee;
border-radius: var(--border-radius);
margin-bottom: 10px;
}
#regularSubjectsList label,
#specializationSubjectsList label,
#practicalsList label {
display: block;
padding: 8px;
border-bottom: 1px solid #f5f5f5;
margin: 0;
}
#regularSubjectsList label:hover,
#specializationSubjectsList label:hover,
#practicalsList label:hover {
background-color: #f8f9fa;
}
#regularSubjectsList input,
#specializationSubjectsList input,
#practicalsList input {
margin-right: 10px;
}
.subject-selection-button {
display: inline-block;
background-color: var(--light);
color: var(--primary);
border: 1px solid var(--primary);
border-radius: 50px;
padding: 10px 20px;
margin: 10px 0;
font-weight: 500;
transition: all 0.3s;
text-decoration: none;
cursor: pointer;
}
.subject-selection-button:hover {
background-color: rgba(26, 74, 124, 0.1);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
}
.subject-selection-button i {
margin-right: 5px;
}
.mt-4 {
margin-top: 2rem;
}
.text-center {
text-align: center;
}
@media (max-width: 768px) {
.dashboard-box {
padding: 25px 20px;
}
.action-buttons {
flex-direction: column;
}
.action-buttons button {
width: 100%;
margin-bottom: 10px;
}
.profile-info p strong {
min-width: 105px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="dashboard-box">
<h1>
Welcome, <span id="view-fullname">{{ user.full_name }}</span>
<small class="editable" onclick="openEdit()"><i class="fas fa-edit"></i> Edit Profile</small>
</h1>
<!-- PROFILE VIEW -->
<div id="profile-view" class="profile-info">
<p><strong><i class="fas fa-id-card"></i> Enrollment No:</strong> <span id="view-enroll">{{ user.enrollment_number }}</span></p>
<p><strong><i class="fas fa-envelope"></i> Email:</strong> <span id="view-email">{{ user.email }}</span></p>
<p><strong><i class="fas fa-phone"></i> Student No:</strong> <span id="view-studno">{{ user.student_number or '-' }}</span></p>
<p><strong><i class="fas fa-phone-alt"></i> Parent No:</strong> <span id="view-parentno">{{ user.parent_number or '-' }}</span></p>
<p><strong><i class="fas fa-envelope-open"></i> Parent Email:</strong> <span id="view-parentemail">{{ user.parent_email or '-' }}</span></p>
</div>
<!-- PROFILE EDIT -->
<div id="profile-edit" class="hidden">
<div class="form-group">
<label>Full Name</label>
<input id="edit-fullname" class="form-control" value="{{ user.full_name }}"/>
</div>
<div class="form-group">
<label>Enrollment No</label>
<input id="edit-enroll" class="form-control" value="{{ user.enrollment_number }}"/>
</div>
<div class="form-group">
<label>Email</label>
<input id="edit-email" class="form-control" value="{{ user.email }}"/>
</div>
<div class="form-group">
<label>Student No</label>
<input id="edit-studno" class="form-control" value="{{ user.student_number }}"/>
</div>
<div class="form-group">
<label>Parent No</label>
<input id="edit-parentno" class="form-control" value="{{ user.parent_number }}"/>
</div>
<div class="form-group">
<label>Parent Email</label>
<input id="edit-parentemail" class="form-control" value="{{ user.parent_email }}"/>
</div>
<div class="action-buttons">
<button class="btn btn-success" onclick="saveProfile()"><i class="fas fa-save"></i> Save</button>
<button class="btn btn-secondary" onclick="cancelEdit()"><i class="fas fa-times"></i> Cancel</button>
</div>
</div>
<hr/>
<div class="alert alert-info">
<i class="fas fa-chart-pie"></i>
<strong>Overall Attendance Average:</strong> <span id="overall-average">Calculating...</span>
</div>
<!-- CLASS SELECT -->
<div class="section-title">
<i class="fas fa-chalkboard-teacher"></i>
<h4>Class Information</h4>
</div>
<div class="form-group">
<label>Select Class</label>
<select id="class-select" class="form-control">
<option value="">-- Choose Class --</option>
<option {{ 'selected' if user.selected_class=='SY-19' }}>SY-19</option>
<option {{ 'selected' if user.selected_class=='SY-20' }}>SY-20</option>
<option {{ 'selected' if user.selected_class=='SY-21' }}>SY-21</option>
<option {{ 'selected' if user.selected_class=='SY-22' }}>SY-22</option>
</select>
</div>
<!-- SUBJECT TABLES -->
<div id="subjects-section" class="{{ '' if user.selected_class else 'hidden' }}">
<div class="alert alert-info">
<i class="fas fa-info-circle"></i>
<strong>Current Class:</strong> <span id="cls-label">{{ user.selected_class }}</span>
</div>
<!-- Regular Subjects -->
<div class="section-title">
<i class="fas fa-book"></i>
<h4>Regular Subjects</h4>
</div>
<button class="subject-selection-button" onclick="openRegularSubjectsModal()">
<i class="fas fa-plus-circle"></i> Select Regular Subjects
</button>
<table class="table table-striped">
<thead>
<tr>
<th>Subject</th>
<th>Attendance Count</th>
<th>Total Count</th>
<th>Percentage</th>
</tr>
</thead>
<tbody id="tbl-subjects">
{% for subject in selected_regular_subjects %}
<tr>
<td>{{ subject }}</td>
<td>{{ subject_attendance['regular'].get(subject, {}).get('attendance', 0) }}</td>
<td>{{ subject_attendance['regular'].get(subject, {}).get('total', 0) }}</td>
<td>
{% set attendance = subject_attendance['regular'].get(subject, {}).get('attendance', 0) %}
{% set total = subject_attendance['regular'].get(subject, {}).get('total', 0) %}
{% if total > 0 %}
{{ (attendance / total * 100) | round(2) }}%
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Specialization -->
<div class="section-title">
<i class="fas fa-star"></i>
<h4>Specialization Subjects</h4>
</div>
<button class="subject-selection-button" onclick="openSpecializationSubjectsModal()">
<i class="fas fa-plus-circle"></i> Select Specialization Subjects
</button>
<table class="table table-striped">
<thead>
<tr>
<th>Specialization Subject</th>
<th>Attendance Count</th>
<th>Total Count</th>
<th>Percentage</th>
</tr>
</thead>
<tbody id="tbl-spec">
{% for subject in selected_specializations %}
<tr>
<td>{{ subject }}</td>
<td>{{ subject_attendance['specialization'].get(subject, {}).get('attendance', 0) }}</td>
<td>{{ subject_attendance['specialization'].get(subject, {}).get('total', 0) }}</td>
<td>
{% set attendance = subject_attendance['specialization'].get(subject, {}).get('attendance', 0) %}
{% set total = subject_attendance['specialization'].get(subject, {}).get('total', 0) %}
{% if total > 0 %}
{{ (attendance / total * 100) | round(2) }}%
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Practical Subjects -->
<div class="section-title">
<i class="fas fa-flask"></i>
<h4>Practical Subjects</h4>
</div>
<button class="subject-selection-button" onclick="openBatchPracticalsModal()">
<i class="fas fa-plus-circle"></i> Select Batch & Practical Subjects
</button>
<table class="table table-striped">
<thead>
<tr>
<th>Practical Subject</th>
<th>Batch</th>
<th>Attendance Count</th>
<th>Total Count</th>
<th>Percentage</th>
</tr>
</thead>
<tbody id="tbl-prac">
{% for subject in selected_practicals %}
<tr>
<td>{{ subject }}</td>
<td>{{ user.selected_batch or 'N/A' }}</td>
<td>{{ subject_attendance['practical'].get(subject, {}).get('attendance', 0) }}</td>
<td>{{ subject_attendance['practical'].get(subject, {}).get('total', 0) }}</td>
<td>
{% set attendance = subject_attendance['practical'].get(subject, {}).get('attendance', 0) %}
{% set total = subject_attendance['practical'].get(subject, {}).get('total', 0) %}
{% if total > 0 %}
{{ (attendance / total * 100) | round(2) }}%
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Teachers -->
<div class="section-title">
<i class="fas fa-chalkboard-teacher"></i>
<h4>Class Teacher Details</h4>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
{% for teacher in teachers %}
<tr>
<td>{{ teacher.full_name }}</td>
<td>
{% if teacher.email %}
<a href="mailto:{{ teacher.email }}">{{ teacher.email }}</a>
{% else %}
Not provided
{% endif %}
</td>
<td>
{% if teacher.phone_number %}
<a href="tel:{{ teacher.phone_number }}">{{ teacher.phone_number }}</a>
{% else %}
Not provided
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- FACE REGISTRATION -->
<div class="mt-4 text-center">
{% if face_exists %}
<a href="/register_face" class="btn btn-primary">
<i class="fas fa-camera"></i> Re-register Face
</a>
{% else %}
<a href="/register_face" class="btn btn-secondary">
<i class="fas fa-camera"></i> Register Face
</a>
{% endif %}
</div>
<a href="/logout" class="btn btn-link mt-2">
<i class="fas fa-sign-out-alt"></i> Logout
</a>
</div>
</div>
<!-- Modals -->
<div class="modal" id="regularSubjectsModal">
<div class="modal-content">
<span class="close-modal" onclick="closeModal('regularSubjectsModal')"></span>
<h3><i class="fas fa-book"></i> Select Regular Subjects</h3>
<div id="regularSubjectsList"></div>
<button onclick="saveRegularSubjects()"><i class="fas fa-save"></i> Save Selections</button>
</div>
</div>
<div class="modal" id="specializationSubjectsModal">
<div class="modal-content">
<span class="close-modal" onclick="closeModal('specializationSubjectsModal')"></span>
<h3><i class="fas fa-star"></i> Select Specialization Subjects</h3>
<div id="specializationSubjectsList"></div>
<button onclick="saveSpecializationSubjects()"><i class="fas fa-save"></i> Save Selections</button>
</div>
</div>
<div class="modal" id="batchPracticalsModal">
<div class="modal-content">
<span class="close-modal" onclick="closeModal('batchPracticalsModal')"></span>
<h3><i class="fas fa-flask"></i> Select Batch & Practical Subjects</h3>
<label for="batchSelectModal"><i class="fas fa-layer-group"></i> Select Batch:</label>
<select id="batchSelectModal"></select>
<div id="practicalsList"></div>
<button onclick="saveBatchAndPracticals()"><i class="fas fa-save"></i> Save Selections</button>
</div>
</div>
<script>
function openEdit() {
document.getElementById('profile-view').classList.add('hidden');
document.getElementById('profile-edit').classList.remove('hidden');
}
function cancelEdit() {
document.getElementById('profile-edit').classList.add('hidden');
document.getElementById('profile-view').classList.remove('hidden');
}
function saveProfile() {
fetch('/api/update_profile', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
full_name: document.getElementById('edit-fullname').value,
enrollment_number: document.getElementById('edit-enroll').value,
email: document.getElementById('edit-email').value,
student_number: document.getElementById('edit-studno').value,
parent_number: document.getElementById('edit-parentno').value,
parent_email: document.getElementById('edit-parentemail').value
})
}).then(r => r.json()).then(resp => {
if (resp.success) location.reload();
else alert(resp.message);
});
}
let selectedRegularSubjects = {{ selected_regular_subjects | tojson | safe }};
let selectedSpecializations = {{ selected_specializations | tojson | safe }};
let selectedBatch = "{{ user.selected_batch or '' }}";
let selectedPracticals = {{ selected_practicals | tojson | safe }};
document.getElementById('class-select').addEventListener('change', e => {
const cls = e.target.value;
fetch('/api/select_class', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ class: cls })
}).then(_ => {
if (!cls) return location.reload();
document.getElementById('subjects-section').classList.remove('hidden');
document.getElementById('cls-label').innerText = cls;
loadStudentSection(cls);
});
});
function loadStudentSection(cls) {
// Handled by template rendering initially
}
function openRegularSubjectsModal() {
const cls = document.getElementById('class-select').value;
if (!cls) {
alert('Please select a class first');
return;
}
fetch(`/get_config?class=${cls}&type=subject`)
.then(r => r.json())
.then(list => {
const listDiv = document.getElementById('regularSubjectsList');
listDiv.innerHTML = '';
list.forEach(subject => {
const checked = selectedRegularSubjects.includes(subject) ? 'checked' : '';
listDiv.innerHTML += `<label><input type="checkbox" value="${subject}" ${checked}> ${subject}</label><br>`;
});
document.getElementById('regularSubjectsModal').style.display = 'block';
});
}
function openSpecializationSubjectsModal() {
const cls = document.getElementById('class-select').value;
if (!cls) {
alert('Please select a class first');
return;
}
fetch(`/get_config?class=${cls}&type=specSubject`)
.then(r => r.json())
.then(list => {
const listDiv = document.getElementById('specializationSubjectsList');
listDiv.innerHTML = '';
list.forEach(subject => {
const checked = selectedSpecializations.includes(subject) ? 'checked' : '';
listDiv.innerHTML += `<label><input type="checkbox" value="${subject}" ${checked}> ${subject}</label><br>`;
});
document.getElementById('specializationSubjectsModal').style.display = 'block';
});
}
function openBatchPracticalsModal() {
const cls = document.getElementById('class-select').value;
if (!cls) {
alert('Please select a class first');
return;
}
fetch(`/get_config?class=${cls}&type=batch`)
.then(r => r.json())
.then(batches => {
const batchSelect = document.getElementById('batchSelectModal');
batchSelect.innerHTML = '<option value="">-- Select Batch --</option>';
batches.forEach(batch => {
const selected = batch === selectedBatch ? 'selected' : '';
batchSelect.innerHTML += `<option value="${batch}" ${selected}>${batch}</option>`;
});
});
fetch(`/get_config?class=${cls}&type=practical`)
.then(r => r.json())
.then(practicals => {
const listDiv = document.getElementById('practicalsList');
listDiv.innerHTML = '';
practicals.forEach(subject => {
const checked = selectedPracticals.includes(subject) ? 'checked' : '';
listDiv.innerHTML += `<label><input type="checkbox" value="${subject}" ${checked}> ${subject}</label><br>`;
});
document.getElementById('batchPracticalsModal').style.display = 'block';
});
}
function saveRegularSubjects() {
const checkboxes = document.querySelectorAll('#regularSubjectsList input[type="checkbox"]:checked');
const selected = Array.from(checkboxes).map(cb => cb.value);
fetch('/api/update_regular_subjects', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({subjects: selected})
}).then(() => {
location.reload();
});
}
function saveSpecializationSubjects() {
const checkboxes = document.querySelectorAll('#specializationSubjectsList input[type="checkbox"]:checked');
const selected = Array.from(checkboxes).map(cb => cb.value);
fetch('/api/update_specializations', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({subjects: selected})
}).then(() => {
location.reload();
});
}
function saveBatchAndPracticals() {
const batch = document.getElementById('batchSelectModal').value;
const checkboxes = document.querySelectorAll('#practicalsList input[type="checkbox"]:checked');
const selectedPracticals = Array.from(checkboxes).map(cb => cb.value);
fetch('/api/update_batch', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({batch: batch})
}).then(() => {
fetch('/api/update_practicals', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({practicals: selectedPracticals})
}).then(() => {
location.reload();
});
});
}
function closeModal(modalId) {
document.getElementById(modalId).style.display = 'none';
}
window.addEventListener('DOMContentLoaded', () => {
const cs = document.getElementById('class-select');
if (cs.value) cs.dispatchEvent(new Event('change'));
// Calculate overall average
const percentageCells = document.querySelectorAll('#tbl-subjects td:last-child, #tbl-spec td:last-child, #tbl-prac td:last-child');
let sum = 0;
let count = 0;
percentageCells.forEach(cell => {
const text = cell.textContent.trim();
if (text !== 'N/A') {
const percentage = parseFloat(text.replace('%', ''));
sum += percentage;
count++;
}
});
const average = count > 0 ? (sum / count).toFixed(2) : 'N/A';
document.getElementById('overall-average').textContent = average === 'N/A' ? 'N/A' : average + '%';
});
</script>
</body>
</html>