let loginSheetName = "Admin"; // Nama sheet yang menyimpan data login
// Sintaks untuk maping ke index.html
function doGet() {
return HtmlService.createHtmlOutputFromFile('dashboard'); // Mengembalikan halaman index
}
function getPage(pageName) {
if (pageName === 'dashboard') {
return HtmlService.createHtmlOutputFromFile('dashboard');
} else if (pageName === 'nilai') {
return HtmlService.createHtmlOutputFromFile('nilai');
} else if (pageName === 'lihat-data') {
return HtmlService.createHtmlOutputFromFile('lihat-data');
} else if (pageName === 'pengaturan') {
return HtmlService.createHtmlOutputFromFile('pengaturan');
}
}
function logoutUser() {
// Fungsi untuk menghapus status login dan mengarahkan ke halaman login
return HtmlService.createHtmlOutput("window.location.href = 'login.html';");
}
function doGet(e) {
// Ambil parameter page dari URL, default ke 'login'
const page = (e.parameter.page || 'login').toLowerCase();
// Daftar halaman HTML yang diizinkan
const allowedPages = ['login', 'lihat-data', 'nilai', 'pengaturan', 'dashboard'];
// Cek apakah halaman yang diminta diizinkan
const safePage = allowedPages.includes(page) ? page : 'login';
return HtmlService.createHtmlOutputFromFile(safePage)
.setTitle("Aplikasi Penilaian")
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
// Fungsi cek login
// Fungsi untuk memverifikasi login dan mengambil data nama guru
function verifyLogin(username, password) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Admin');
const data = sheet.getDataRange().getValues(); // Ambil semua data dari sheet Admin
// Loop untuk mencari username dan password yang cocok
for (let i = 1; i < data.length; i++) {
const storedUsername = data[i][1]; // Kolom USERNAME (indeks 1)
const storedPassword = data[i][2]; // Kolom PASSWORD (indeks 2)
if (storedUsername === username && storedPassword === password) {
// Login berhasil, simpan status login
const userProps = PropertiesService.getUserProperties();
userProps.setProperty('username', username); // Menyimpan username login
// Mengembalikan data pengguna yang login, termasuk nama guru
return {
success: true,
nama: data[i][3], // Kolom NAMA GURU (indeks 3)
role: 'Guru' // Menyimpan role sebagai Guru
};
}
}
function getDataGuru() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Admin");
const data = sheet.getRange(2, 1, sheet.getLastRow()-1, 6).getValues(); // tanpa header
return data;
}
// Jika tidak ditemukan kecocokan, kembalikan status gagal dengan pesan kesalahan
return {
success: false,
message: 'Username atau Password salah!' // Pesan kesalahan yang jelas
};
}
// Menampilkan halaman dashboard setelah login berhasil
function loadIndexPage(nama, position, email) {
// Ini adalah template untuk halaman index.html setelah login
var template = HtmlService.createTemplateFromFile('dashboard.html'); // Pastikan nama file 'index.html' sesuai
template.nama = nama;
template.position = position;
template.email = email;
// Kembalikan HTML ke browser
return template.evaluate().getContent();
}
function getPage(pageName) {
const allowedPages = ['dashboard', 'nilai', 'lihat-data', 'pengaturan'];
if (!allowedPages.includes(pageName)) {
pageName = 'dashboard';
}
return HtmlService.createHtmlOutputFromFile(pageName).getContent();
}
// Menu di spreadsheet
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('📘 Menu Rapor')
.addItem('📊 Tampilkan Sidebar', 'tampilkanSidebar')
.addToUi();
}
// Buat header jika belum ada di sheet "Data"
function buatHeaderJikaBelumAda() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DATA");
if (!sheet) {
SpreadsheetApp.getActiveSpreadsheet().insertSheet("DATA");
}
if (sheet.getLastRow() === 0) {
sheet.appendRow([
"NO", "NAMA", "NISN", "MAPEL", "KELAS",
"TP1", "TP2", "TP3", "TP4", "TP5", "TP6", "TP7", "TP8",
"LM1", "LM2", "LM3", "LM4", "LM5", "LM6", "LM7", "LM8",
"NA STS", "NA SAS", "TANGGAL INPUT"
]);
}
}
function showDataPage() {
return HtmlService.createHtmlOutputFromFile('data')
.setWidth(1200)
.setHeight(600);
}
function getData() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('DATA'); // ganti sesuai nama sheet kamu
const data = sheet.getDataRange().getValues();
return data;
}
// Simpan data siswa
function simpanData(data) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
const semuaData = sheet.getDataRange().getValues();
const nomorUrut = semuaData.length;
const totalTP = [data.tp_1, data.tp_2, data.tp_3, data.tp_4, data.tp_5, data.tp_6, data.tp_7, data.tp_8]
.reduce((sum, val) => sum + (parseFloat(val) || 0), 0);
const totalLM = [data.lm_1, data.lm_2, data.lm_3, data.lm_4, data.lm_5, data.lm_6, data.lm_7, data.lm_8]
.reduce((sum, val) => sum + (parseFloat(val) || 0), 0);
const na_sts = (totalTP / 8).toFixed(2);
const na_sas = (totalLM / 8).toFixed(2);
const row = [
nomorUrut,
data.nama_siswa,
data.nisn,
data.mata_pelajaran,
data.kelas,
data.tp_1, data.tp_2, data.tp_3, data.tp_4,
data.tp_5, data.tp_6, data.tp_7, data.tp_8,
data.lm_1, data.lm_2, data.lm_3, data.lm_4,
data.lm_5, data.lm_6, data.lm_7, data.lm_8,
na_sts,
na_sas,
new Date()
];
sheet.getRange(sheet.getLastRow() + 1, 1, 1, row.length).setValues([row]);
SpreadsheetApp.flush(); // Pastikan data segera disimpan
resetNomorUrut(); // Menjaga urutan NO tetap rapi
return '✅ Data berhasil disimpan!';
}
// Fungsi reset nomor urut otomatis
function resetNomorUrut() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
const data = sheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
sheet.getRange(i + 1, 1).setValue(i);
}
SpreadsheetApp.flush();
}
// Cari data berdasarkan NISN
function cariData(nisn) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
const data = sheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
if (data[i][2] == nisn) {
return {
rowIndex: i + 1,
nama_siswa: data[i][1],
nisn: data[i][2],
mata_pelajaran: data[i][3],
kelas: data[i][4],
tp_1: data[i][5], tp_2: data[i][6], tp_3: data[i][7], tp_4: data[i][8],
tp_5: data[i][9], tp_6: data[i][10], tp_7: data[i][11], tp_8: data[i][12],
lm_1: data[i][13], lm_2: data[i][14], lm_3: data[i][15], lm_4: data[i][16],
lm_5: data[i][17], lm_6: data[i][18], lm_7: data[i][19], lm_8: data[i][20],
na_sts: data[i][21],
na_sas: data[i][22],
tanggal_input: data[i][23]
};
}
}
return null; // Jika data tidak ditemukan
}
function ambilDataRapor() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data Rapor");
const data = sheet.getDataRange().getValues(); // Ambil semua data
return data.slice(1); // Hapus header
}
// Skript Untuk integrasi ke pengaturan.html
function simpanDataTP(mapel, tpList, semester) {
const ss = SpreadsheetApp.openById("1AThNmj05y6NqfXWpn9AQOPoNcNf-xpEeRx58WZlQnfY");
let sheet = ss.getSheetByName("TP");
if (!sheet) {
sheet = ss.insertSheet("TP");
sheet.appendRow(["No", "MAPEL", "TP", "Semester"]);
}
const tps = tpList.split("\n").map(tp => tp.trim()).filter(tp => tp !== "");
const startRow = sheet.getLastRow() + 1;
for (let i = 0; i < tps.length; i++) {
sheet.appendRow([
startRow + i - 1, // Nomor urut
mapel,
tps[i],
semester
]);
}
}
function doPost(e) {
try {
const sheet = SpreadsheetApp.openById('1AThNmj05y6NqfXWpn9AQOPoNcNf-xpEeRx58WZlQnfY').getSheetByName('TP');
const data = JSON.parse(e.postData.contents);
const lastRow = sheet.getLastRow();
const no = lastRow + 1; // Menambah nomor urut
sheet.appendRow([no, data.mapel, data.tp, data.semester]);
return ContentService.createTextOutput(JSON.stringify({ success: true }))
.setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({ success: false, error: err.message }))
.setMimeType(ContentService.MimeType.JSON);
}
}
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Form Nilai Rapor</title>
<!-- ✅ Bootstrap 5 CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', sans-serif;
margin: 0;
padding: 0;
background-color: #f5f7fa;
color: #333;
display: flex;
height: 100vh;
}
.sidebar {
width: 220px;
background-color: #1a73e8;
color: white;
padding: 20px;
display: flex;
flex-direction: column;
}
.sidebar h2 {
color: white;
margin-bottom: 30px;
font-size: 1.2em;
text-align: center;
}
.sidebar a {
color: white;
text-decoration: none;
margin-bottom: 15px;
font-weight: 500;
display: block;
transition: background 0.3s;
}
.sidebar a:hover {
background-color: #1558b0;
padding-left: 10px;
border-radius: 4px;
}
.content {
flex-grow: 1;
padding: 20px;
overflow-y: auto;
}
h2 {
text-align: center;
color: #1a73e8;
}
.section {
background: white;
padding: 20px;
border-radius: 12px;
margin-bottom: 20px;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
h3 {
margin-bottom: 15px;
color: #444;
}
label {
font-size: 0.9em;
margin-top: 10px;
display: block;
}
input, select {
width: 100%;
padding: 6px 8px;
margin-top: 5px;
font-size: 0.9em;
border: 1px solid #ccc;
border-radius: 6px;
}
.grid-inputs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
gap: 10px;
}
.grid-inputs label {
font-size: 0.8em;
}
button {
background-color: #1a73e8;
color: white;
padding: 12px;
width: 100%;
border: none;
border-radius: 8px;
font-size: 1em;
cursor: pointer;
margin-top: 10px;
}
button:hover {
background-color: #0f4ea4;
}
input[readonly] {
background-color: #eee;
}
.hidden {
display: none;
}
</style>
</head>
<!-- Sidebar -->
<nav class="sidebar d-flex flex-column p-3 bg-primary text-white" style="width: 220px; height: 100vh;">
<h2 class="text-center mb-4">📊 Menu Rapor</h2>
<!-- HTML untuk Menampilkan Nama Guru -->
<div class="mb-4 small">
👤 <strong id="user-name">Guru</strong><br/>
🧭 <em id="user-role">Pengguna</em>
</div>
<!-- Script untuk Menampilkan Nama Guru yang Login -->
<script>
function tampilkanNamaGuru() {
google.script.run.withSuccessHandler(function(response) {
if (response.success) {
document.getElementById('user-name').textContent = response.nama; // Set nama guru
document.getElementById('user-role').textContent = response.role; // Set role Guru
} else {
alert('Login gagal: ' + response.message);
}
}).verifyLogin('USERNAME', 'PASSWORD'); // Ganti dengan username dan password yang sesuai
}
// Panggil fungsi saat halaman dimuat
window.onload = tampilkanNamaGuru;
</script>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="#" class="nav-link text-white">🏠 Beranda</a>
</li>
<li>
<a href="#" class="nav-link text-white">📝 Input Nilai</a>
</li>
<li>
<a href="#" class="nav-link text-white">📄 Lihat Data</a>
</li>
<li>
<a href="#" class="nav-link text-white">⚙️ Pengaturan</a>
</li>
<li>
<a href="#" class="nav-link text-white" onclick="logout()">🚪 Logout</a>
</li>
</ul>
</nav>
<div class="content">
<h2 class="text-center text-primary mb-4">📝 Form Input Nilai Rapor</h2>
<form id="raporForm">
<!-- Identitas -->
<div class="section mb-4">
<h3 class="mb-3">📘 Identitas Siswa</h3>
<div class="mb-3">
<label for="nama_siswa" class="form-label">Nama Siswa</label>
<input type="text" class="form-control" name="nama_siswa" id="nama_siswa" required />
</div>
<div class="mb-3">
<label for="nisn" class="form-label">NISN</label>
<input type="text" class="form-control" name="nisn" id="nisn" required />
</div>
<div class="mb-3">
<label for="kelas" class="form-label">Kelas</label>
<select name="kelas" id="kelas" class="form-select" required>
<option value="">--Pilih Kelas--</option>
<option>Kelas I</option>
<option>Kelas II</option>
<option>Kelas III</option>
<option>Kelas IV</option>
<option>Kelas V</option>
<option>Kelas VI</option>
</select>
</div>
<div class="mb-3">
<label for="mata_pelajaran" class="form-label">Mata Pelajaran</label>
<select name="mata_pelajaran" id="mata_pelajaran" class="form-select" required>
<option value="">--Pilih Mapel--</option>
<option>Pendidikan Agama Katolik dan Budi Pekerti</option>
<option>Pendidikan Pancasila</option>
<option>Bahasa Indonesia</option>
<option>Matematika</option>
<option>IPAS</option>
<option>Bahasa Inggris</option>
<option>Seni Tari</option>
<option>Seni Musik</option>
<option>Seni Rupa</option>
<option>Mulok 1</option>
<option>Mulok 2</option>
<option>Mulok 3</option>
</select>
</div>
<form id="raporForm">
<!-- TP -->
<div class="section">
<h3>🧪 Nilai Sumatif TP</h3>
<div class="grid-inputs" id="tpInputs"></div>
</div>
<!-- LM -->
<div class="section">
<h3>📚 Nilai Sumatif LM</h3>
<div class="grid-inputs" id="lmInputs"></div>
</div>
<!-- Input Nilai Akhir -->
<div class="section">
<h3>📊 Nilai Akhir</h3>
<label>NA STS (otomatis)</label>
<input type="number" name="sts" id="sts" readonly>
<label>NA SAS (otomatis)</label>
<input type="number" name="sas" id="sas" readonly>
</div>
<!-- Tombol Simpan, Update, dll -->
<button type="submit" id="saveBtn">💾 Simpan Nilai</button>
<button type="button" id="updateBtn" class="hidden">Update Nilai</button>
<button type="button" id="searchBtn">🔍 Cari Data</button>
<button type="button" id="deleteBtn" class="hidden">🗑️ Hapus Data</button>
</form>
<script>
const form = document.getElementById("raporForm");
// Generate input TP dan LM
window.onload = function () {
const tpContainer = document.getElementById("tpInputs");
const lmContainer = document.getElementById("lmInputs");
for (let i = 1; i <= 8; i++) {
tpContainer.innerHTML += `
<div>
<label>TP ${i}</label>
<input type="number" name="tp_${i}" min="0" max="100" required>
</div>`;
lmContainer.innerHTML += `
<div>
<label>LM ${i}</label>
<input type="number" name="lm_${i}" min="0" max="100" required>
</div>`;
}
};
// Hitung rata-rata otomatis saat input berubah
form.addEventListener("input", () => {
let totalTP = 0, totalLM = 0;
for (let i = 1; i <= 8; i++) {
const tpVal = parseFloat(form.querySelector(`[name="tp_${i}"]`)?.value) || 0;
const lmVal = parseFloat(form.querySelector(`[name="lm_${i}"]`)?.value) || 0;
totalTP += tpVal;
totalLM += lmVal;
}
form.querySelector('[name="sts"]').value = (totalTP / 8).toFixed(2);
form.querySelector('[name="sas"]').value = (totalLM / 8).toFixed(2);
});
// Fungsi untuk meng-clear form
function clearForm() {
form.reset(); // Reset form
for (let i = 1; i <= 8; i++) {
form.querySelector(`[name="tp_${i}"]`).value = '';
form.querySelector(`[name="lm_${i}"]`).value = '';
}
form.querySelector('[name="sts"]').value = '';
form.querySelector('[name="sas"]').value = '';
document.getElementById("updateBtn").classList.add("hidden");
document.getElementById("deleteBtn").classList.add("hidden");
}
// Tombol Simpan Data
document.getElementById("saveBtn").addEventListener("click", (e) => {
e.preventDefault(); // Mencegah form submit default
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ Masukkan NISN untuk menyimpan data.");
return;
}
const data = {
nisn: nisn,
nama_siswa: form.querySelector('[name="nama_siswa"]').value.trim(),
kelas: form.querySelector('[name="kelas"]').value.trim(),
mata_pelajaran: form.querySelector('[name="mata_pelajaran"]').value.trim(),
sts: form.querySelector('[name="sts"]').value.trim(),
sas: form.querySelector('[name="sas"]').value.trim(),
};
for (let i = 1; i <= 8; i++) {
data[`tp_${i}`] = form.querySelector(`[name="tp_${i}"]`).value.trim();
data[`lm_${i}`] = form.querySelector(`[name="lm_${i}"]`).value.trim();
}
google.script.run
.withSuccessHandler(() => {
alert("✅ Data berhasil disimpan.");
clearForm(); // Clear form after saving
})
.withFailureHandler((err) => alert("❌ Gagal menyimpan data: " + err.message))
.simpanData(data);
});
// Tombol Cari Data
document.getElementById("searchBtn").addEventListener("click", () => {
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ Masukkan NISN untuk mencari data.");
return;
}
google.script.run
.withSuccessHandler((data) => {
if (data) {
form.querySelector('[name="nama_siswa"]').value = data.nama_siswa || "";
form.querySelector('[name="kelas"]').value = data.kelas || "";
form.querySelector('[name="mata_pelajaran"]').value = data.mata_pelajaran || "";
for (let i = 1; i <= 8; i++) {
if (data[`tp_${i}`]) form.querySelector(`[name="tp_${i}"]`).value = data[`tp_${i}`];
if (data[`lm_${i}`]) form.querySelector(`[name="lm_${i}"]`).value = data[`lm_${i}`];
}
form.querySelector('[name="sts"]').value = data.sts || "";
form.querySelector('[name="sas"]').value = data.sas || "";
document.getElementById("updateBtn").classList.remove("hidden");
document.getElementById("deleteBtn").classList.remove("hidden");
} else {
alert("❌ Data tidak ditemukan.");
}
})
.withFailureHandler((err) => alert("❌ Gagal mencari data: " + err.message))
.cariData(nisn);
});
// Tombol Update Data
document.getElementById("updateBtn").addEventListener("click", () => {
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ NISN tidak ditemukan.");
return;
}
const data = {
nisn: nisn,
nama_siswa: form.querySelector('[name="nama_siswa"]').value.trim(),
kelas: form.querySelector('[name="kelas"]').value.trim(),
mata_pelajaran: form.querySelector('[name="mata_pelajaran"]').value.trim(),
sts: form.querySelector('[name="sts"]').value.trim(),
sas: form.querySelector('[name="sas"]').value.trim(),
};
for (let i = 1; i <= 8; i++) {
data[`tp_${i}`] = form.querySelector(`[name="tp_${i}"]`).value.trim();
data[`lm_${i}`] = form.querySelector(`[name="lm_${i}"]`).value.trim();
}
google.script.run
.withSuccessHandler(() => {
alert("✅ Data berhasil diperbarui.");
clearForm(); // Clear form after updating
})
.withFailureHandler((err) => alert("❌ Gagal memperbarui data: " + err.message))
.updateData(data);
});
// Tombol Hapus Data
document.getElementById("deleteBtn").addEventListener("click", () => {
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ NISN tidak ditemukan.");
return;
}
const confirmDelete = confirm("⚠️ Apakah Anda yakin ingin menghapus data ini?");
if (confirmDelete) {
google.script.run
.withSuccessHandler(() => {
alert("✅ Data berhasil dihapus.");
clearForm(); // Clear form after deleting
})
.withFailureHandler((err) => alert("❌ Gagal menghapus data: " + err.message))
.hapusData(nisn);
}
});
</script>
<script>
// Logout handler
function logout() {
if (confirm("Yakin ingin logout?")) {
google.script.run
.withSuccessHandler(() => location.reload())
.logoutUser();
}
}
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Form Nilai Rapor</title>
<!-- ✅ Bootstrap 5 CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', sans-serif;
margin: 0;
padding: 0;
background-color: #f5f7fa;
color: #333;
display: flex;
height: 100vh;
}
.sidebar {
width: 220px;
background-color: #1a73e8;
color: white;
padding: 20px;
display: flex;
flex-direction: column;
}
.sidebar h2 {
color: white;
margin-bottom: 30px;
font-size: 1.2em;
text-align: center;
}
.sidebar a {
color: white;
text-decoration: none;
margin-bottom: 15px;
font-weight: 500;
display: block;
transition: background 0.3s;
}
.sidebar a:hover {
background-color: #1558b0;
padding-left: 10px;
border-radius: 4px;
}
.content {
flex-grow: 1;
padding: 20px;
overflow-y: auto;
}
h2 {
text-align: center;
color: #1a73e8;
}
.section {
background: white;
padding: 20px;
border-radius: 12px;
margin-bottom: 20px;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
h3 {
margin-bottom: 15px;
color: #444;
}
label {
font-size: 0.9em;
margin-top: 10px;
display: block;
}
input, select {
width: 100%;
padding: 6px 8px;
margin-top: 5px;
font-size: 0.9em;
border: 1px solid #ccc;
border-radius: 6px;
}
.grid-inputs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
gap: 10px;
}
.grid-inputs label {
font-size: 0.8em;
}
button {
background-color: #1a73e8;
color: white;
padding: 12px;
width: 100%;
border: none;
border-radius: 8px;
font-size: 1em;
cursor: pointer;
margin-top: 10px;
}
button:hover {
background-color: #0f4ea4;
}
input[readonly] {
background-color: #eee;
}
.hidden {
display: none;
}
</style>
</head>
<!-- Sidebar -->
<nav class="sidebar d-flex flex-column p-3 bg-primary text-white" style="width: 220px; height: 100vh;">
<h2 class="text-center mb-4">📊 Menu Rapor</h2>
<!-- HTML untuk Menampilkan Nama Guru -->
<div class="mb-4 small">
👤 <strong id="user-name">Guru</strong><br/>
🧭 <em id="user-role">Pengguna</em>
</div>
<!-- Script untuk Menampilkan Nama Guru yang Login -->
<script>
function tampilkanNamaGuru() {
google.script.run.withSuccessHandler(function(response) {
if (response.success) {
document.getElementById('user-name').textContent = response.nama; // Set nama guru
document.getElementById('user-role').textContent = response.role; // Set role Guru
} else {
alert('Login gagal: ' + response.message);
}
}).verifyLogin('USERNAME', 'PASSWORD'); // Ganti dengan username dan password yang sesuai
}
// Panggil fungsi saat halaman dimuat
window.onload = tampilkanNamaGuru;
</script>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="#" class="nav-link text-white">🏠 Beranda</a>
</li>
<li>
<a href="#" class="nav-link text-white">📝 Input Nilai</a>
</li>
<li>
<a href="#" class="nav-link text-white">📄 Lihat Data</a>
</li>
<li>
<a href="#" class="nav-link text-white">⚙️ Pengaturan</a>
</li>
<li>
<a href="#" class="nav-link text-white" onclick="logout()">🚪 Logout</a>
</li>
</ul>
</nav>
<div class="content">
<h2 class="text-center text-primary mb-4">📝 Form Input Nilai Rapor</h2>
<form id="raporForm">
<!-- Identitas -->
<div class="section mb-4">
<h3 class="mb-3">📘 Identitas Siswa</h3>
<div class="mb-3">
<label for="nama_siswa" class="form-label">Nama Siswa</label>
<input type="text" class="form-control" name="nama_siswa" id="nama_siswa" required />
</div>
<div class="mb-3">
<label for="nisn" class="form-label">NISN</label>
<input type="text" class="form-control" name="nisn" id="nisn" required />
</div>
<div class="mb-3">
<label for="kelas" class="form-label">Kelas</label>
<select name="kelas" id="kelas" class="form-select" required>
<option value="">--Pilih Kelas--</option>
<option>Kelas I</option>
<option>Kelas II</option>
<option>Kelas III</option>
<option>Kelas IV</option>
<option>Kelas V</option>
<option>Kelas VI</option>
</select>
</div>
<div class="mb-3">
<label for="mata_pelajaran" class="form-label">Mata Pelajaran</label>
<select name="mata_pelajaran" id="mata_pelajaran" class="form-select" required>
<option value="">--Pilih Mapel--</option>
<option>Pendidikan Agama Katolik dan Budi Pekerti</option>
<option>Pendidikan Pancasila</option>
<option>Bahasa Indonesia</option>
<option>Matematika</option>
<option>IPAS</option>
<option>Bahasa Inggris</option>
<option>Seni Tari</option>
<option>Seni Musik</option>
<option>Seni Rupa</option>
<option>Mulok 1</option>
<option>Mulok 2</option>
<option>Mulok 3</option>
</select>
</div>
<form id="raporForm">
<!-- TP -->
<div class="section">
<h3>🧪 Nilai Sumatif TP</h3>
<div class="grid-inputs" id="tpInputs"></div>
</div>
<!-- LM -->
<div class="section">
<h3>📚 Nilai Sumatif LM</h3>
<div class="grid-inputs" id="lmInputs"></div>
</div>
<!-- Input Nilai Akhir -->
<div class="section">
<h3>📊 Nilai Akhir</h3>
<label>NA STS (otomatis)</label>
<input type="number" name="sts" id="sts" readonly>
<label>NA SAS (otomatis)</label>
<input type="number" name="sas" id="sas" readonly>
</div>
<!-- Tombol Simpan, Update, dll -->
<button type="submit" id="saveBtn">💾 Simpan Nilai</button>
<button type="button" id="updateBtn" class="hidden">Update Nilai</button>
<button type="button" id="searchBtn">🔍 Cari Data</button>
<button type="button" id="deleteBtn" class="hidden">🗑️ Hapus Data</button>
</form>
<script>
const form = document.getElementById("raporForm");
// Generate input TP dan LM
window.onload = function () {
const tpContainer = document.getElementById("tpInputs");
const lmContainer = document.getElementById("lmInputs");
for (let i = 1; i <= 8; i++) {
tpContainer.innerHTML += `
<div>
<label>TP ${i}</label>
<input type="number" name="tp_${i}" min="0" max="100" required>
</div>`;
lmContainer.innerHTML += `
<div>
<label>LM ${i}</label>
<input type="number" name="lm_${i}" min="0" max="100" required>
</div>`;
}
};
// Hitung rata-rata otomatis saat input berubah
form.addEventListener("input", () => {
let totalTP = 0, totalLM = 0;
for (let i = 1; i <= 8; i++) {
const tpVal = parseFloat(form.querySelector(`[name="tp_${i}"]`)?.value) || 0;
const lmVal = parseFloat(form.querySelector(`[name="lm_${i}"]`)?.value) || 0;
totalTP += tpVal;
totalLM += lmVal;
}
form.querySelector('[name="sts"]').value = (totalTP / 8).toFixed(2);
form.querySelector('[name="sas"]').value = (totalLM / 8).toFixed(2);
});
// Fungsi untuk meng-clear form
function clearForm() {
form.reset(); // Reset form
for (let i = 1; i <= 8; i++) {
form.querySelector(`[name="tp_${i}"]`).value = '';
form.querySelector(`[name="lm_${i}"]`).value = '';
}
form.querySelector('[name="sts"]').value = '';
form.querySelector('[name="sas"]').value = '';
document.getElementById("updateBtn").classList.add("hidden");
document.getElementById("deleteBtn").classList.add("hidden");
}
// Tombol Simpan Data
document.getElementById("saveBtn").addEventListener("click", (e) => {
e.preventDefault(); // Mencegah form submit default
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ Masukkan NISN untuk menyimpan data.");
return;
}
const data = {
nisn: nisn,
nama_siswa: form.querySelector('[name="nama_siswa"]').value.trim(),
kelas: form.querySelector('[name="kelas"]').value.trim(),
mata_pelajaran: form.querySelector('[name="mata_pelajaran"]').value.trim(),
sts: form.querySelector('[name="sts"]').value.trim(),
sas: form.querySelector('[name="sas"]').value.trim(),
};
for (let i = 1; i <= 8; i++) {
data[`tp_${i}`] = form.querySelector(`[name="tp_${i}"]`).value.trim();
data[`lm_${i}`] = form.querySelector(`[name="lm_${i}"]`).value.trim();
}
google.script.run
.withSuccessHandler(() => {
alert("✅ Data berhasil disimpan.");
clearForm(); // Clear form after saving
})
.withFailureHandler((err) => alert("❌ Gagal menyimpan data: " + err.message))
.simpanData(data);
});
// Tombol Cari Data
document.getElementById("searchBtn").addEventListener("click", () => {
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ Masukkan NISN untuk mencari data.");
return;
}
google.script.run
.withSuccessHandler((data) => {
if (data) {
form.querySelector('[name="nama_siswa"]').value = data.nama_siswa || "";
form.querySelector('[name="kelas"]').value = data.kelas || "";
form.querySelector('[name="mata_pelajaran"]').value = data.mata_pelajaran || "";
for (let i = 1; i <= 8; i++) {
if (data[`tp_${i}`]) form.querySelector(`[name="tp_${i}"]`).value = data[`tp_${i}`];
if (data[`lm_${i}`]) form.querySelector(`[name="lm_${i}"]`).value = data[`lm_${i}`];
}
form.querySelector('[name="sts"]').value = data.sts || "";
form.querySelector('[name="sas"]').value = data.sas || "";
document.getElementById("updateBtn").classList.remove("hidden");
document.getElementById("deleteBtn").classList.remove("hidden");
} else {
alert("❌ Data tidak ditemukan.");
}
})
.withFailureHandler((err) => alert("❌ Gagal mencari data: " + err.message))
.cariData(nisn);
});
// Tombol Update Data
document.getElementById("updateBtn").addEventListener("click", () => {
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ NISN tidak ditemukan.");
return;
}
const data = {
nisn: nisn,
nama_siswa: form.querySelector('[name="nama_siswa"]').value.trim(),
kelas: form.querySelector('[name="kelas"]').value.trim(),
mata_pelajaran: form.querySelector('[name="mata_pelajaran"]').value.trim(),
sts: form.querySelector('[name="sts"]').value.trim(),
sas: form.querySelector('[name="sas"]').value.trim(),
};
for (let i = 1; i <= 8; i++) {
data[`tp_${i}`] = form.querySelector(`[name="tp_${i}"]`).value.trim();
data[`lm_${i}`] = form.querySelector(`[name="lm_${i}"]`).value.trim();
}
google.script.run
.withSuccessHandler(() => {
alert("✅ Data berhasil diperbarui.");
clearForm(); // Clear form after updating
})
.withFailureHandler((err) => alert("❌ Gagal memperbarui data: " + err.message))
.updateData(data);
});
// Tombol Hapus Data
document.getElementById("deleteBtn").addEventListener("click", () => {
const nisn = form.querySelector('[name="nisn"]').value.trim();
if (!nisn) {
alert("❌ NISN tidak ditemukan.");
return;
}
const confirmDelete = confirm("⚠️ Apakah Anda yakin ingin menghapus data ini?");
if (confirmDelete) {
google.script.run
.withSuccessHandler(() => {
alert("✅ Data berhasil dihapus.");
clearForm(); // Clear form after deleting
})
.withFailureHandler((err) => alert("❌ Gagal menghapus data: " + err.message))
.hapusData(nisn);
}
});
</script>
<script>
// Logout handler
function logout() {
if (confirm("Yakin ingin logout?")) {
google.script.run
.withSuccessHandler(() => location.reload())
.logoutUser();
}
}
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lihat Data Nilai</title>
<!-- ✅ Bootstrap 5 CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
/* Style yang sudah ada sebelumnya */
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', sans-serif;
margin: 0;
padding: 0;
background-color: #f5f7fa;
color: #333;
display: flex;
height: 100vh;
}
.sidebar {
width: 220px;
background-color: #1a73e8;
color: white;
padding: 20px;
display: flex;
flex-direction: column;
}
.sidebar h2 {
color: white;
margin-bottom: 30px;
font-size: 1.2em;
text-align: center;
}
.sidebar a {
color: white;
text-decoration: none;
margin-bottom: 15px;
font-weight: 500;
display: block;
transition: background 0.3s;
}
.sidebar a:hover {
background-color: #1558b0;
padding-left: 10px;
border-radius: 4px;
}
.content {
flex-grow: 1;
padding: 20px;
overflow-y: auto;
}
h2 {
text-align: center;
color: #1a73e8;
}
</style>
</head>
<!-- Sidebar -->
<nav class="sidebar d-flex flex-column p-3 bg-primary text-white" style="width: 220px; height: 100vh;">
<h2 class="text-center mb-4">📊 Menu Rapor</h2>
<div class="mb-4 small">
👤 <strong id="user-name">Guru</strong><br/>
🧭 <em id="user-role">Pengguna</em>
</div>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="index.html" class="nav-link text-white">🏠 Beranda</a>
</li>
<li>
<a href="#" class="nav-link text-white">📄 Lihat Data</a>
</li>
<li>
<a href="#" class="nav-link text-white">⚙️ Pengaturan</a>
</li>
<li>
<a href="#" class="nav-link text-white" onclick="logout()">🚪 Logout</a>
</li>
</ul>
</nav>
<div class="content">
<h2 class="text-center text-primary mb-4">📄 Lihat Data Nilai</h2>
<div id="table_div">Memuat data...</div>
</div>
<script>
// Panggil fungsi untuk menampilkan nama guru saat halaman dimuat
function tampilkanNamaGuru() {
google.script.run.withSuccessHandler(function(response) {
if (response.success) {
document.getElementById('user-name').textContent = response.nama; // Set nama guru
document.getElementById('user-role').textContent = response.role; // Set role Guru
} else {
alert('Login gagal: ' + response.message);
}
}).verifyLogin('USERNAME', 'PASSWORD'); // Ganti dengan username dan password yang sesuai
}
// Memuat dan menampilkan data nilai dari Google Sheets
google.charts.load('current', { packages: ['DATA'] });
google.charts.setOnLoadCallback(drawTable);
let originalData;
function drawTable() {
const queryString = encodeURIComponent("SELECT B, C, D, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W");
const spreadsheetId = "1mqz0rC0lBC1YmBVCwy1K64PUnZGKpMuFQ0tww5MknRI";
const dataSourceUrl = `https://docs.google.com/spreadsheets/d/${spreadsheetId}/gviz/tq?tq=${queryString}`;
const query = new google.visualization.Query(dataSourceUrl);
query.send(function(response) {
const data = response.getDataTable();
originalData = data;
const table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(data, {showRowNumber: false, width: '100%', height: '100%'});
});
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Form Nilai Rapor</title>
<!-- ✅ Bootstrap 5 CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', sans-serif;
margin: 0;
padding: 0;
background-color: #f5f7fa;
color: #333;
display: flex;
height: 100vh;
}
.sidebar {
width: 220px;
background-color: #1a73e8;
color: white;
padding: 20px;
display: flex;
flex-direction: column;
}
.sidebar h2 {
color: white;
margin-bottom: 30px;
font-size: 1.2em;
text-align: center;
}
.sidebar a {
color: white;
text-decoration: none;
margin-bottom: 15px;
font-weight: 500;
display: block;
transition: background 0.3s;
}
.sidebar a:hover {
background-color: #1558b0;
padding-left: 10px;
border-radius: 4px;
}
.content {
flex-grow: 1;
padding: 20px;
overflow-y: auto;
}
h2 {
text-align: center;
color: #1a73e8;
}
.section {
background: white;
padding: 20px;
border-radius: 12px;
margin-bottom: 20px;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
h3 {
margin-bottom: 15px;
color: #444;
}
label {
font-size: 0.9em;
margin-top: 10px;
display: block;
}
input, select {
width: 100%;
padding: 6px 8px;
margin-top: 5px;
font-size: 0.9em;
border: 1px solid #ccc;
border-radius: 6px;
}
.grid-inputs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
gap: 10px;
}
.grid-inputs label {
font-size: 0.8em;
}
button {
background-color: #1a73e8;
color: white;
padding: 12px;
width: 100%;
border: none;
border-radius: 8px;
font-size: 1em;
cursor: pointer;
margin-top: 10px;
}
button:hover {
background-color: #0f4ea4;
}
input[readonly] {
background-color: #eee;
}
.hidden {
display: none;
}
</style>
</head>
<!-- Sidebar -->
<nav class="sidebar d-flex flex-column p-3 bg-primary text-white" style="width: 220px; height: 100vh;">
<h2 class="text-center mb-4">📊 Menu Rapor</h2>
<!-- HTML untuk Menampilkan Nama Guru -->
<div class="mb-4 small">
👤 <strong id="user-name">Guru</strong><br/>
🧭 <em id="user-role">Pengguna</em>
</div>
</script>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="#" class="nav-link text-white">🏠 Beranda</a>
</li>
<li>
<a href="#" class="nav-link text-white">📝 Input Nilai</a>
</li>
<li>
<a href="#" class="nav-link text-white">📄 Lihat Nilai</a>
</li>
<li>
<a href="#" class="nav-link text-white">⚙️ Raport</a>
</li>
<li>
<a href="#" class="nav-link text-white" onclick="logout()">🚪 Logout</a>
</li>
</ul>
</nav>
<!-- Content -->
<div class="content">
<h2>Selamat datang di Dashboard Rapor Online!</h2>
<p>Kelola data rapor, nilai, dan deskripsi capaian dengan mudah melalui aplikasi ini.</p>
<p>Akses berbagai fitur untuk memperbarui nilai, melihat capaian kompetensi, dan mencetak rapor dengan cepat.</p>
<p>Gunakan menu di sebelah kiri untuk navigasi ke berbagai bagian aplikasi dan pantau perkembangan siswa secara real-time.</p>
<p>Semua data disinkronkan dengan Google Sheets, sehingga Anda bisa mengelola nilai dan laporan kapan saja, di mana saja.</p>
<!-- Nama dan Kontak di sebelah kanan bawah -->
<div style="position: absolute; bottom: 10px; right: 20px; font-size: 14px; color: #555; text-align: left;">
<p>Markus Paru</p>
<p>+6281338607300</p>
<p>markusparu54@guru.sd.belajar.id</p>
</div>
</div>
<script>
// Fungsi logout
function logout() {
localStorage.clear();
window.location.href = "login.html";
}
// Panggil saat halaman dimuat
window.onload = tampilkanNamaGuru;
</script>
</body>
</html>
<!-- guru.html -->
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Data Guru</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body class="bg-light">
<div class="container mt-4">
<h2 class="mb-4 text-primary">👩🏫 Data Guru</h2>
<table class="table table-bordered table-striped">
<thead class="table-primary">
<tr>
<th>ID</th>
<th>Username</th>
<th>Password</th>
<th>Nama</th>
<th>Jabatan</th>
<th>Email</th>
</tr>
</thead>
<tbody id="dataGuruBody">
<tr><td colspan="6">Memuat data...</td></tr>
</tbody>
</table>
</div>
<script>
// Ambil data guru dari Apps Script
google.script.run.withSuccessHandler(function(data) {
const tbody = document.getElementById('dataGuruBody');
tbody.innerHTML = ""; // Kosongkan
if (data.length === 0) {
tbody.innerHTML = "<tr><td colspan='6'>Tidak ada data ditemukan.</td></tr>";
return;
}
data.forEach(function(row) {
const tr = document.createElement("tr");
row.forEach(function(cell) {
const td = document.createElement("td");
td.textContent = cell;
tr.appendChild(td);
});
tbody.appendChild(tr);
});
}).getDataGuru(); // Fungsi dari .gs
</script>
</body>
</html>