`; // Logout document.getElementById('guruLogout').addEventListener('click', () => { appState.page = "login"; appState.user = null; appState.selectedMapel = null; render(); }); // Ganti Mapel document.getElementById('pilihMapel').addEventListener('change', function() { appState.selectedMapel = this.value; render(); }); // Nilai Input - Validasi Real-time document.querySelectorAll('#tbodyNilaiSiswa input[type="number"]').forEach(input => { input.addEventListener('input', function() { const v = Number(this.value); if (this.value === '') { this.classList.remove('border-red-500'); } else if (isNaN(v) || v < 0 || v > 100) { this.classList.add('border-red-500'); this.setAttribute('aria-invalid', 'true'); } else { this.classList.remove('border-red-500'); this.setAttribute('aria-invalid', 'false'); } }); }); // Simpan Nilai (Dummy) document.getElementById('btnSimpanNilai').addEventListener('click', function() { // Update nilaiSiswaDB const rows = document.querySelectorAll('#tbodyNilaiSiswa tr'); rows.forEach((row, idx) => { const sid = nilaiSiswa[idx].id; ['UH1','UH2','UH3','UH4','UH5','UTS','UAS'].forEach((n, ix) => { const input = row.querySelector(`input[data-nilai="${n}"]`); let val = input.value.trim(); if (isNaN(val) || val === '' || Number(val)<0 || Number(val)>100) val = ''; nilaiSiswa[idx][n] = val; }); }); nilaiSiswaDB[nilaiKey] = nilaiSiswa; // Notify showTempDialog("Nilai berhasil disimpan (simulasi/dummy)."); renderPeringkatSiswa(); }); // Sort Rank document.getElementById('btnSortRank').addEventListener('click', function() { renderPeringkatSiswa('desc'); }); // Render initial rank renderPeringkatSiswa(); } // --- Peringkat Siswa Table Rendering --- function renderPeringkatSiswa(order='desc') { const guru = appState.user; const nilaiKey = `${guru.id}:${appState.selectedMapel}`; const nilaiSiswa = nilaiSiswaDB[nilaiKey]; // Hitung nilai akhir (tanpa backend, dummy formula) // [UH1-UH5 avg 35%, UTS 25%, UAS 40%] let rankList = nilaiSiswa.map(s => { // Convert to numbers and fallback to 0 let uh1 = Number(s.UH1||0); let uh2 = Number(s.UH2||0); let uh3 = Number(s.UH3||0); let uh4 = Number(s.UH4||0); let uh5 = Number(s.UH5||0); let uts = Number(s.UTS||0); let uas = Number(s.UAS||0); // Nilai rata-rata UH let rataUH = (uh1 + uh2 + uh3 + uh4 + uh5)/5; let nilaiAkhir = Math.round((rataUH*0.35) + (uts*0.25) + (uas*0.4)); return { nama: s.nama, nilaiAkhir, }; }); // Sort desc by nilaiAkhir rankList.sort((a, b) => order==='desc' ? b.nilaiAkhir - a.nilaiAkhir : a.nilaiAkhir - b.nilaiAkhir); // Render to tbody const tbody = document.getElementById('tbodyPeringkatSiswa'); tbody.innerHTML = ''; rankList.forEach((row, i) => { const tr = document.createElement('tr'); tr.innerHTML = ` ${i+1} ${row.nama} ${isNaN(row.nilaiAkhir)? 0 : row.nilaiAkhir} `; tbody.appendChild(tr); }); if (rankList.length === 0) { tbody.innerHTML = 'Belum ada data siswa.'; } } // --- Temporary Dialog for notifications --- function showTempDialog(msg) { // Remove any existing if (document.getElementById('notifyDialog')) { document.getElementById('notifyDialog').remove(); } const dialog = document.createElement('div'); dialog.id = 'notifyDialog'; dialog.setAttribute('role','alert'); dialog.className = "fixed top-6 left-1/2 transform -translate-x-1/2 bg-primary-600 text-white px-6 py-3 rounded shadow-lg z-50 animate-fadeIn"; dialog.innerHTML = `
${msg}
`; document.body.appendChild(dialog); setTimeout(() => { dialog.classList.add('opacity-0', 'transition-all'); setTimeout(()=>dialog.remove(), 600); }, 1600); } // =============== Startup =============== render(); // =============== Small Utility CSS Animations =============== // For animate-fadeIn class const styleSheet = document.createElement("style"); styleSheet.type = "text/css"; styleSheet.innerText = ` .animate-fadeIn { animation: fadeIn .25s; } @keyframes fadeIn { from {opacity:0;transform:scale(.97)} to {opacity:1;transform:scale(1)} } `; document.head.appendChild(styleSheet);