// ===== APP CONFIG =====
// URL API PHP untuk koneksi ke MySQL Rumahweb
var API_URL = "api.php";
// URL Google Apps Script untuk handle upload/download Google Drive (TETAP)
var SCRIPT_URL = "https://script.google.com/macros/s/AKfycbygNw-Sw9_9z2PcaIHx74dDWvYYxp0vF6XtC-fAlTmCvMkEycf3bnduonWAuVDG3TW3/exec";
var USERS = {
'admin':{password:'veiahmad1984',role:'admin',nama:'Bang Vei',label:'ADMIN'},
'timup2d':{password:'huraa123',role:'petugas',nama:'Tim UP2D S2JB',label:'PETUGAS'},
'pengawas':{password:'pengawas123',role:'pengawas_k3',nama:'Pengawas K3',label:'PENGAWAS K3'},
'supervisor':{password:'supervisor123',role:'supervisor',nama:'Supervisor',label:'SUPERVISOR'},
'kuyung':{password:'teknik123',role:'supervisor',nama:'Kuyung Endang',label:'SUPERVISOR'},
'uids2jb':{password:'123',role:'supervisor',nama:'UID S2JB',label:'SUPERVISOR'},
'up2d':{password:'up2ds2jb',role:'supervisor',nama:'UP2D S2JB',label:'SUPERVISOR'}
};
var PERMS = { admin:{dashboard:true,tambah:true,view:true,edit:true,delete:true}, petugas:{dashboard:false,tambah:true,view:true,edit:false,delete:false}, pengawas_k3:{dashboard:false,tambah:false,view:true,edit:false,delete:false}, supervisor:{dashboard:true,tambah:true,view:true,edit:false,delete:false} };
var ROLE_REDIRECT = {admin:'dashboard',petugas:'add',pengawas_k3:'list',supervisor:'list'};
var dataPekerjaan = {
"TIM PEMELIHARAAN GH DAN PMCB PREVENTIF (Inspeksi)": {
"ASSESSMENT TIER 1 (TANPA PADAM)": ["Pemeriksaan Lingkungan Kondisi Bangunan GH","Pemeriksaan Kondisi Cubicle, Pendataan Cubicle","Pengecekan kondisi PMCB, Pendataan PMCB","Mengisi Dokumentasi Hasil Pemeliharaan & Pencatatan Data Asset"],
"ASSESSMENT TIER 2 (TANPA PADAM)": ["Pengecekan dan Pengukuran Supply AC/DC","Pengecekan Kabel Wiring","Pengecekan Relay Proteksi","Pengecekan Setting Proteksi PMCB","Pengukuran Suhu (termovision)","Pengukuran suara dan bau (Partial Discharge)","Mengisi Dokumentasi Hasil Pemeliharaan"]
},
"TIM PEMELIHARAAN GH DAN PMCB KOREKTIF (HAR)": {
"Pemeliharaan Peralatan Mekanik GH (Incoming dan Kopel)": ["Pengecekan dan Perbaikan Wiring Cubicle","Pengujian Fungsi Mekanik Cubicle","Pembersihan Kompartement Cubicle","Pembersihan Kompartement Kabel Wiring","Pembersihan Kompartemen Busbar","Pengecekan dan Pelumasan Mekanik Atas","Pengujian Tahanan Kontak Busbar, DS","Pengujian Tahanan Isolasi DS, Busbar","Pengecekan dan Pemasangan Terminasi Kabel Tanah","Pengukuran Pentanahan","Perbaikan Grounding","Pengecekan dan Penggantian Heater","Perbaikan Tutup Bawah Cubicle","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pemeliharaan Peralatan Mekanik GH (Outgoing)": ["Pengecekan dan Perbaikan Wiring Cubicle","Pengujian Fungsi Mekanik Cubicle","Pembersihan Kompartement Cubicle","Pembersihan Kompartement Kabel Wiring","Pembersihan Kompartemen Busbar","Pembersihan Kompartemen PMT/CT","Pengecekan dan Pelumasan Mekanik Atas","Pengecekan dan Pelumasan Mekanik CB","Pengecekan dan Perbaikan Wiring Supply, Lampu Indikator, Tombol","Pengecekan dan penggantian Tripping Coil, Motorize","Pengujian kecepatan dan keserempakan PMT","Pengujian Tahanan Kontak busbar, DS dan PMT","Pengujian CT/PT","Pengujian Tahanan Isolasi DS, PMT, Busbar","Pengukuran Pentanahan","Perbaikan Grounding","Pengecekan dan Penggantian Heater","Perbaikan Tutup Bawah Cubicle","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pemeliharaan PMCB": ["Pengecekan Panel PMCB","Pengecekan Dan Perbaikan Mekanik PMCB","Perbaikan Wiring PMCB","Mengisi Dokumentasi Hasil Pemeliharaan","Menaikkan Box KPL/PMCB"],
"Pembongkaran Cubicle Incoming/ Couple": ["Pembongkaran Cubicle Incoming/ Couple","Pembongkaran Wiring Cubicle","Pembongkaran Kabel Tanah","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pemasangan Cubicle Incoming/ Couple": ["Pemasangan Cubicle","Re Wiring Cubicle","Pemasangan Kabel Tanah","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pembongkaran Cubicle Outgoing": ["Pembongkaran Cubicle Outgoing","Pembongkaran Wiring Cubicle","Pembongkaran Kabel Tanah","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pemasangan Cubicle Outgoing": ["Pemasangan Cubicle","Re Wiring Cubicle","Re Wiring Relay","Pemasangan Kabel Tanah","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pembongkaran PMCB": ["Pembongkaran PMCB","Pembongkaran Panel","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pemasangan PMCB": ["Pemasangan PMCB","Pemasangan Panel","Re Wiring PMCB","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pemasangan CT/PT": ["Penggantian CT/PT","Pengujian CT/PT","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pengecekan dan Pemasangan Terminasi Kabel Tanah": ["Pengecekan dan Pemasangan Terminasi Kabel Tanah","Pemasangan Heatsring Kabel Tanah","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Penggantian PMT": ["Penggantian PMT","Pengujian PMT","Bongkar Dan Pasang Kabel Tanah","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Relay Proteksi GH": ["Pengecekan dan Perbaikan Wiring Relay Proteksi","Pengujian Relay Proteksi","Re setting Relay Proteksi","Penggantian Relay Proteksi","Mengisi Dokumentasi Hasil Pemeliharaan"],
"Pembongkaran LBS/Recloser": ["Pembongkaran LBS/Recloser","Mengisi Dokumentasi Hasil Pemeliharaan & Pencatatan Data Asset"],
"Pemasangan LBS/Recloser": ["Pemasangan LBS/Recloser","Mengisi Dokumentasi Hasil Pemeliharaan & Pencatatan Data Asset"]
},
"TIM PEMELIHARAAN KEY PONT LINE (KPL)": {
"ASSESSMENT TIER 1 (TANPA PADAM)": ["Pengamatan secara visual IED","Pengamatan secara visual Modem","Pembersihan lingkungan sekitar Key point","Pembersihan Panel IED Key Point"],
"ASSESSMENT TIER 2 (TANPA PADAM)": ["Pemeriksaan dan Pemeriksaan kondisi awal LED Indikasi pada panel","Pemeriksaan status dan kondisi parameter IED Key Point (data setting & Proteksi)","Sistem komunikasi data","Pemeriksaan Power modem dan antena modem","Pemeriksaan Status dan kondisi Modem asesoris (data setting, kuat sinyal dan test ping)","Pengukuran Kuat sinyal Provider di lokasi dan 10 Gawang setelah dan sebelum","Melakukan Penggantian modem dan setting konfigurasi (sesuai intruksi Pengawas PLN)","Melakukan uji koneksi modem ke master station","Perapian wiring Modem dan asesoris","Sistem Power supply","Pemeriksaan Suply input Power 220 VAC dari PT/SR","Pengukuran sistem Power supply dan Pengujian kapasitas baterai","Melakukan Penggantian baterai (sesuai intruksi dari pengawas PLN)","Perapian wiring sistem supply","Pengujian Teleinformasi data","Pengujian Fungsi Telestatus, Telemetering koordinasi dengan Tim master Station","PENGUJIAN Telecontrol (PADAM)"],
"ASSESSMENT TIER 3/ Pemeliharaan korektif IED RTU": ["Melakukan Penggantian IED RTU dan setting konfigurasi (data setting RTU, setting protokol komunikasi)","Melakukan uji koneksi/integrasi ke master station","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"]
},
"TIM PEMELIHARAAN SCADA GI-GH PREVENTIF": {
"ASSESSMENT TIER 1 (TANPA PADAM) - GARDU INDUK": ["Pengamatan secara visual","Pembersihan lingkungan sekitar Panel RTU","Pembersihan bagian dalam Panel RTU","Pengamatan wiring Power Supply","Pengamatan Wiring, LED dan status RTU","Pengamatan Wiring, LED dan status Remote IO","Pengamatan Wiring Platin Per Kubikel","Pengamatan visual Rectifier"],
"ASSESSMENT TIER 2 (TANPA PADAM) - GARDU INDUK": ["Pengujian Koneksi komunikasi data dari RTU ke Master station","Pemeriksaan power supply, lampu LED RTU dan status RTU pada master station (koordinasi dengan master station)","Pemeriksaan Tegangan supply, wiring common dan status pada Remote IO","Pemeriksaan wiring Platin Per Kubikel ke Remote IO","Pemeriksaan wiring platin per jurusan ke kabel multicore kubikel","Pemeriksaan wiring komunikasi data RTU ke Relai Proteksi","Pengujian Telestatus (lokal,remote, status CB, DC Failed)","Pengujian Telemetering","Pengukuran Pengujian kapasitas batre","Pengukuran Suply input Power 220 VAC Rectifier","Pengukuran output 48 VDC dan baterai pada Rectifier"],
"ASSESSMENT TIER 1 (TANPA PADAM) - GARDU HUBUNG": ["Pengamatan secara visual","Pembersihan lingkungan sekitar Panel RTU","Pembersihan bagian dalam Panel RTU","Pengamatan wiring Power Supply","Pengamatan Wiring, LED dan status RTU","Pengamatan Wiring, LED dan status Remote IO","Pengamatan Wiring Platin Per Kubikel","Pengamatan visual Rectifier"],
"ASSESSMENT TIER 2 (TANPA PADAM) - GARDU HUBUNG": ["Pengujian Koneksi komunikasi data dari RTU ke Master station","Pemeriksaan power supply, lampu LED RTU dan status RTU pada master station (koordinasi dengan master station)","Pemeriksaan Tegangan supply, wiring common dan status pada Remote IO","Pemeriksaan wiring Platin Per Kubikel ke Remote IO","Pemeriksaan wiring platin per jurusan ke kabel multicore kubikel","Pemeriksaan wiring komunikasi data RTU ke Relai Proteksi","Pengujian Telestatus (lokal,remote, status CB, DC Failed)","Pengujian Telemetering","Pengukuran Pengujian kapasitas batre","Pengukuran Suply input Power 220 VAC Rectifier","Pengukuran output 48 VDC dan baterai pada Rectifier","PENGUJIAN Telecontrol (PADAM)"]
},
"TIM PEMELIHARAAN SCADA GI-GH KOREKTIF": {
"Pemeliharaan korektif RTU - GI": ["Penggantian RTU","Mapping database dan Integrasi ke uplink dan downlink","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"],
"Pemeliharaan korektif Remote io - GI": ["Penggantian Remote IO","Penarikan dan perbaikan kabel Power dan Komunikasi Remote IO","Mapping data base dan integrasi ke uplink/RTU","Mapping data base dan integrasi ke Downlink/relai proteksi","Pengujian TID Remote IO","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"],
"Pemeliharaan korektif wiring Platin per kubikel - GI": ["Penarikan Kabel multicore / kabel TID ke Kubikel 20 KV","wiring kabel TID/Multicore pada cell Kubikel","Perbaikan wiring Platin/Auxilary Relay","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"],
"Pemeliharaan korektif Sistem Power Suply - GI": ["Pemeriksaan dan penarikan Suply Power 220 VAC Rectifier","Penggantian Rectifier dan perapian wiring","Melakukan Penggantian batre dan Perapian wiring","Pengujian Fungsi Telestatus dan Telemetering"],
"Pemeliharaan korektif RTU - GH": ["Penggantian RTU","Mapping database dan Integrasi ke uplink dan downlink","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"],
"Pemeliharaan korektif Remote io - GH": ["Penggantian Remote IO","Pemeriksaan dan perbaikan kabel Power dan Komunikasi Remote IO","Mapping data base dan integrasi ke uplink/RTU","Mapping data base dan integrasi ke Downlink/relai proteksi","Pengujian TID Remote IO","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"],
"Pemeliharaan korektif wiring Platin per kubikel - GH": ["Penarikan Kabel multicore / kabel TID ke Kubikel 20 KV","Wiring kabel TID/Multicore pada cell Kubikel","Perbaikan wiring Platin/Auxilary Relay","Pengujian Fungsi Telestatus dan Telemetering serta Telecontrol (Padam)"],
"Pemeliharaan korektif Sistem Power Suply - GH": ["Pemeriksaan Suply input Power 220 VAC Rectifier","Pemeriksaan output 48 VDC dan baterai pada Rectifier","Melakukan Penggantian batre dan Perapian wiring","Pengujian Fungsi Telestatus dan Telemetering"]
},
"TELEKOM": {
"ASSESSMENT TIER 1 (TANPA PADAM) - REPEATER": ["Pengamatan secara visual Kondisi Repeater dan Arrester","Pengamatan secara visual kondisi antena","Pengamatan secara visual kondisi Kabel Heliax dan conector","Pembersihan lingkungan sekitar Box Repeater","Pemeriksaan kondisi status eksisting dan koordinasi dengan Tim Scadatel","Pembersihan bagian dalam Box repeater dan Fan Repeater"],
"ASSESSMENT TIER 2 (TANPA PADAM) - REPEATER": ["Pemeriksaan Tegangan Input supply ke repeater","Pemeriksaan Tegangan Input batre repeater","Pengujian kapasitas batre","Melakukan Pembongkaran Batre Jika diperlukan (koordinasi dengan Pengawas UP2D)","Melakukan Pemasangan Batre Jika diperlukan (koordinasi dengan Pengawas UP2D)","Pembongkaran UPS","Pemasangan UPS","Pengukuran SWR dan Power Transmit Repeater","Melakukan pemeriksaan kabel jumper dan penggantian jika diperlukan (koordinasi dengan Pengawas UP2D)","Melakukan pemeriksaan Arrester 220VAC dan Arrester Lan","Melakukan pembongkaran Arrester 220VAC, MCB dan Arrester Lan","Melakukan pemasangan Arrester 220VAC, MCB dan Arrester Lan","Melakukan pembongkaran Duplexer","Melakukan pemasangan Duplexer","Melakukan pembongkaran Repeater","Melakukan pemasangan Repeater","Melakukan pemeriksaan atau pemasangan grounding kit","Melakukan pemeriksaan Kabel LAN repeater","Pengujian Test Komunikasi ke UP2D & UP3"],
"PEMELIHARAAN KOREKTIF /Melakukan korektif repeater dan duplexer": ["Melakukan korektif repeater dan duplexer"],
"ASSESSMENT TIER 1 (TANPA PADAM) - TOWER": ["Pengamatan secara visual kondisi tower","Pengamatan secara visual kondisi klem kuku macan, kawat sling dan jarum keras","Pengamatan secara visual kondisi antena, lampu tower dan splitzen","Pembersihan lingkungan sekitar tower"],
"ASSESSMENT TIER 2 (TANPA PADAM) - TOWER": ["Pengukuran tahanan grounding tower","Pengencangan Sling","Pembersihan karat pada kuku macan sling","Perbaikan MCB lampo tower","Penambahan titik grounding"],
"ASSESSMENT TIER 1 (TANPA PADAM) - RADIO BASE": ["Pengamatan secara visual Kondisi Radio Base","Pengamatan secara visual kondisi antena","Pengamatan secara visual kondisi Kabel Heliax dan conector","Pembersihan lingkungan sekitar Radio base","Pemeriksaan kondisi status eksisting dan koordinasi dengan Tim Scadatel","Pemeriksaan Kondisi dan Fungsi IP Phone"],
"ASSESSMENT TIER 2 (TANPA PADAM) - RADIO BASE": ["Pemeriksaan Tegangan Input supply 220VAC ke Power Supply","Pemeriksaan Tegangan Output Power Supply","Pengujian kapasitas batre","Melakukan Pembongkaran Batre Jika diperlukan (koordinasi dengan Pengawas UP2D)","Melakukan Pemasangan Batre Jika diperlukan (koordinasi dengan Pengawas UP2D)","Pembongkaran Power Supply","Pemasangan Power Supply","Pengukuran SWR dan Power Transmit Repeater","Melakukan pemeriksaan dan perbaikan konektor serta adapter dan penggantian jika diperlukan (koordinasi dengan Pengawas UP2D)","Melakukan pembongkaran Radio base","Melakukan pemasangan Radio base","Pengujian Test Komunikasi ke UP2D & UP3","Pengujian Test Komunikasi melalui IP Phone ke UP2D & UP3"]
}
};
var dataRekapStruktur = {
"TIM PEMELIHARAAN GH DAN PMCB PREVENTIF (Inspeksi)": [
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM)"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM)"}
],
"TIM PEMELIHARAAN GH DAN PMCB KOREKTIF (HAR)": [
{type:'item', pk:"Pemeliharaan Peralatan Mekanik GH (Incoming dan Kopel)"},
{type:'item', pk:"Pemeliharaan Peralatan Mekanik GH (Outgoing)"},
{type:'item', pk:"Pemeliharaan PMCB"},
{type:'item', pk:"Pembongkaran Cubicle Incoming/ Couple"},
{type:'item', pk:"Pemasangan Cubicle Incoming/ Couple"},
{type:'item', pk:"Pembongkaran Cubicle Outgoing"},
{type:'item', pk:"Pemasangan Cubicle Outgoing"},
{type:'item', pk:"Pembongkaran PMCB"},
{type:'item', pk:"Pemasangan PMCB"},
{type:'item', pk:"Pemasangan CT/PT"},
{type:'item', pk:"Pengecekan dan Pemasangan Terminasi Kabel Tanah"},
{type:'item', pk:"Penggantian PMT"},
{type:'item', pk:"Relay Proteksi GH"},
{type:'item', pk:"Pembongkaran LBS/Recloser"},
{type:'item', pk:"Pemasangan LBS/Recloser"}
],
"TIM PEMELIHARAAN KEY PONT LINE (KPL)": [
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM)"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM)"},
{type:'item', pk:"ASSESSMENT TIER 3/ Pemeliharaan korektif IED RTU"}
],
"TIM PEMELIHARAAN SCADA GI-GH PREVENTIF": [
{type:'sub', label:"A. PEMELIHARAAN PREVENTIF - GARDU INDUK"},
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM) - GARDU INDUK"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM) - GARDU INDUK"},
{type:'sub', label:"B. PEMELIHARAAN PREVENTIF - GARDU HUBUNG"},
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM) - GARDU HUBUNG"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM) - GARDU HUBUNG"}
],
"TIM PEMELIHARAAN SCADA GI-GH KOREKTIF": [
{type:'sub', label:"A. PEMELIHARAAN KOREKTIF - GARDU INDUK"},
{type:'item', pk:"Pemeliharaan korektif RTU - GI"},
{type:'item', pk:"Pemeliharaan korektif Remote io - GI"},
{type:'item', pk:"Pemeliharaan korektif wiring Platin per kubikel - GI"},
{type:'item', pk:"Pemeliharaan korektif Sistem Power Suply - GI"},
{type:'sub', label:"B. PEMELIHARAAN KOREKTIF - GARDU HUBUNG"},
{type:'item', pk:"Pemeliharaan korektif RTU - GH"},
{type:'item', pk:"Pemeliharaan korektif Remote io - GH"},
{type:'item', pk:"Pemeliharaan korektif wiring Platin per kubikel - GH"},
{type:'item', pk:"Pemeliharaan korektif Sistem Power Suply - GH"}
],
"TELEKOM": [
{type:'sub', label:"A. PEMELIHARAAN REPEATER"},
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM) - REPEATER"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM) - REPEATER"},
{type:'item', pk:"PEMELIHARAAN KOREKTIF /Melakukan korektif repeater dan duplexer"},
{type:'sub', label:"B. PEMELIHARAAN TOWER"},
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM) - TOWER"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM) - TOWER"},
{type:'sub', label:"C. PEMELIHARAAN RADIO BASE"},
{type:'item', pk:"ASSESSMENT TIER 1 (TANPA PADAM) - RADIO BASE"},
{type:'item', pk:"ASSESSMENT TIER 2 (TANPA PADAM) - RADIO BASE"}
]
};
var pkPerTim = {};
Object.keys(dataRekapStruktur).forEach(function(tim) {
pkPerTim[tim] = [];
dataRekapStruktur[tim].forEach(function(entry) {
if (entry.type === 'item' && entry.pk) pkPerTim[tim].push(entry.pk);
});
});
var dataZona = {
"ZONA 1": { "UP3 PALEMBANG": ["ULP AMPERA","ULP KENTEN","ULP MARIANA","ULP PANGKALAN BALAI","ULP RIVAI","ULP SEKAYU","ULP SUKARAME","ULP SUNGAI LILIN"], "UP3 OGAN ILIR": ["ULP TUGU MULYO","ULP PRABUMULIH","ULP KAYU AGUNG","ULP INDRALAYA"] },
"ZONA 2": { "UP3 LAHAT": ["ULP PAGAR ALAM","ULP MUARA ENIM","ULP MUARA DUA","ULP MARTAPURA","ULP LEMBAYUNG","ULP BATURAJA"], "UP3 LUBUK LINGGAU": ["ULP TEBING TINGGI","ULP PENDOPO","ULP MUARATARA","ULP MUARA BELITI","ULP LUBUK LINGGAU"], "UP3 BENGKULU": ["ULP TELUK SEGARA","ULP TAIS","ULP NUSA INDAH","ULP MUKOMUKO","ULP MUARA AMAN","ULP MANNA","ULP KEPAHIANG","ULP CURUP","ULP BINTUHAN","ULP ARGAMAKMUR"] },
"ZONA 3": { "UP3 JAMBI": ["ULP TELANAI PURA","ULP SEBERANG KOTA","ULP MUARA SABAK","ULP MUARA BULIAN","ULP KUALA TUNGKAL","ULP KOTA BARU"], "UP3 MUARO BUNGO": ["ULP MUARA TEBO","ULP SEI PENUH","ULP SAROLANGUN","ULP RIMBO BUJANG","ULP KOTA BUNGO","ULP KERSIK TUO","ULP BANGKO"] }
};
var dataULP = {
"UP3 PALEMBANG": ["ULP AMPERA","ULP KENTEN","ULP MARIANA","ULP PANGKALAN BALAI","ULP RIVAI","ULP SEKAYU","ULP SUKARAME","ULP SUNGAI LILIN"],
"UP3 LAHAT": ["ULP PAGAR ALAM","ULP MUARA ENIM","ULP MUARA DUA","ULP MARTAPURA","ULP LEMBAYUNG","ULP BATURAJA"],
"UP3 OGAN ILIR": ["ULP TUGU MULYO","ULP PRABUMULIH","ULP KAYU AGUNG","ULP INDRALAYA"],
"UP3 LUBUK LINGGAU": ["ULP TEBING TINGGI","ULP PENDOPO","ULP MUARATARA","ULP MUARA BELITI","ULP LUBUK LINGGAU"],
"UP3 BENGKULU": ["ULP TELUK SEGARA","ULP TAIS","ULP NUSA INDAH","ULP MUKOMUKO","ULP MUARA AMAN","ULP MANNA","ULP KEPAHIANG","ULP CURUP","ULP BINTUHAN","ULP ARGAMAKMUR"],
"UP3 JAMBI": ["ULP TELANAI PURA","ULP SEBERANG KOTA","ULP MUARA SABAK","ULP MUARA BULIAN","ULP KUALA TUNGKAL","ULP KOTA BARU"],
"UP3 MUARO BUNGO": ["ULP MUARA TEBO","ULP SEI PENUH","ULP SAROLANGUN","ULP RIMBO BUJANG","ULP KOTA BUNGO","ULP KERSIK TUO","ULP BANGKO"]
};
var namaBulan = {"01":"Januari","02":"Februari","03":"Maret","04":"April","05":"Mei","06":"Juni","07":"Juli","08":"Agustus","09":"September","10":"Oktober","11":"November","12":"Desember"};
var up3ToZona = {};
Object.keys(dataZona).forEach(function(z){Object.keys(dataZona[z]).forEach(function(u){up3ToZona[u]=z;});});
var zonaNames = ["ZONA 1","ZONA 2","ZONA 3"];
var laporanData = [];
var currentSession = null;
var firebaseUnsubscribe = null;
var searchDebounceTimer = null;
function togglePw(){var i=document.getElementById('loginPassword'),c=document.getElementById('pwEyeIcon');if(i.type==='password'){i.type='text';c.className='fa fa-eye-slash';}else{i.type='password';c.className='fa fa-eye';}}
function handleLogin(e){
e.preventDefault();var u=document.getElementById('loginUsername').value.trim().toLowerCase(),p=document.getElementById('loginPassword').value,eb=document.getElementById('loginError'),em=document.getElementById('loginErrorMsg');
if(!USERS[u]){eb.style.display='flex';em.textContent='Username tidak ditemukan.';return;}
if(USERS[u].password!==p){eb.style.display='flex';em.textContent='Password salah.';return;}
eb.style.display='none';
currentSession={username:u,role:USERS[u].role,nama:USERS[u].nama,label:USERS[u].label};
try { localStorage.setItem('yantek_session',JSON.stringify(currentSession)); } catch(e) {}
enterApp();
}
function handleLogout(){
try { localStorage.removeItem('yantek_session'); } catch(e) {}
currentSession=null;document.getElementById('mainNavbar').style.display='none';document.body.classList.add('is-login');
document.getElementById('loginForm').reset();$('.view-section').removeClass('active');$('#view-login').addClass('active');
showToast('Berhasil keluar.','success');
}
function getSession(){if(currentSession)return currentSession;try{var s=localStorage.getItem('yantek_session');if(s){currentSession=JSON.parse(s);return currentSession;}}catch(e){}return null;}
function getPerm(k){var s=getSession();if(!s)return false;return PERMS[s.role]?PERMS[s.role][k]:false;}
function getDefaultView(){var s=getSession();if(!s)return 'login';return ROLE_REDIRECT[s.role]||'list';}
function enterApp(){
var s=getSession();if(!s){handleLogout();return;}
document.body.classList.remove('is-login');document.getElementById('mainNavbar').style.display='';
document.getElementById('navUserName').textContent=s.nama;
document.getElementById('nav-dashboard').style.display=getPerm('dashboard')?'':'none';
document.getElementById('btnTambahList').style.display=getPerm('tambah')?'':'none';
showView(getDefaultView());
fetchDataFromDB();
try {
var cached = localStorage.getItem('yantek_data_cache');
if (cached) {
laporanData = JSON.parse(cached);
for(var i=0;i10)laporanData[i].Tanggal=String(t).substring(0,10);
}
applyListFilters();renderRekapDashboard();populateListFilterTim();
}
} catch(e) {}
showToast('Selamat datang, '+s.nama,'success');
}
function checkAuth(){var s=getSession();if(s){enterApp();}else{handleLogout();}}
function isBase64(d){return d&&typeof d==='string'&&d.indexOf('data:')===0;}
function isFileId(d){if(!d||typeof d!=='string')return false;if(d.indexOf('data:')===0)return false;return d.length>=10&&d.length<200;}
function base64ToBlobUrl(b64){try{var p=b64.split(','),m=p[0].match(/:(.*?);/)[1],r=atob(p[1]),a=new Uint8Array(r.length);for(var i=0;i3000000){showToast('PDF maksimal 3MB.','danger');input.value='';return;}
document.getElementById(nId).textContent=f.name;
if(fnId) document.getElementById(fnId).value=f.name;
input.closest('.upload-wrapper').querySelector('.custom-upload-box').classList.add('has-file');
var r=new FileReader();r.onload=function(e){document.getElementById(bId).value=e.target.result;};r.readAsDataURL(f);
}
else{
document.getElementById(nId).textContent='';
document.getElementById(bId).value='';
if(fnId) document.getElementById(fnId).value='';
input.closest('.upload-wrapper').querySelector('.custom-upload-box').classList.remove('has-file');
}
}
function compressImg(f,mw,q,cb){var r=new FileReader();r.readAsDataURL(f);r.onload=function(e){var img=new Image();img.src=e.target.result;img.onload=function(){var c=document.createElement('canvas'),w=img.width,h=img.height;if(w>mw){h*=mw/w;w=mw;}c.width=w;c.height=h;c.getContext('2d').drawImage(img,0,0,w,h);cb(c.toDataURL('image/jpeg',q));};};}
function showLoading(v,t){document.getElementById('loading-overlay').style.display=v?'flex':'none';if(t)document.querySelector('.loading-text').textContent=t;else document.querySelector('.loading-text').textContent='Memuat Data...';}
function showToast(m,t){var bg=t==='success'?'toast-success':'toast-danger',ic=t==='success'?'fa-check-circle':'fa-exclamation-triangle';var el=$('
'+m+'
');$('#toast-container').append(el);el.toast({delay:3500}).toast('show');setTimeout(function(){el.remove();},4000);}
// Mengganti listenToFirebase menjadi Fetch ke api.php
async function fetchDataFromDB() {
try {
let res = await fetch(API_URL + '?action=getLaporan');
if(!res.ok) throw new Error('Network response was not ok');
let data = await res.json();
if(data.status === 'success') {
laporanData = data.data;
for(var i=0; i 10) {
laporanData[i].Tanggal = String(t).substring(0, 10);
}
}
try { localStorage.setItem('yantek_data_cache', JSON.stringify(laporanData)); } catch(e) {}
applyListFilters();
renderRekapDashboard();
populateListFilterTim();
} else {
showToast('Gagal memuat data dari server.', 'danger');
}
} catch(err) {
console.error("Error fetching data: ", err);
showToast('Gagal memuat data. Menampilkan data cache.', 'danger');
try {
var cached = localStorage.getItem('yantek_data_cache');
if (cached) {
laporanData = JSON.parse(cached);
applyListFilters(); renderRekapDashboard(); populateListFilterTim();
}
} catch(e2) {}
}
}
async function safeFetch(url, options, retries = 5) {
let lastError = null;
for (let i = 0; i < retries; i++) {
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 90000);
let res = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
let text = await res.text();
if (text.trim().startsWith('<') || text.trim().startsWith(' setTimeout(r, delay));
} else {
throw new Error(errMsg + ' Silakan periksa koneksi internet dan coba lagi.');
}
}
}
throw lastError || new Error('Gagal terhubung ke server setelah beberapa percobaan.');
}
async function uploadFileToDrive(base64, fileName){
var text = await safeFetch(SCRIPT_URL, {
method: 'POST',
headers: { 'Content-Type': 'text/plain;charset=utf-8' },
body: JSON.stringify({action:'uploadFile', base64:base64, fileName:fileName})
}, 5);
var data;
try {
data = JSON.parse(text);
} catch(e) {
throw new Error('Respon server tidak valid (bukan JSON).');
}
if(data.status === 'success') return data.fileId;
throw new Error(data.message || 'Gagal upload file');
}
function showView(n,id){
document.body.classList.remove('print-list-mode');
if(n==='dashboard'&&!getPerm('dashboard')){n=getDefaultView();}
if(n==='add'&&!getPerm('tambah')){n='list';}
if(n==='edit'&&!getPerm('edit')){showToast('Akses ditolak.','danger');return;}
$('.view-section').removeClass('active');$('#view-'+n).addClass('active');
$('.navbar-nav .nav-item').removeClass('active');
if(n==='dashboard'){$('#nav-dashboard').addClass('active');renderRekapDashboard();}
else if(n==='list'||n==='add'||n==='edit'||n==='detail'){$('#nav-list').addClass('active');}
if(n==='list')applyListFilters();
else if(n==='add')resetAddForm();
else if(n==='edit'&&id!==undefined)populateEdit(id);
else if(n==='detail'&&id!==undefined)populateDetail(id);
$('.navbar-collapse').collapse('hide');window.scrollTo({top:0,behavior:'smooth'});
}
function populateListFilterTim() {
var sel = $('#listFilterTim');
sel.empty().append('');
Object.keys(dataPekerjaan).forEach(function(t) {
sel.append($('');
if (tim && pkPerTim[tim]) {
pkPerTim[tim].forEach(function(p) {
sel.append($('