SmartPark Pro

Basis Data Administrasi

Akses: WARGA

Form Pendaftaran Warga

Semua kolom wajib diisi untuk verifikasi fasilitas parkir lingkungan.

Informasi Pembayaran Iuran:
  • Warga RW 06: Rp 25.000 | Non-RW 06: Rp 30.000 | Parkir Insidental/dirumah: Rp 10.000
  • Transfer Bank BCA: 7770841415 a.n Ari Friansyah
  • E-Wallet DANA / QRIS: 085315325335 a.n Ari Friansyah
// Penampung State Data Lokal Aplikasi /* PLACEHOLDER: JS UPDATE DATA */ // Penampung State Data Lokal Aplikasi let currentRole = "warga"; // default user login role let dataPendaftarGlobal = []; // KOSONGKAN (HAPUS BUDI & AHMAD DI SINI) // Inisialisasi awal saat halaman termuat window.addEventListener('DOMContentLoaded', () => { simulasiRoleAkses(); loadDataAdmin(); // Panggil fungsi penarikan data dari Google Sheets }); // Fungsi simulasi pembagian hak akses tampilan UI function simulasiRoleAkses() { const areaAdmin = document.getElementById('area-admin-panel'); const areaWarga = document.getElementById('area-pendaftaran-warga'); const labelRole = document.getElementById('label-role'); if (currentRole === "admin") { areaAdmin.classList.remove('hidden'); areaWarga.classList.add('hidden'); labelRole.textContent = "Akses: ADMIN"; renderDataAdmin(dataPendaftarGlobal); } else { areaAdmin.classList.add('hidden'); areaWarga.classList.remove('hidden'); labelRole.textContent = "Akses: WARGA"; } } // Fungsi Render List Data khusus untuk Admin via Template Literals function renderDataAdmin(dataArray) { const kontainer = document.getElementById('list-data-pendaftar'); if (dataArray.length === 0) { kontainer.innerHTML = `
Tidak ada data pendaftaran ditemukan.
`; return; } kontainer.innerHTML = dataArray.map(item => `
${item.id} ${item.status}

${item.nama}

NIK: ${item.nik} | RT: ${item.rt}

${item.paket}

