Aplikasi ini berjalan independen di atas postingan Blogger. Seluruh data disimpan dan divalidasi dengan aman melalui backend Google Apps Script. Pastikan untuk membagikan kode lisensi secara personal kepada klien Anda.
Klien harus memasang kode verifikasi (terdapat di tab "Script Klien") ke dalam aplikasi sekolah mereka agar validasi upload siswa bisa bekerja.
Buat Lisensi Baru
Kode Lisensi Berhasil Dibuat!
EDU-XXXXXX
Daftar Lisensi Terdaftar
Tanggal
Klien
Kode Lisensi
Batas Siswa
Status
Aksi
Memuat data...
Script Integrasi Klien
Langkah 1: Pasang Script Inti
Salin kode HTML/JavaScript di bawah ini dan tinggal Anda copy paste script sebelum kode </head> pada Tema (Edit HTML) atau di dalam Postingan Aplikasi Sekolah milik klien Anda.
<!-- SCRIPT VALIDASI LISENSI APLIKASI SEKOLAH -->
<script>
const GAS_VERIFY_URL = "https://script.google.com/macros/s/AKfycbyv2B9_fKFGYLrfOX3RlHqdHjW4BhzbIg6E1aP-RDrH3faMp1eQO4kqiqOTVQ2gwpT8/exec";
let MAX_STUDENTS_ALLOWED = 0;
// Fungsi untuk memverifikasi ke backend GAS
async function verifikasiLisensi(kodeLisensi) {
try {
console.log("Memverifikasi lisensi...");
let response = await fetch(GAS_VERIFY_URL + "?action=verify&code=" + kodeLisensi);
let data = await response.json();
if(data.success && data.status === 'Aktif') {
MAX_STUDENTS_ALLOWED = parseInt(data.maxStudents);
return true;
} else {
showLicenseWarning("Lisensi tidak valid atau sudah dinonaktifkan oleh Admin.");
return false;
}
} catch (error) {
showLicenseWarning("Gagal terhubung ke server lisensi. Pastikan koneksi internet stabil.");
return false;
}
}
// Panggil fungsi ini SAAT KLIEN KLIK TOMBOL UPLOAD SISWA
// Contoh penggunaan: if(!cekLimitUploadSiswa(jumlahDataExcel)) return;
function cekLimitUploadSiswa(jumlahSiswaYangDiperiksa) {
if(MAX_STUDENTS_ALLOWED === 0) {
showLicenseWarning("Sistem terkunci. Silakan verifikasi kode lisensi Anda terlebih dahulu untuk menggunakan fitur upload!");
return false; // BLOKIR UPLOAD
}
if(jumlahSiswaYangDiperiksa > MAX_STUDENTS_ALLOWED) {
let msg = "Versi Trial Maksimal 20 Siswa/Santri, Untuk Upload Lebih dari 20 data silahkan Upgrade ke Premium.";
if(MAX_STUDENTS_ALLOWED > 20 && MAX_STUDENTS_ALLOWED !== 999999) {
msg = "Batas Lisensi Anda adalah " + MAX_STUDENTS_ALLOWED + " Siswa/Santri. Upload " + jumlahSiswaYangDiperiksa + " data ditolak. Silahkan Upgrade untuk menambah kuota.";
}
showLicenseWarning(msg);
return false; // BLOKIR UPLOAD
}
return true; // IZINKAN UPLOAD
}
// Sistem Peringatan Kustom Tanpa Alert Bawaan Browser
function showLicenseWarning(pesan) {
// Hapus modal lama jika ada
let oldModal = document.getElementById('license-warning-modal');
if(oldModal) oldModal.remove();
let modalHTML = `
<div id="license-warning-modal" style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);z-index:99999999;display:flex;align-items:center;justify-content:center;font-family:sans-serif;backdrop-filter:blur(3px);">
<div style="background:#fff;padding:30px;border-radius:12px;max-width:400px;width:90%;text-align:center;box-shadow:0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04);animation: fadeIn 0.3s;">
<div style="color:#ef4444;font-size:48px;margin-bottom:15px;">⚠️</div>
<h3 style="margin:0 0 10px 0;color:#1f2937;font-size:20px;font-weight:bold;">Peringatan Lisensi</h3>
<p style="color:#4b5563;margin-bottom:25px;line-height:1.6;font-size:15px;">${pesan}</p>
<button onclick="document.getElementById('license-warning-modal').remove()" style="background:#ef4444;color:white;border:none;padding:12px 20px;border-radius:6px;cursor:pointer;font-weight:bold;width:100%;font-size:15px;transition:background 0.2s;" onmouseover="this.style.background='#dc2626'" onmouseout="this.style.background='#ef4444'">Saya Mengerti</button>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', modalHTML);
}
</script>
Langkah 2: Panggil Pencegat di Firebase Anda (Penting!)
Ganti fungsi handleImportCSV lama Anda dengan kode di bawah ini. Kode ini sudah disisipkan pengecekan lisensi otomatis.
// Fitur Bulk Import CSV
window.handleImportCSV = function(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = async function(e) {
const text = e.target.result;
const rows = text.split('\n');
// --- 1. PROTEKSI LISENSI DIMULAI DARI SINI ---
// Hitung total baris dikurangi 1 (asumsi baris 0 adalah Header)
let totalDataUpload = rows.length - 1;
// Cek limit. Jika melanggar, fungsi mengembalikan false dan upload dibatalkan.
if (!cekLimitUploadSiswa(totalDataUpload)) {
event.target.value = ''; // Reset input file agar bisa memilih file lagi
return; // Hentikan eksekusi kode di bawahnya
}
// --- PROTEKSI SELESAI ---
let successCount = 0;
let errorCount = 0;
showToast("Memulai proses import data...", "info");
// Mulai dari i=1 jika baris pertama adalah Header
for (let i = 1; i < rows.length; i++) {
const row = rows[i].trim();
if (!row) continue;
// Memisahkan dengan koma atau titik koma (tergantung format Excel)
const cols = row.split(/,|;/);
// Pastikan minimal ada NIS dan Nama
if (cols.length >= 2) {
const nis = cols[0].trim();
const nama = cols[1].trim();
const kamar = cols[2] ? cols[2].trim() : '-';
const emailWali = cols[3] ? cols[3].trim() : '';
let noWa = cols[4] ? cols[4].trim() : '';
// Format WA (ganti 08 menjadi 628)
if(noWa.startsWith('0')) noWa = '62' + noWa.substring(1);
if (nis && nama) {
try {
const sId = "S" + nis;
await setDoc(doc(db, "santri", sId), {
nis: nis,
nama: nama,
kamar: kamar,
emailWali: emailWali,
noWa: noWa,
status: "Aktif"
});
successCount++;
} catch (err) {
console.error("Gagal import baris " + i + ":", err);
errorCount++;
}
}
}
}
showToast(`Import selesai. Berhasil: ${successCount}, Gagal: ${errorCount}`);
loadAllData(); // Refresh tabel
event.target.value = ''; // Reset input file
};
reader.readAsText(file);
};
Komentar
Posting Komentar