Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * SERTIFIKAT SEMINAR ONLINE (FINAL - TEMA BIRU KUNING)
- * Google Form -> Google Sheet -> Apps Script Web App
- * Kolom Sheet: A=Timestamp, B=Nama, C=Email, D=Instansi, ... F=Status
- */
- // ===== KONFIGURASI =====
- var CONFIG = {
- judul: 'Peran Sistem Informasi dalam Pengambilan Keputusan',
- judulSorot: 'Berbasis Big Data',
- tanggal: 'Sabtu, 15 November 2026',
- tempat: 'Zoom / Aula Fakultas',
- penyelenggara: 'Kelompok 3 Big Data',
- penandatangan: 'Ketua Panitia',
- prefix: 'SEM-2026-',
- sheetIndex: 0
- };
- // ===== ROUTER =====
- function doGet(e) {
- var p = e.parameter || {};
- if (p.no) return halamanVerifikasi_(p.no);
- if (p.email || p.nama) return halamanSertifikat_(p.email, p.nama);
- return halamanCari_();
- }
- // ===== DATA & HELPER =====
- function ambilData_() {
- var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[CONFIG.sheetIndex];
- return sh.getDataRange().getValues();
- }
- function buatNomor_(baris) {
- return CONFIG.prefix + ('000' + (baris - 1)).slice(-3);
- }
- function norm_(s) {
- return String(s || '').toLowerCase().replace(/\s+/g, ' ').trim();
- }
- function esc_(s) {
- return String(s).replace(/&/g, '&').replace(/</g, '<')
- .replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
- }
- // ===== TEMPLATE HALAMAN =====
- function bungkus_(isi) {
- var css = [
- '*{box-sizing:border-box}',
- 'body{margin:0;padding:16px;background:#e9eef7;font-family:Poppins,Arial,sans-serif;',
- '-webkit-print-color-adjust:exact;print-color-adjust:exact}',
- /* kotak form & verifikasi */
- '.box{max-width:430px;margin:50px auto;background:#fff;padding:32px;text-align:center;',
- 'border-radius:16px;border-top:8px solid #fbb724;box-shadow:0 8px 30px rgba(10,36,99,.15)}',
- '.box h2{color:#0a2463;margin:0 0 8px}',
- '.box p{color:#445}',
- '.box input{padding:12px;width:100%;margin:10px 0;font-size:16px;border:2px solid #c9d8f5;border-radius:10px}',
- '.btn{padding:12px 26px;font-size:16px;font-weight:700;cursor:pointer;border:0;border-radius:999px;',
- 'background:#0a2463;color:#fff}',
- '.btn.y{background:#fbb724;color:#0a2463}',
- /* sertifikat */
- '.wrap{width:100%;overflow:hidden}',
- '.stage{width:1000px;height:707px;position:relative;transform-origin:top left}',
- '.cert{position:absolute;inset:0;overflow:hidden;color:#0a2463;text-align:center;',
- 'background:radial-gradient(circle at 1px 1px,rgba(47,111,219,.13) 1.5px,transparent 1.6px) 0 0/22px 22px,',
- 'linear-gradient(135deg,#ffffff 0%,#eaf2ff 55%,#dbe8ff 100%)}',
- '.frame{position:absolute;inset:20px;border:2px solid rgba(10,36,99,.18);border-radius:14px}',
- /* sudut dekoratif */
- '.sd{position:absolute;width:330px;height:200px;background:#fbb724;clip-path:polygon(0 0,100% 0,0 100%)}',
- '.sn{position:absolute;width:290px;height:172px;background:#0a2463;clip-path:polygon(0 0,100% 0,0 100%)}',
- '.sb{position:absolute;width:210px;height:125px;background:#2f6fdb;clip-path:polygon(0 0,100% 0,0 100%)}',
- '.tl{top:0;left:0}',
- '.br{bottom:0;right:0;transform:rotate(180deg)}',
- /* isi */
- '.isi{position:absolute;left:110px;right:110px;top:46px}',
- '.pill{display:inline-block;background:#0a2463;color:#fff;font-weight:700;letter-spacing:6px;',
- 'font-size:15px;padding:8px 28px;border-radius:999px}',
- '.judul{font-size:62px;font-weight:800;letter-spacing:8px;margin:12px 0 0;line-height:1;color:#0a2463}',
- '.nomor{font-size:13px;color:#2f6fdb;font-weight:600;margin-top:8px;letter-spacing:1px}',
- '.kecil{font-size:16px;color:#34456b;margin:20px 0 4px}',
- '.nama{display:inline-block;font-size:44px;font-weight:800;color:#0a2463;padding:0 26px 4px;',
- 'border-bottom:6px solid #fbb724;line-height:1.15;max-width:100%}',
- '.inst{font-size:17px;font-weight:600;color:#2f6fdb;margin-top:10px}',
- '.ket{font-size:16px;color:#34456b;margin:16px 0 8px;line-height:1.5}',
- '.ket b.role{background:#0a2463;color:#fff;padding:2px 14px;border-radius:999px;font-size:14px;letter-spacing:1px}',
- '.tema{font-size:25px;font-weight:800;line-height:1.25;color:#0a2463}',
- '.sorot{display:inline-block;background:#fbb724;color:#0a2463;font-weight:800;font-size:25px;',
- 'padding:3px 22px;border-radius:999px;margin-top:8px}',
- '.tgl{font-size:14px;color:#34456b;margin-top:12px}',
- /* footer */
- '.qr{position:absolute;left:50%;transform:translateX(-50%);bottom:26px;width:300px;background:#fff;',
- 'padding:10px 10px 8px;border-radius:14px;border:2px solid #fbb724;text-align:center;',
- 'box-shadow:0 4px 14px rgba(10,36,99,.2);color:#0a2463}',
- '.qr img{display:block;width:86px;height:86px;margin:0 auto}',
- '.qr .cap{font-size:11px;font-weight:600;margin-top:6px;line-height:1.35}',
- '.qr .nm{font-size:13px;font-weight:800;margin-top:2px}',
- '.noprint{text-align:center;margin:18px}',
- /* cetak */
- '@page{size:A4 landscape;margin:0}',
- '@media print{body{padding:0;background:#fff}.noprint{display:none}',
- '.wrap{height:794px!important;overflow:hidden}',
- '.stage{transform:scale(1.1225)!important}}'
- ].join('');
- var js =
- '<script>function fit(){var w=document.getElementById("wrap");if(!w)return;' +
- 'var s=document.getElementById("stage");var k=Math.min(1,(window.innerWidth-32)/1000);' +
- 's.style.transform="scale("+k+")";w.style.height=(707*k)+"px";}' +
- 'window.addEventListener("resize",fit);window.addEventListener("load",fit);' +
- 'window.addEventListener("beforeprint",function(){var w=document.getElementById("wrap");' +
- 'var s=document.getElementById("stage");if(!w)return;' +
- 'w.style.height="794px";s.style.transform="scale(1.1225)";});' +
- 'window.addEventListener("afterprint",fit);</script>';
- return HtmlService.createHtmlOutput(
- '<!DOCTYPE html><html><head><meta charset="utf-8">' +
- '<meta name="viewport" content="width=device-width,initial-scale=1">' +
- '<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700;800&display=swap" rel="stylesheet">' +
- '<title>Sertifikat Seminar</title><style>' + css + '</style></head><body>' +
- isi + js + '</body></html>'
- ).setTitle('Sertifikat Seminar')
- .addMetaTag('viewport', 'width=device-width, initial-scale=1');
- }
- // ===== HALAMAN =====
- function halamanCari_(pesan) {
- return bungkus_(
- '<div class="box"><h2>Unduh Sertifikat Seminar</h2>' +
- '<p>' + esc_(CONFIG.judul) + ' ' + esc_(CONFIG.judulSorot) + '</p>' +
- (pesan ? '<p style="color:#d32f2f;font-weight:700">' + esc_(pesan) + '</p>' : '') +
- '<p>Isi data berikut sesuai saat pendaftaran untuk membuka sertifikat.</p>' +
- '<form method="get" action="' + ScriptApp.getService().getUrl() + '" target="_top" style="text-align:left">' +
- '<label style="font-weight:700;color:#0a2463">Nama Lengkap</label>' +
- '<input type="text" name="nama" placeholder="Nama sesuai pendaftaran" required>' +
- '<label style="font-weight:700;color:#0a2463">Email</label>' +
- '<input type="email" name="email" placeholder="[email protected]" required>' +
- '<div style="text-align:center;margin-top:8px">' +
- '<button class="btn" type="submit">Tampilkan Sertifikat</button></div></form></div>'
- );
- }
- function halamanSertifikat_(email, nama) {
- email = norm_(email);
- nama = norm_(nama);
- if (!email || !nama) return halamanCari_('Nama lengkap dan email wajib diisi.');
- var rows = ambilData_();
- for (var i = 1; i < rows.length; i++) {
- if (norm_(rows[i][2]) === email && norm_(rows[i][1]) === nama) {
- var nomor = buatNomor_(i + 1);
- var urlVerif = ScriptApp.getService().getUrl() + '?no=' + nomor;
- var qr = 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&margin=0&data=' +
- encodeURIComponent(urlVerif);
- var status = rows[i][5] ? ' • ' + esc_(String(rows[i][5]).toUpperCase()) : '';
- var namaSize = String(rows[i][1]).length > 28 ? 'style="font-size:34px"' : '';
- var cert =
- '<div class="wrap" id="wrap"><div class="stage" id="stage"><div class="cert">' +
- '<div class="frame"></div>' +
- '<div class="sd tl"></div><div class="sn tl"></div><div class="sb tl"></div>' +
- '<div class="sd br"></div><div class="sn br"></div><div class="sb br"></div>' +
- '<div class="isi">' +
- '<div class="pill">SEMINAR NASIONAL</div>' +
- '<div class="judul">SERTIFIKAT</div>' +
- '<div class="nomor">No. ' + esc_(nomor) + '</div>' +
- '<div class="kecil">Diberikan kepada</div>' +
- '<div class="nama" ' + namaSize + '>' + esc_(rows[i][1]) + '</div>' +
- '<div class="inst">' + esc_(rows[i][3]) + '</div>' +
- '<div class="ket">atas partisipasinya sebagai <b class="role">PESERTA' + status + '</b> dalam seminar</div>' +
- '<div class="tema">' + esc_(CONFIG.judul) + '</div>' +
- '<div class="sorot">' + esc_(CONFIG.judulSorot) + '</div>' +
- '<div class="tgl">' + esc_(CONFIG.tanggal) + ' • ' + esc_(CONFIG.tempat) + '</div>' +
- '</div>' +
- '<div class="qr"><img src="' + qr + '" alt="QR">' +
- '<div class="nm">' + esc_(CONFIG.penandatangan) + ' • ' + esc_(CONFIG.penyelenggara) + '</div>' +
- '<div class="cap">Tanda tangan digital • scan untuk verifikasi</div></div>' +
- '</div></div></div>' +
- '<div class="noprint"><button class="btn y" onclick="window.print()">Cetak / Simpan PDF</button></div>';
- return bungkus_(cert);
- }
- }
- return halamanCari_('Data tidak cocok. Pastikan nama lengkap dan email sama persis dengan saat mendaftar.');
- }
- function halamanVerifikasi_(no) {
- no = String(no).trim();
- var rows = ambilData_();
- for (var i = 1; i < rows.length; i++) {
- if (buatNomor_(i + 1) === no) {
- return bungkus_('<div class="box"><h2 style="color:#12a150">✔ SERTIFIKAT VALID</h2>' +
- '<p>Nomor: <b>' + esc_(no) + '</b></p>' +
- '<p>Atas nama: <b>' + esc_(rows[i][1]) + '</b></p>' +
- '<p>' + esc_(CONFIG.judul) + ' ' + esc_(CONFIG.judulSorot) + '</p></div>');
- }
- }
- return bungkus_('<div class="box"><h2 style="color:#d32f2f">✖ TIDAK VALID</h2>' +
- '<p>Nomor sertifikat tidak ditemukan.</p></div>');
- }
Advertisement
Add Comment
Please, Sign In to add comment