`).join(''); } // Fungsi Pencarian Data function handleSearch(query) { const filtered = dataPendaftarGlobal.filter(item => item.nama.toLowerCase().includes(query.toLowerCase()) || item.nik.includes(query) || item.id.toLowerCase().includes(query.toLowerCase()) ); renderDataAdmin(filtered); } // Helper konversi file unggahan gambar menjadi string base64 murni function fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result.split(',')[1]); reader.onerror = error => reject(error); }); } // Fungsi Utama Penanganan Form Submit Kirim Pendaftaran Warga async function handlePendaftaran(event) { event.preventDefault(); const fileKtpInput = document.getElementById('reg-file-ktp').files[0]; const fileMotorInput = document.getElementById('reg-file-motor').files[0]; if (!fileKtpInput || !fileMotorInput) { alert("❌ Harap lengkapi unggahan foto KTP dan foto Motor terlebih dahulu!"); return; } const nama = document.getElementById('reg-nama').value; const wa = document.getElementById('reg-wa').value; const nik = document.getElementById('reg-nik').value; const rt = document.getElementById('reg-rt').value; const rw = document.getElementById('reg-rw').value; const alamat = document.getElementById('reg-alamat').value; const paket = document.getElementById('reg-paket').value; try { const base64Ktp = await fileToBase64(fileKtpInput); const base64Motor = await fileToBase64(fileMotorInput); const payload = { action: "daftarWarga", nama: document.getElementById('reg-nama').value, namaPanggilan: document.getElementById('reg-panggilan').value, // <--- BARU statusPekerjaan: document.getElementById('reg-status').value, // <--- BARU wa: document.getElementById('reg-wa').value, nik: document.getElementById('reg-nik').value, rt: document.getElementById('reg-rt').value, rw: document.getElementById('reg-rw').value, alamat: document.getElementById('reg-alamat').value, paket: document.getElementById('reg-paket').value, fotoKtp: base64Ktp, namaKtpFile: fileKtpInput.name, fotoMotor: base64Motor, namaMotorFile: fileMotorInput.name }; // Kondisi jika aplikasi berjalan di dalam PREVIEW_MODE internal if (PREVIEW_MODE) { alert(`🎉 [Preview Mode Sukses]\nData ${nama} berhasil diproses secara lokal!\nBerkas gambar berhasil dienkripsi ke Base64.`); // Optimistic UI update data lokal dummy dataPendaftarGlobal.push({ id: "REG-" + new Date().getTime().toString().slice(-4), nama: nama, nik: nik, rt: rt, paket: paket, status: "Menunggu Verifikasi" }); document.getElementById('form-daftar-warga').reset(); return; } // Eksekusi pengiriman data asinkron asli ke database Cloud Google Spreadsheet const response = await fetch(APP_URL, { method: "POST", body: JSON.stringify(payload) }); const result = await response.json(); if (result.status === "success") { alert("✅ Pendaftaran berhasil dikirim! Silakan tunggu verifikasi oleh pihak kepengurusan RW."); document.getElementById('form-daftar-warga').reset(); } else { alert("❌ Gagal mengirim berkas: " + result.message); } } catch (error) { console.error(error); alert("❌ Terjadi kegagalan komunikasi sistem atau ukuran berkas foto terlalu besar."); } } // Fungsi Refresh / Sinkronisasi Data function refreshData() { alert("🔄 Data ter-sinkronisasi dengan versi terbaru!"); if (currentRole === "admin") renderDataAdmin(dataPendaftarGlobal); } // Fungsi Keluar / Logout akun function handleLogout() { if (confirm("Apakah kamu yakin ingin keluar dari aplikasi?")) { // 1. Hapus session/token login pengguna jika disimpan di localStorage atau sessionStorage localStorage.removeItem("user_session"); sessionStorage.clear(); // 2. Jika kamu memiliki modal/layar login di index.html, tampilkan layar login tersebut: const areaLogin = document.getElementById('area-login'); if (areaLogin) { areaLogin.classList.remove('hidden'); } else { // 3. Jika menggunakan halaman terpisah atau refresh untuk reset state aplikasi: window.location.reload(); } } } /* PLACEHOLDER: JS BARU */ /* PLACEHOLDER: JS BARU */ // Update Variabel Role & Session Handling Login let currentRole = localStorage.getItem("user_role") || null; // Inisialisasi awal saat halaman di-load window.addEventListener('DOMContentLoaded', () => { if (currentRole) { document.getElementById('modal-login').classList.add('hidden'); simulasiRoleAkses(); } else { document.getElementById('modal-login').classList.remove('hidden'); } }); // Fungsi Masuk Sesuai Role function masukSebagai(role) { currentRole = role; localStorage.setItem("user_role", role); document.getElementById('modal-login').classList.add('hidden'); simulasiRoleAkses(); } // Perbaikan Fungsi Keluar (Logout) function handleLogout() { if (confirm("Apakah kamu yakin ingin keluar dari aplikasi?")) { localStorage.removeItem("user_role"); currentRole = null; document.getElementById('modal-login').classList.remove('hidden'); } } // Update Handler Pendaftaran Warga (Termasuk Validasi Foto Depan & Samping Motor) async function handlePendaftaran(event) { event.preventDefault(); const fileKtpInput = document.getElementById('reg-file-ktp').files[0]; const fileMotorDepanInput = document.getElementById('reg-file-motor-depan').files[0]; const fileMotorSampingInput = document.getElementById('reg-file-motor-samping').files[0]; // Validasi Wajib Isi Semua Berkas if (!fileKtpInput || !fileMotorDepanInput || !fileMotorSampingInput) { alert("❌ Harap lengkapi SEMUA berkas unggahan: Foto KTP, Foto Motor Tampak Depan, dan Foto Motor Tampak Samping!"); return; } try { const base64Ktp = await fileToBase64(fileKtpInput); const base64MotorDepan = await fileToBase64(fileMotorDepanInput); const base64MotorSamping = await fileToBase64(fileMotorSampingInput); const payload = { action: "daftarWarga", nama: document.getElementById('reg-nama').value, namaPanggilan: document.getElementById('reg-panggilan').value, statusPekerjaan: document.getElementById('reg-status').value, wa: document.getElementById('reg-wa').value, nik: document.getElementById('reg-nik').value, rt: document.getElementById('reg-rt').value, rw: document.getElementById('reg-rw').value, alamat: document.getElementById('reg-alamat').value, paket: document.getElementById('reg-paket').value, fotoKtp: base64Ktp, namaKtpFile: fileKtpInput.name, fotoMotorDepan: base64MotorDepan, namaMotorDepanFile: fileMotorDepanInput.name, fotoMotorSamping: base64MotorSamping, namaMotorSampingFile: fileMotorSampingInput.name }; if (PREVIEW_MODE) { alert("🎉 [Preview Mode Sukses]\nPendaftaran berhasil diproses! Ketiga foto berkas (KTP, Motor Depan, & Motor Samping) terverifikasi."); document.getElementById('form-daftar-warga').reset(); return; } const response = await fetch(APP_URL, { method: "POST", body: JSON.stringify(payload) }); const result = await response.json(); if (result.status === "success") { alert("✅ Pendaftaran berhasil dikirim! Berkas foto KTP dan Motor lengkap."); document.getElementById('form-daftar-warga').reset(); } else { alert("❌ Gagal mengirim berkas: " + result.message); } } catch (error) { console.error(error); alert("❌ Terjadi kesalahan saat memproses gambar."); } } /* PLACEHOLDER: JS BARU */ // Variabel Penampung State Akses Login let currentRole = localStorage.getItem("user_role") || null; // Cek status sesi saat halaman selesai di-load window.addEventListener('DOMContentLoaded', () => { const loginScreen = document.getElementById('login-screen'); const mainApp = document.getElementById('main-app'); if (currentRole) { if (loginScreen) loginScreen.classList.add('hidden'); if (mainApp) mainApp.classList.remove('hidden'); simulasiRoleAkses(); } else { if (loginScreen) loginScreen.classList.remove('hidden'); if (mainApp) mainApp.classList.add('hidden'); } }); // Fungsi Masuk Sebagai WARGA function loginWarga() { const wa = document.getElementById('input-wa').value; if (!wa) return alert("❌ Harap masukkan nomor WhatsApp terlebih dahulu!"); currentRole = "warga"; localStorage.setItem("user_role", "warga"); localStorage.setItem("user_wa", wa); // Buka tampilan utama document.getElementById('login-screen').classList.add('hidden'); document.getElementById('main-app').classList.remove('hidden'); simulasiRoleAkses(); } // Fungsi Masuk Sebagai ADMIN function showAdminLogin() { const pass = prompt("Masukkan Password Admin:"); if (pass === "123" || pass === "admin") { // Password default admin currentRole = "admin"; localStorage.setItem("user_role", "admin"); document.getElementById('login-screen').classList.add('hidden'); document.getElementById('main-app').classList.remove('hidden'); simulasiRoleAkses(); } else if (pass !== null) { alert("❌ Password Admin Salah!"); } } // Fungsi Pengatur Tampilan Sesuai Peran (Admin vs Warga) function simulasiRoleAkses() { const areaAdmin = document.getElementById('area-admin-panel'); const areaWarga = document.getElementById('area-pendaftaran-warga'); const labelRole = document.getElementById('label-role'); if (currentRole === "admin") { if (areaAdmin) areaAdmin.classList.remove('hidden'); if (areaWarga) areaWarga.classList.add('hidden'); if (labelRole) labelRole.textContent = "Akses: ADMIN"; if (typeof renderDataAdmin === 'function') renderDataAdmin(dataPendaftarGlobal); } else { if (areaAdmin) areaAdmin.classList.add('hidden'); if (areaWarga) areaWarga.classList.remove('hidden'); if (labelRole) labelRole.textContent = "Akses: WARGA"; } } // Perbaikan Fungsi Keluar (Logout) function handleLogout() { if (confirm("Apakah kamu yakin ingin keluar dari aplikasi?")) { localStorage.clear(); currentRole = null; // Sembunyikan main app, tampilkan layar login document.getElementById('main-app').classList.add('hidden'); document.getElementById('login-screen').classList.remove('hidden'); // Reset form nomor WA const inputWa = document.getElementById('input-wa'); if (inputWa) inputWa.value = ""; } }

Selamat Datang

Silakan pilih akses untuk melanjutkan

Atau
/* PLACEHOLDER: JS BARU */ // 1. Inisialisasi variabel global data if (typeof dataPendaftarGlobal === 'undefined') { var dataPendaftarGlobal = []; } // 2. Fungsi Ambil Data Real-time dari Google Sheets ke Admin Panel /* PLACEHOLDER: JS BARU */ /* PLACEHOLDER: JS BARU */ /* PLACEHOLDER: JS BARU */ async function loadDataAdmin() { // Cari kontainer list admin di DOM const container = document.getElementById('adminDataList') || document.querySelector('.space-y-4'); if (!container) return; // 1. Tampilkan Indikator Loading container.innerHTML = `

