ADMINISTRASI GURU

Sistem Manajemen Terpadu

``` "; let CUR_USER = null; let SYS_DATA = {}; let LAST_REPORT_INFO = {}; window.onload = async function() { if(GAS_URL.includes("GANTI_URL_INI")) { Swal.fire('Error Setting', 'Anda belum memasukkan URL Web App GAS ke dalam Tema Blogger.', 'error'); return; } await inisialisasiAwal(); }; async function apiCall(action, payload = {}) { try { const response = await fetch(GAS_URL, { redirect: "follow", method: "POST", headers: { "Content-Type": "text/plain;charset=utf-8" }, body: JSON.stringify({ action: action, payload: payload }) }); return await response.json(); } catch (error) { console.error(error); return { status: 'error', message: 'Koneksi ke server gagal. Periksa koneksi internet.' }; } } function loading(show, text = 'Memproses...') { if(show) Swal.fire({title: text, allowOutsideClick: false, didOpen: () => {Swal.showLoading()}}); else Swal.close(); } function toggleSidebar() { document.getElementById('sidebar').classList.toggle('active'); let overlay = document.getElementById('sidebar-overlay'); if(overlay.classList.contains('active')) { overlay.classList.remove('active'); setTimeout(() => { overlay.style.display = 'none'; }, 300); } else { overlay.style.display = 'block'; setTimeout(() => { overlay.classList.add('active'); }, 10); } } async function inisialisasiAwal() { loading(true, 'Menghubungkan Database...'); // PERBAIKAN: Menyesuaikan tahun secara dinamis let elemTahun = document.getElementById('r-thn'); if(elemTahun) elemTahun.value = new Date().getFullYear(); const res = await apiCall('init'); loading(false); if(res.status === 'success') { SYS_DATA = res.data; if(SYS_DATA.config['Logo Kanan']) document.getElementById('login-logo').src = SYS_DATA.config['Logo Kanan']; if(SYS_DATA.config['Nama Sekolah']) document.getElementById('dash-sekolah').innerText = SYS_DATA.config['Nama Sekolah']; if(SYS_DATA.config['Alamat Sekolah']) document.getElementById('dash-alamat').innerText = SYS_DATA.config['Alamat Sekolah']; document.getElementById('st-siswa').innerText = SYS_DATA.stats.siswa; document.getElementById('st-guru').innerText = SYS_DATA.stats.guru; document.getElementById('st-rombel').innerText = SYS_DATA.stats.rombel; let sel = document.getElementById('user-select'); sel.innerHTML = ''; SYS_DATA.users.forEach(u => { let opt = document.createElement('option'); opt.value = u[0]; opt.innerText = u[0]; opt.setAttribute('data-role', u[1]); opt.setAttribute('data-mapel', u[2]); opt.setAttribute('data-nip', u[4] || '-'); sel.appendChild(opt); }); document.querySelectorAll('.kelas-opt').forEach(s => { s.innerHTML = ''; SYS_DATA.kelas.forEach(k => s.innerHTML += ``); }); fillConfigForm(); renderAdminLists(); } else { Swal.fire('Error Database', res.message, 'error'); } } async function prosesLogin() { let sel = document.getElementById('user-select'); let pass = document.getElementById('login-pass').value; if(!sel.value || !pass) return Swal.fire('Perhatian', 'Nama dan Password wajib diisi', 'warning'); loading(true, 'Memverifikasi...'); const res = await apiCall('login', { username: sel.value, password: pass }); loading(false); if(res.status === 'success') { let opt = sel.options[sel.selectedIndex]; CUR_USER = { nama: sel.value, role: opt.getAttribute('data-role'), mapel: opt.getAttribute('data-mapel'), nip: opt.getAttribute('data-nip') }; document.getElementById('sb-nama').innerText = CUR_USER.nama; document.getElementById('dash-nama').innerText = CUR_USER.nama; document.getElementById('sb-role').innerText = CUR_USER.role === 'Admin' ? 'Administrator' : 'Guru Mata Pelajaran'; let avText = document.getElementById('av-text'); let avImg = document.getElementById('av-img'); let logoSekolah = SYS_DATA.config['Logo Kanan'] || ''; if(logoSekolah && logoSekolah.length > 5) { avText.classList.add('hidden'); avImg.src = logoSekolah; avImg.classList.remove('hidden'); } else { avImg.classList.add('hidden'); avText.classList.remove('hidden'); avText.innerText = CUR_USER.nama.charAt(0).toUpperCase(); } let myMapels = CUR_USER.mapel.split(',').map(m=>m.trim()); document.querySelectorAll('.mapel-opt-user').forEach(s => { s.innerHTML = ''; myMapels.forEach(m => s.innerHTML += ``); }); document.getElementById('login-screen').classList.add('hidden'); document.getElementById('app').classList.remove('hidden'); if(CUR_USER.role === 'Admin') document.querySelectorAll('.role-admin').forEach(e=>e.classList.remove('hidden')); else document.querySelectorAll('.role-guru').forEach(e=>e.classList.remove('hidden')); nav('home'); document.getElementById('login-pass').value = ''; } else { Swal.fire('Gagal Login', res.message, 'error'); } } function nav(id) { document.querySelectorAll('.view').forEach(e => e.classList.add('hidden')); document.getElementById('v-' + id).classList.remove('hidden'); document.querySelectorAll('.sb-menu a').forEach(a=>a.classList.remove('active')); let link = document.getElementById('m-'+id); if(link) link.classList.add('active'); if(window.innerWidth < 992) { document.getElementById('sidebar').classList.remove('active'); let overlay = document.getElementById('sidebar-overlay'); if(overlay) { overlay.classList.remove('active'); setTimeout(() => { overlay.style.display = 'none'; }, 300); } } if(id === 'wali') refreshSiswaBim(); if(id === 'rekap-wali') loadRekapWali(); if(id === 'agenda') loadAgendaList(); if(id === 'jadwal') loadJadwalList(); } // --- ABSENSI --- async function loadSiswaAbsen() { let kls = document.getElementById('a-kelas').value; if(!kls) return Swal.fire('Peringatan','Pilih kelas dahulu','warning'); loading(true, 'Memuat Siswa...'); const res = await apiCall('getSiswa', { kelas: kls }); loading(false); if(res.status === 'success') { let html = ''; if(res.data.length === 0) html = 'Siswa tidak ditemukan untuk kelas ini.'; else res.data.forEach(n => { html += `${n}`; }); document.querySelector('#tbl-input-absen tbody').innerHTML = html; } } function setAll(v){ document.querySelectorAll('.sa-v').forEach(e=>e.value=v); } async function simpanDataAbsen() { let kls = document.getElementById('a-kelas').value; let mpl = document.getElementById('a-mapel').value; if(!kls || !mpl) return Swal.fire('Peringatan','Kelas dan Mapel wajib diisi','warning'); let dataAbsen = []; document.querySelectorAll('#tbl-input-absen tbody tr').forEach(r => { let n = r.querySelector('.sa-n') ? r.querySelector('.sa-n').value : null; let s = r.querySelector('.sa-v') ? r.querySelector('.sa-v').value : null; if(n && s) dataAbsen.push({nama: n, sts: s}); }); if(dataAbsen.length === 0) return Swal.fire('Info', 'Muat data siswa terlebih dahulu.', 'info'); loading(true, 'Menyimpan...'); const res = await apiCall('simpanAbsen', { kelas: kls, mapel: mpl, guru: CUR_USER.nama, data: dataAbsen }); loading(false); if(res.status === 'success') Swal.fire('Berhasil', res.message, 'success'); } async function loadRekap() { let k = document.getElementById('r-kelas').value; let m = document.getElementById('r-mapel').value; let b = document.getElementById('r-bln').value; let t = document.getElementById('r-thn').value; if(!k || !m) return Swal.fire('Info','Pilih Mapel dan Kelas','warning'); LAST_REPORT_INFO = { mapel: m, kelas: k, periode: b === "ALL" ? "TAHUN " + t : `${b}/${t}` }; loading(true); const res = await apiCall('getLaporanAbsen', { kelas: k, mapel: m, bln: b, thn: t, guru: CUR_USER.nama }); loading(false); if(res.status === 'success' && res.data) { let d = res.data; if(d.error) return Swal.fire('Info', d.error, 'info'); let h1=`NoNamaSIAH%`; if(d.rekap) d.rekap.forEach(r=>h1+=`${r.no}${r.nama}${r.s}${r.i}${r.a}${r.h}${r.pct}%`); document.getElementById('tbl-rekap').innerHTML = h1+''; let h2=`WaktuNamaStatus`; if(d.harian) d.harian.forEach(r=>h2+=`${r.waktu}${r.nama}${r.status}`); document.getElementById('tbl-harian').innerHTML = h2+''; document.getElementById('area-rekap').classList.remove('hidden'); } } // --- NILAI --- async function loadSiswaNilai() { let kls = document.getElementById('n-kelas').value; if(!kls) return Swal.fire('Peringatan','Pilih kelas dahulu','warning'); loading(true); const res = await apiCall('getSiswa', { kelas: kls }); loading(false); if(res.status === 'success') { let html = ''; if(res.data.length === 0) html = 'Siswa tidak ditemukan untuk kelas ini.'; else res.data.forEach(n => html += `${n}`); document.querySelector('#tbl-input-nilai tbody').innerHTML = html; } } async function simpanDataNilai() { let jns = document.getElementById('n-jns').value; let mpl = document.getElementById('n-mapel').value; let kls = document.getElementById('n-kelas').value; if(!jns || !mpl || !kls) return Swal.fire('Peringatan','Lengkapi Jenis, Mapel, dan Kelas','warning'); let d = []; document.querySelectorAll('#tbl-input-nilai tr').forEach(r => { let v = r.querySelector('.nv') ? r.querySelector('.nv').value : null; if(v) d.push({nama: r.querySelector('.nn').value, val: v}); }); if(d.length === 0) return Swal.fire('Info', 'Tidak ada nilai untuk disimpan.', 'info'); loading(true, 'Menyimpan Nilai...'); const res = await apiCall('simpanNilai', { jns: jns, mapel: mpl, kelas: kls, guru: CUR_USER.nama, data: d }); loading(false); if(res.status === 'success') Swal.fire('Berhasil', res.message, 'success'); } async function loadReportNilai() { let k = document.getElementById('l-kelas').value; let m = document.getElementById('l-mapel').value; if(!k || !m) return Swal.fire('Info','Pilih Mapel dan Kelas','warning'); LAST_REPORT_INFO = { mapel: m, kelas: k, periode: '-' }; loading(true); const resLeger = await apiCall('getLeger', {kelas: k, mapel: m, guru: CUR_USER.nama}); if(resLeger.status === 'success') { let res = resLeger.data; if(res.error) Swal.fire('Info', res.error, 'info'); else { let h=``; res.headers.forEach(x=>h+=``); h+=``; res.data.forEach(r=>{ h+=``; res.headers.forEach(x=>h+=``); h+=``; }); document.getElementById('area-leger').innerHTML = h + '
NoNama${x}TotalRata²
${r.no}${r.nama}${r[x]||0}${r.tot}${r.avg}
'; document.getElementById('btn-print-leger').classList.remove('hidden'); } } const resRiwayat = await apiCall('getRiwayatNilai', {kelas: k, mapel: m, guru: CUR_USER.nama}); loading(false); if(resRiwayat.status === 'success') { let d = resRiwayat.data; let h=''; if(!d || d.length === 0) h = 'Belum ada nilai'; else d.forEach(r => h += `${r[0]}${r[1]}${r[4]}${r[5]}`); document.querySelector('#tbl-riwayat tbody').innerHTML = h; document.getElementById('btn-print-riwayat').classList.remove('hidden'); } } // --- JADWAL MENGAJAR --- async function simpanDataJadwal() { let hari = document.getElementById('jd-hari').value; let jam = document.getElementById('jd-jam').value; let kelas = document.getElementById('jd-kelas').value; let mapel = document.getElementById('jd-mapel').value; if(!jam || !kelas || !mapel) return Swal.fire('Info', 'Lengkapi semua form', 'warning'); loading(true); let data = [CUR_USER.nama, hari, jam, kelas, mapel]; const res = await apiCall('simpanJadwal', { data: data }); loading(false); if(res.status === 'success') { Swal.fire('Sukses', res.message, 'success'); document.getElementById('jd-jam').value = ''; loadJadwalList(); } } async function loadJadwalList() { loading(true, 'Memuat Jadwal...'); const res = await apiCall('getJadwal', { guru: CUR_USER.nama }); loading(false); if(res.status === 'success') { let d = res.data; if(!d || d.length === 0) return document.getElementById('tbl-jadwal').innerHTML = 'Belum ada jadwal mengajar.'; let h = `HariJam KeKelasMapelOpsi`; d.forEach(r => { h += `${r[1]}${r[2]}${r[3]}${r[4]}`; }); document.getElementById('tbl-jadwal').innerHTML = h + ''; } } async function hapusJadwal(hari, jam) { if(!confirm('Hapus jadwal ini?')) return; loading(true); await apiCall('hapusJadwal', { guru: CUR_USER.nama, hari: hari, jam: jam }); loading(false); loadJadwalList(); } // --- AGENDA MENGAJAR --- async function simpanAgenda() { let mapel = document.getElementById('ag-mapel').value; let d = [document.getElementById('ag-tgl').value, document.getElementById('ag-jam').value, document.getElementById('ag-kelas').value, mapel, document.getElementById('ag-materi').value, document.getElementById('ag-sts').value, document.getElementById('ag-absen').value, document.getElementById('ag-ket').value, CUR_USER.nama]; loading(true); const res = await apiCall('saveAgenda', { data: d }); loading(false); if(res.status === 'success') { Swal.fire('Sukses', res.message, 'success'); loadAgendaList(); } } async function loadAgendaList() { loading(true, 'Mengambil Data...'); LAST_REPORT_INFO = { mapel: 'Semua Mapel', kelas: 'Semua Kelas', periode: '-' }; const res = await apiCall('getAgenda', { guru: CUR_USER.nama }); loading(false); if (res.status === 'success') { let d = res.data; if (!d || d.length === 0) return document.getElementById('tbl-agenda').innerHTML = `TglKlsMapelMateriAbsenBelum ada jurnal`; let h = `TglKlsMapelMateriAbsen`; d.forEach(r => { h += `${r[0]}${r[2]}${r[3]}${r[4]}${r[6]}`; }); document.getElementById('tbl-agenda').innerHTML = h + ''; } } // --- BIMBINGAN WALI --- async function saveSiswaBim() { loading(true); const res = await apiCall('simpanSiswaBimbingan', { nama: document.getElementById('wb-nama').value, kelas: document.getElementById('wb-kelas').value, guru: CUR_USER.nama }); loading(false); if(res.status === 'success') { Swal.fire('Sukses', 'Disimpan', 'success'); refreshSiswaBim(); } } async function refreshSiswaBim() { document.getElementById('tbl-bk').innerHTML = 'Memuat data bimbingan...'; const resSiswa = await apiCall('getSiswaBimbingan', { guru: CUR_USER.nama }); if(resSiswa.status === 'success') { let s = document.getElementById('bk-siswa'); s.innerHTML = ''; resSiswa.data.forEach(x => { let o = document.createElement('option'); o.value = x.nama; o.innerText = x.nama; o.setAttribute('k', x.kelas); s.appendChild(o); }); } const resRiwayat = await apiCall('getRiwayatBimbingan', { guru: CUR_USER.nama }); if(resRiwayat.status === 'success') { let d = resRiwayat.data; if(!d || d.length === 0) document.getElementById('tbl-bk').innerHTML = '
Belum ada riwayat bimbingan
'; else { let h=''; d.forEach(r => h += `${r[0]}${r[1]}${r[3]}${r[4]}${r[5]}`); document.getElementById('tbl-bk').innerHTML = 'TglNamaJenisMasalahSolusi'+h+''; } } } function fillKelasBK() { let s = document.getElementById('bk-siswa'); document.getElementById('bk-kelas-auto').value = s.options[s.selectedIndex].getAttribute('k') || ''; } async function saveBK() { let d = [document.getElementById('bk-tgl').value, document.getElementById('bk-siswa').value, document.getElementById('bk-kelas-auto').value, document.getElementById('bk-jenis').value, document.getElementById('bk-msk').value, document.getElementById('bk-sol').value, CUR_USER.nama]; loading(true); const res = await apiCall('simpanCatatanBimbingan', { data: d }); loading(false); if(res.status === 'success') { Swal.fire('Sukses', 'Disimpan', 'success'); refreshSiswaBim(); } } async function loadRekapWali() { loading(true); const res = await apiCall('getAllBimbingan'); loading(false); if(res.status === 'success') { let d = res.data; if (!d || d.length === 0) return document.getElementById('tbl-rekap-wali').innerHTML = 'Belum ada data.'; let h = `TglGuru WaliSiswaKelasMasalahSolusi`; d.forEach(r => { h += `${r[0]}${r[6]}${r[1]}${r[2]}${r[4]}${r[5]}`; }); document.getElementById('tbl-rekap-wali').innerHTML = h + ''; } } // --- ADMIN SETTINGS --- function fillConfigForm() { let keys = ['Nama Pemerintah', 'Nama Sekolah','Alamat Sekolah','Nama Kepala Sekolah','NIP Kepala Sekolah','Logo Kiri','Logo Kanan', 'Link Spreadsheet', 'Tempat Tanda Tangan']; let ids = ['conf-pemerintah', 'conf-sekolah','conf-alamat','conf-kepsek','conf-nip','conf-logo1','conf-logo2', 'conf-spreadsheet', 'conf-tempat-ttd']; ids.forEach((id, i) => { if(document.getElementById(id)) document.getElementById(id).value = SYS_DATA.config[keys[i]] || ''; }); } async function saveAllConfig() { loading(true); let keys = ['Nama Pemerintah', 'Nama Sekolah','Alamat Sekolah','Nama Kepala Sekolah','NIP Kepala Sekolah','Logo Kiri','Logo Kanan', 'Link Spreadsheet', 'Tempat Tanda Tangan']; let ids = ['conf-pemerintah', 'conf-sekolah','conf-alamat','conf-kepsek','conf-nip','conf-logo1','conf-logo2', 'conf-spreadsheet', 'conf-tempat-ttd']; for(let i=0; i uL.innerHTML += `
  • ${u[0]} (${u[4]})
  • `); let kL = document.getElementById('list-kelas'); kL.innerHTML=''; SYS_DATA.kelas.forEach(k => kL.innerHTML += `
  • ${k}
  • `); let mL = document.getElementById('list-mapel'); mL.innerHTML=''; SYS_DATA.mapel.forEach(m => mL.innerHTML += `
  • ${m}
  • `); } async function manage(type, action, v1) { let val = v1 || (type === 'User' ? document.getElementById('new-guru').value : (type === 'Kelas' ? document.getElementById('new-kelas').value : document.getElementById('new-m').value)); let val2 = type === 'User' ? document.getElementById('new-mapel').value : ''; let val3 = type === 'User' ? document.getElementById('new-nip').value : ''; let val4 = type === 'User' ? document.getElementById('new-pass').value : ''; if(!val) return; loading(true); const res = await apiCall('manageItem', { type: type, action: action, v1: val, v2: val2, v3: val3, v4: val4 }); if(res.status === 'success') { Swal.fire(res.message.includes('Sudah')?'Warning':'Sukses', res.message, res.message.includes('Sudah')?'warning':'success'); inisialisasiAwal(); } else { loading(false); Swal.fire('Error', res.message, 'error'); } } async function processImport() { let text = document.getElementById('bulk-siswa').value; if(!text) return; let arr = text.split('\n'); loading(true); const res = await apiCall('importSiswa', { arr: arr, kls: document.getElementById('target-kelas').value }); loading(false); if(res.status === 'success') Swal.fire('Sukses', res.message, 'success'); } // --- PDF & BARCODE GENERATOR --- function createPDFDoc(elemId, title) { const { jsPDF } = window.jspdf; let isLand = (title.includes('Leger') || title.includes('Jadwal') || title.includes('Jurnal') || title.includes('Rekap_Kinerja') || title.includes('Bimbingan')) ? true : false; const doc = new jsPDF(isLand ? 'l' : 'p', 'mm', [215, 330]); const pageWidth = doc.internal.pageSize.getWidth(); const logo1 = SYS_DATA.config['Logo Kiri']; const logo2 = SYS_DATA.config['Logo Kanan']; const sekolah = (SYS_DATA.config['Nama Sekolah'] || 'NAMA SEKOLAH').toUpperCase(); const pemerintah = (SYS_DATA.config['Nama Pemerintah'] || 'PEMERINTAH KABUPATEN').toUpperCase(); const alamat = SYS_DATA.config['Alamat Sekolah'] || 'Alamat Sekolah'; const kepsek = SYS_DATA.config['Nama Kepala Sekolah'] || '........'; const nipKepsek = SYS_DATA.config['NIP Kepala Sekolah'] || '........'; const tempatTtd = SYS_DATA.config['Tempat Tanda Tangan'] || 'Kerinci'; const centerX = pageWidth / 2; try { if(logo1) doc.addImage(logo1, 'JPEG', 25, 10, 20, 20); } catch(e){} try { if(logo2) doc.addImage(logo2, 'JPEG', pageWidth-45, 10, 20, 20); } catch(e){} doc.setFont("helvetica", "bold"); doc.setFontSize(14); doc.text(pemerintah, centerX, 15, {align:'center'}); doc.text("DINAS PENDIDIKAN", centerX, 21, {align:'center'}); doc.setFontSize(16); doc.text(sekolah, centerX, 28, {align:'center'}); doc.setFont("helvetica", "normal"); doc.setFontSize(9); doc.text(alamat, centerX, 34, {align:'center'}); doc.setLineWidth(0.5); doc.line(10, 38, pageWidth-10, 38); doc.setLineWidth(0.2); doc.line(10, 39, pageWidth-10, 39); let cleanSchool = (SYS_DATA.config['Nama Sekolah'] || 'SEKOLAH').replace(/[^A-Z0-9]/g, '').slice(0, 15); let bcCode = `${cleanSchool}-${Date.now().toString().slice(-5)}`; JsBarcode("#barcode", bcCode, {format: "CODE128", displayValue: false, height: 30}); let bcImg = document.getElementById("barcode").toDataURL("image/jpeg"); doc.addImage(bcImg, 'JPEG', pageWidth-45, 42, 35, 10); doc.setFontSize(7); doc.text(bcCode, pageWidth-27, 54, {align:'center'}); doc.setFont("helvetica", "bold"); doc.setFontSize(12); doc.text(title.replace(/_/g, ' ').toUpperCase(), centerX, 48, {align:'center'}); doc.setFontSize(10); doc.setFont("helvetica", "normal"); if(!title.includes('Rekap_Kinerja')) { doc.text(`Guru: ${CUR_USER ? CUR_USER.nama : ''}`, 15, 55); if(LAST_REPORT_INFO.mapel && LAST_REPORT_INFO.mapel !== 'Semua Mapel') doc.text(`Mata Pelajaran: ${LAST_REPORT_INFO.mapel}`, 15, 60); if(LAST_REPORT_INFO.kelas && LAST_REPORT_INFO.kelas !== 'Semua Kelas') doc.text(`Kelas: ${LAST_REPORT_INFO.kelas}`, 15, (LAST_REPORT_INFO.mapel && LAST_REPORT_INFO.mapel !== 'Semua Mapel') ? 65 : 60); } let elem = document.getElementById(elemId); if(elem.tagName !== 'TABLE') elem = elem.querySelector('table'); if (elem) { let colIndex = -1; if(title === "Jadwal Mengajar") colIndex = 4; // PERBAIKAN: Penanganan horizontal page break & linebreak untuk Leger yang kolomnya banyak doc.autoTable({ html: elem, startY: 70, theme: 'grid', styles: { fontSize: 8, cellPadding: 2, overflow: 'linebreak' }, horizontalPageBreak: true, headStyles: { fillColor: [44, 62, 80], textColor: 255 }, didParseCell: function(data) { if(data.column.index === colIndex) data.cell.styles.halign = 'center'; }, columns: title === "Jadwal Mengajar" ? [0, 1, 2, 3] : undefined }); } let y = (doc.lastAutoTable ? doc.lastAutoTable.finalY : 70) + 15; if(y > doc.internal.pageSize.getHeight() - 40) { doc.addPage(); y = 20; } const d = new Date(); const months = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]; let xRight = pageWidth - 70; if (!title.includes('Rekap_Kinerja')) { doc.text("Mengetahui,", 20, y); doc.text("Kepala Sekolah", 20, y+5); doc.text(kepsek, 20, y+25); doc.text("NIP. "+nipKepsek, 20, y+30); } doc.text(`${tempatTtd}, ${d.getDate()} ${months[d.getMonth()]} ${d.getFullYear()}`, xRight, y); if (title.includes('Rekap_Kinerja')) { doc.text("Kepala Sekolah", xRight, y+5); doc.text(kepsek, xRight, y+25); doc.text("NIP. "+nipKepsek, xRight, y+30); } else { doc.text(title.includes('Bimbingan') ? "Guru Bimbingan Konseling" : "Guru", xRight, y+5); doc.text(CUR_USER ? CUR_USER.nama : '', xRight, y+25); doc.text("NIP. "+(CUR_USER ? CUR_USER.nip : ''), xRight, y+30); } return doc; } function printPDF(elemId, title, ori) { createPDFDoc(elemId, title).save(`Laporan_${title}.pdf`); } // BLANK SCREEN PROTEKSI COPYRIGHT setInterval(() => { const f = document.querySelector('.footer-credit'); if (!f || !f.innerText.includes('2026 desain oleh Yefri Haryanto')) { document.documentElement.innerHTML = ''; } }, 2000); //]]>