Menghubungkan ke Google Sheets...

`; // 2. Jika PREVIEW_MODE false & APP_URL terisi, langsung ambil data asli if (!PREVIEW_MODE && APP_URL && APP_URL !== "") { try { const response = await fetch(APP_URL); const result = await response.json(); if (result.status === "success" && Array.isArray(result.data)) { // Jika database di Google Sheets kosong if (result.data.length === 0) { container.innerHTML = `

Belum Ada Data Pendaftaran

Data warga yang mendaftar akan otomatis muncul di sini.

`; return; } // Render Data Asli (Ari Friansyah & pendaftar lainnya) container.innerHTML = result.data.map(item => `
${item.id || 'REG-NEW'} ${item.status || 'Menunggu Verifikasi'}

${item.nama} ${item.panggilan ? '(' + item.panggilan + ')' : ''}

NIK: ${item.nik || '-'} | RT: ${item.rt || '-'} | WA: ${item.wa || '-'}

🚗 ${item.paket || '-'}
${item.urlKtp ? `Lihat Berkas` : ''}
`).join(''); } else { throw new Error(result.message || "Gagal mengambil data"); } } catch (err) { console.error(err); container.innerHTML = `

Gagal Mengambil Data Database

${err.message}

`; } } else { container.innerHTML = `
⚠️ PREVIEW_MODE masih TRUE atau APP_URL belum diisi dengan URL Apps Script.
`; } } // Handler Tombol Sinkron Data async function syncDataAdmin(event) { const btn = event?.currentTarget || document.getElementById('btnSync'); if (btn) btn.classList.add('opacity-50', 'pointer-events-none'); await loadDataAdmin(); if (btn) btn.classList.remove('opacity-50', 'pointer-events-none'); } // 3. Override/Perbarui Fungsi Cek Akses Sesi function cekSesiAkses() { const loginScreen = document.getElementById('login-screen'); const mainApp = document.getElementById('main-app'); const areaAdmin = document.getElementById('area-admin-panel'); const areaWarga = document.getElementById('area-pendaftaran-warga'); const labelRole = document.getElementById('label-role'); if (currentRole) { if (loginScreen) loginScreen.style.display = 'none'; if (mainApp) mainApp.classList.remove('hidden'); if (currentRole === "admin") { if (areaAdmin) areaAdmin.classList.remove('hidden'); if (areaWarga) areaWarga.classList.add('hidden'); if (labelRole) labelRole.textContent = "Akses: ADMIN"; // Jalankan pengambilan data Google Sheets jika bukan mode preview if (typeof PREVIEW_MODE !== 'undefined' && !PREVIEW_MODE) { loadDataAdmin(); } else if (typeof renderDataAdmin === 'function') { renderDataAdmin(dataPendaftarGlobal); } } else { if (areaAdmin) areaAdmin.classList.add('hidden'); if (areaWarga) areaWarga.classList.remove('hidden'); if (labelRole) labelRole.textContent = "Akses: WARGA"; } } else { if (loginScreen) loginScreen.style.display = 'flex'; if (mainApp) mainApp.classList.add('hidden'); } } // 4. Pastikan fungsi dipanggil otomatis saat halaman selesai dimuat document.addEventListener('DOMContentLoaded', () => { try { currentRole = localStorage.getItem("user_role") || null; } catch(e) {} cekSesiAkses(); });