<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Absensi SMK Pervekt Jawa Timur</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.gradient-bg {
background: linear-gradient(135deg, #000066 0%, #ff0066 50%, #660000 100%);
}
.card-shadow {
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
}
.pulse-animation {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
.sidebar-item {
transition: all 0.3s ease;
}
.sidebar-item:hover {
background-color: rgba(255, 255, 255, 0.1);
transform: translateX(5px);
}
.sidebar-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid #fbbf24;
}
@keyframes marquee {
0% { transform: translateX(100%); }
100% { transform: translateX(-100%); }
}
.animate-marquee {
animation: marquee 20s linear infinite;
}
.popup-overlay {
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
}
.popup-content {
background: linear-gradient(135deg, #000066 0%, #ff0066 50%, #660000 100%);
animation: popupSlide 0.3s ease-out;
}
@keyframes popupSlide {
from {
opacity: 0;
transform: scale(0.8) translateY(-20px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
</style>
</head>
<body class="gradient-bg min-h-screen">
<!-- Login Page -->
<div id="login-page" class="fixed inset-0 z-50 flex items-center justify-center" style="background-image: url('https://freeimghost.net/images/2025/08/19/sekolah1.jpg'); background-size: cover; background-position: center;">
<div class="absolute inset-0 bg-black bg-opacity-50"></div>
<div class="relative bg-white rounded-xl card-shadow p-8 w-full max-w-md mx-4">
<div class="text-center mb-8">
<img src="https://freeimghost.net/images/2025/08/19/Logo-pervekt1.png" alt="Logo SMK Pervekt" class="w-20 h-20 mx-auto mb-4 rounded-lg" onerror="this.style.display='none';">
<h1 class="text-2xl font-bold text-gray-800">SMK Pervekt</h1>
<p class="text-gray-600">Sistem Absensi Online</p>
</div>
<form id="login-form" class="space-y-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Username:</label>
<input type="text" id="username" required
class="w-full px-4 py-3 border-2 border-pink-500 rounded-lg focus:ring-2 focus:ring-pink-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Password:</label>
<input type="password" id="password" required
class="w-full px-4 py-3 border-2 border-pink-500 rounded-lg focus:ring-2 focus:ring-pink-500 focus:border-transparent">
</div>
<button type="submit" class="w-full py-3 px-4 rounded-lg text-white font-bold transition duration-200 transform hover:scale-105" style="background: linear-gradient(135deg, #000066 0%, #ff0066 50%, #660000 100%);">
🔐 Masuk
</button>
</form>
<div id="login-error" class="hidden mt-4 p-3 bg-red-100 border border-red-400 text-red-700 rounded-lg text-sm text-center">
Username atau password salah!
</div>
</div>
</div>
<!-- Running Text -->
<div class="bg-pink-500 text-white py-2 overflow-hidden">
<div class="whitespace-nowrap animate-marquee">
<span class="text-lg font-bold">🎓 Daftar Hadir - SMK Percontohan Pervekt Jawa Timur 🎓 Sistem Absensi Online Terpadu 🎓 Selamat Datang di Portal Akademik 🎓</span>
</div>
</div>
<div id="main-app" class="flex h-screen hidden">
<!-- Sidebar -->
<div class="w-64 bg-gray-800 text-white flex flex-col">
<!-- Header -->
<div class="p-6 border-b border-gray-700">
<div class="flex items-center mb-3">
<img src="https://freeimghost.net/images/2025/08/19/Logo-pervekt1.png" alt="Logo SMK Pervekt" class="w-12 h-12 mr-3 rounded-lg" onerror="this.style.display='none';">
<div>
<h1 class="text-xl font-bold">SMK Pervekt</h1>
<p class="text-sm text-gray-300">Jawa Timur</p>
</div>
</div>
</div>
<!-- Navigation -->
<nav class="flex-1 p-4">
<ul class="space-y-2">
<li>
<button onclick="showSection('absensi')" class="sidebar-item active w-full text-left px-4 py-3 rounded-lg flex items-center" id="nav-absensi">
<span class="mr-3">✏️</span>
<span>Absensi</span>
</button>
</li>
<li>
<button onclick="showSection('data-murid')" class="sidebar-item w-full text-left px-4 py-3 rounded-lg flex items-center" id="nav-data-murid">
<span class="mr-3">👨🎓</span>
<span>Data Murid</span>
</button>
</li>
<li>
<button onclick="showSection('data-guru')" class="sidebar-item w-full text-left px-4 py-3 rounded-lg flex items-center" id="nav-data-guru">
<span class="mr-3">👨🏫</span>
<span>Data Guru</span>
</button>
</li>
</ul>
</nav>
<!-- Footer -->
<div class="p-4 border-t border-gray-700">
<div class="bg-green-600 text-green-100 px-3 py-2 rounded text-sm text-center">
🚀 Sistem Aktif
</div>
</div>
</div>
<!-- Main Content -->
<div class="flex-1 overflow-auto">
<!-- Absensi Section -->
<div id="section-absensi" class="p-8">
<div class="max-w-6xl mx-auto">
<div class="mb-8">
<h2 class="text-3xl font-bold text-white mb-2">✏️ Form Absensi</h2>
<p class="text-blue-100">Sistem absensi online SMK Percontohan Pervekt Jawa Timur</p>
</div>
<div class="grid lg:grid-cols-2 gap-8">
<!-- Form Absensi -->
<div class="bg-white rounded-xl card-shadow p-6">
<h3 class="text-2xl font-bold text-gray-800 mb-6">📝 Input Absensi</h3>
<!-- Clock -->
<div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6 rounded">
<div class="flex items-center">
<span class="text-blue-600 mr-2">⏰</span>
<div>
<p class="text-sm text-blue-600 font-medium">Waktu Indonesia Timur (WIT)</p>
<p id="clock-wit" class="text-lg font-bold text-blue-800 pulse-animation">Memuat waktu...</p>
</div>
</div>
</div>
<form id="form-absensi" class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Kelas:</label>
<select name="kelas" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<option value="Kelas 10">Kelas 10</option>
<option value="Kelas 11">Kelas 11</option>
<option value="Kelas 12">Kelas 12</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">NIS:</label>
<input type="text" name="nis" placeholder="Masukkan NIS murid" required
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Nama Murid:</label>
<input type="text" name="namamurid" placeholder="Masukkan nama murid" required
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Tanggal:</label>
<input type="date" name="tanggal" required
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Keterangan:</label>
<select name="keterangan" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<option value="Hadir">✅ Hadir</option>
<option value="Sakit">🤒 Sakit</option>
<option value="Izin">📝 Izin</option>
<option value="Alpa">❌ Alpa</option>
</select>
</div>
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg border-2 border-pink-500 transition duration-200 transform hover:scale-105">
📤 Kirim Absensi
</button>
</form>
<!-- Success Message -->
<div id="success-message" class="hidden mt-4"></div>
</div>
<!-- Riwayat Absensi -->
<div class="bg-white rounded-xl card-shadow p-6">
<div class="flex justify-between items-center mb-6">
<h3 class="text-2xl font-bold text-gray-800">📊 Riwayat Absensi</h3>
<button id="clear-data" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg border-2 border-pink-500 text-sm font-medium transition duration-200">
🗑️ Hapus Semua
</button>
</div>
<div id="attendance-list" class="space-y-3 max-h-96 overflow-y-auto">
<div class="text-center text-gray-500 py-8">
<p class="text-lg">📝 Belum ada data absensi</p>
<p class="text-sm">Isi form untuk mulai mencatat absensi</p>
</div>
</div>
<!-- Statistics -->
<div id="stats" class="hidden mt-6 grid grid-cols-2 gap-4">
<div class="bg-green-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-green-600" id="hadir-count">0</div>
<div class="text-sm text-green-700">Hadir</div>
</div>
<div class="bg-red-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-red-600" id="absent-count">0</div>
<div class="text-sm text-red-700">Tidak Hadir</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Data Murid Section -->
<div id="section-data-murid" class="p-8 hidden">
<div class="max-w-6xl mx-auto">
<div class="mb-8">
<h2 class="text-3xl font-bold text-white mb-2">👨🎓 Data Murid</h2>
<p class="text-blue-100">Daftar lengkap murid SMK Percontohan Pervekt Jawa Timur</p>
</div>
<div class="bg-white rounded-xl card-shadow p-6">
<div class="flex justify-between items-center mb-6">
<h3 class="text-2xl font-bold text-gray-800">📋 Daftar Murid</h3>
<div class="flex items-center space-x-4">
<input type="text" id="search-murid" placeholder="Cari nama atau NIS..."
class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<button onclick="loadDataMurid()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg border-2 border-pink-500 font-medium">
🔄 Refresh
</button>
</div>
</div>
<div id="loading-murid" class="text-center py-8">
<div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<p class="mt-2 text-gray-600">Memuat data murid...</p>
</div>
<div id="murid-table" class="hidden overflow-x-auto">
<table class="w-full table-auto">
<thead>
<tr class="bg-gray-50">
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">No</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">NIS</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">NISN</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Nama Murid</th>
</tr>
</thead>
<tbody id="murid-tbody" class="divide-y divide-gray-200">
</tbody>
</table>
</div>
<div id="murid-stats" class="hidden mt-6 grid grid-cols-3 gap-4">
<div class="bg-blue-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-blue-600" id="total-murid">0</div>
<div class="text-sm text-blue-700">Total Murid</div>
</div>
<div class="bg-green-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-green-600" id="kelas-10">0</div>
<div class="text-sm text-green-700">Dengan NIS</div>
</div>
<div class="bg-purple-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-purple-600" id="kelas-11-12">0</div>
<div class="text-sm text-purple-700">Dengan NISN</div>
</div>
</div>
</div>
</div>
</div>
<!-- Data Guru Section -->
<div id="section-data-guru" class="p-8 hidden">
<div class="max-w-6xl mx-auto">
<div class="mb-8">
<h2 class="text-3xl font-bold text-white mb-2">👨🏫 Data Guru</h2>
<p class="text-blue-100">Daftar lengkap guru SMK Percontohan Pervekt Jawa Timur</p>
</div>
<div class="bg-white rounded-xl card-shadow p-6">
<div class="flex justify-between items-center mb-6">
<h3 class="text-2xl font-bold text-gray-800">📋 Daftar Guru</h3>
<div class="flex items-center space-x-4">
<input type="text" id="search-guru" placeholder="Cari nama, NIP, atau jabatan..."
class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<button onclick="loadDataGuru()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg border-2 border-pink-500 font-medium">
🔄 Refresh
</button>
</div>
</div>
<div id="loading-guru" class="text-center py-8">
<div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<p class="mt-2 text-gray-600">Memuat data guru...</p>
</div>
<div id="guru-table" class="hidden overflow-x-auto">
<table class="w-full table-auto">
<thead>
<tr class="bg-gray-50">
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">No</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Nama Guru</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">NIP</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Jabatan</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Nomor WA</th>
</tr>
</thead>
<tbody id="guru-tbody" class="divide-y divide-gray-200">
</tbody>
</table>
</div>
<div id="guru-stats" class="hidden mt-6 grid grid-cols-2 gap-4">
<div class="bg-blue-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-blue-600" id="total-guru">0</div>
<div class="text-sm text-blue-700">Total Guru</div>
</div>
<div class="bg-green-50 p-4 rounded-lg text-center">
<div class="text-2xl font-bold text-green-600" id="mata-pelajaran">0</div>
<div class="text-sm text-green-700">Dengan NIP</div>
</div>
</div>
<!-- Teacher Profile Cards -->
<div id="guru-profiles" class="hidden mt-8">
<h4 class="text-xl font-bold text-gray-800 mb-6">👥 Profil Guru</h4>
<div id="guru-profile-grid" class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Profile cards will be inserted here -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Success Popup -->
<div id="success-popup" class="fixed inset-0 z-50 flex items-center justify-center popup-overlay hidden">
<div class="popup-content rounded-xl p-8 max-w-md mx-4 text-center text-white">
<div class="mb-6">
<div class="w-20 h-20 bg-white bg-opacity-20 rounded-full flex items-center justify-center mx-auto mb-4">
<span class="text-4xl">✅</span>
</div>
<h3 class="text-2xl font-bold mb-2">Berhasil!</h3>
<p class="text-lg">Daftar hadir telah dikirim</p>
</div>
<button onclick="closeSuccessPopup()" class="bg-white bg-opacity-20 hover:bg-opacity-30 text-white px-6 py-2 rounded-lg font-medium transition duration-200">
Tutup
</button>
</div>
</div>
<!-- Footer -->
<footer class="bg-gray-800 text-white py-4 text-center">
<p class="text-sm">© 2025 SMK Percontohan Pervekt Jawa Timur - Hak Cipta Dilindungi</p>
</footer>
<script>
// Global variables
let muridData = [];
let guruData = [];
const clockEl = document.getElementById("clock-wit");
const form = document.getElementById("form-absensi");
const successMessage = document.getElementById("success-message");
const attendanceList = document.getElementById("attendance-list");
const clearDataBtn = document.getElementById("clear-data");
const statsEl = document.getElementById("stats");
const hadirCountEl = document.getElementById("hadir-count");
const absentCountEl = document.getElementById("absent-count");
// Set today's date as default
document.querySelector('input[name="tanggal"]').value = new Date().toISOString().split('T')[0];
// Update clock for WIT (UTC+9)
function updateClockWIT() {
const now = new Date();
const witTime = new Date(now.getTime() + (9 * 60 * 60 * 1000));
const formatter = new Intl.DateTimeFormat("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false
});
clockEl.textContent = formatter.format(witTime);
}
setInterval(updateClockWIT, 1000);
updateClockWIT();
// Navigation functions
function showSection(sectionName) {
// Hide all sections
document.querySelectorAll('[id^="section-"]').forEach(section => {
section.classList.add('hidden');
});
// Remove active class from all nav items
document.querySelectorAll('.sidebar-item').forEach(item => {
item.classList.remove('active');
});
// Show selected section
document.getElementById(`section-${sectionName}`).classList.remove('hidden');
document.getElementById(`nav-${sectionName}`).classList.add('active');
// Load data if needed
if (sectionName === 'data-murid' && muridData.length === 0) {
loadDataMurid();
} else if (sectionName === 'data-guru' && guruData.length === 0) {
loadDataGuru();
}
}
// Load data murid from Google Sheets
async function loadDataMurid() {
const loadingEl = document.getElementById('loading-murid');
const tableEl = document.getElementById('murid-table');
const statsEl = document.getElementById('murid-stats');
loadingEl.classList.remove('hidden');
tableEl.classList.add('hidden');
statsEl.classList.add('hidden');
try {
const response = await fetch('https://docs.google.com/spreadsheets/d/e/2PACX-1vSYDuI2iERadVoehPHnsLlcxb612aSTrGhWHQziUsZplm6PGH_ypzihbMRcvsiOL5Lf9p0GXgGqbAXW/pub?output=csv');
const csvText = await response.text();
// Parse CSV
const lines = csvText.split('\n');
const headers = lines[0].split(',');
muridData = [];
for (let i = 1; i < lines.length; i++) {
if (lines[i].trim()) {
const values = lines[i].split(',');
muridData.push({
no: values[0]?.trim() || '',
nis: values[1]?.trim() || '',
nisn: values[2]?.trim() || '',
nama: values[3]?.trim() || ''
});
}
}
displayMuridData(muridData);
updateMuridStats(muridData);
} catch (error) {
console.error('Error loading murid data:', error);
loadingEl.innerHTML = `
<div class="text-center py-8 text-red-600">
<p>❌ Gagal memuat data murid</p>
<p class="text-sm">Periksa koneksi internet Anda</p>
</div>
`;
}
}
function displayMuridData(data) {
const tbody = document.getElementById('murid-tbody');
const loadingEl = document.getElementById('loading-murid');
const tableEl = document.getElementById('murid-table');
tbody.innerHTML = data.map((murid, index) => `
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm text-gray-900">${murid.no}</td>
<td class="px-4 py-3 text-sm font-medium text-gray-900">${murid.nis}</td>
<td class="px-4 py-3 text-sm text-gray-900">${murid.nisn}</td>
<td class="px-4 py-3 text-sm text-gray-900">${murid.nama}</td>
</tr>
`).join('');
loadingEl.classList.add('hidden');
tableEl.classList.remove('hidden');
}
function updateMuridStats(data) {
const totalMurid = data.length;
const withNIS = data.filter(m => m.nis && m.nis.trim() !== '').length;
const withNISN = data.filter(m => m.nisn && m.nisn.trim() !== '').length;
document.getElementById('total-murid').textContent = totalMurid;
document.getElementById('kelas-10').textContent = withNIS;
document.getElementById('kelas-11-12').textContent = withNISN;
document.getElementById('murid-stats').classList.remove('hidden');
}
// Load data guru from Google Sheets
async function loadDataGuru() {
const loadingEl = document.getElementById('loading-guru');
const tableEl = document.getElementById('guru-table');
const statsEl = document.getElementById('guru-stats');
loadingEl.classList.remove('hidden');
tableEl.classList.add('hidden');
statsEl.classList.add('hidden');
try {
const response = await fetch('https://docs.google.com/spreadsheets/d/e/2PACX-1vT-RTmCcIYrOlxFIsaLNLmOyEodVNK3HFzyxaur_n8JEM1Gn4BJgZOmVwBE64PpuAEtX4iGW5eqiPei/pub?output=csv');
const csvText = await response.text();
// Parse CSV
const lines = csvText.split('\n');
const headers = lines[0].split(',');
guruData = [];
for (let i = 1; i < lines.length; i++) {
if (lines[i].trim()) {
const values = lines[i].split(',');
guruData.push({
no: values[0]?.trim() || '',
nama: values[1]?.trim() || '',
nip: values[2]?.trim() || '',
jabatan: values[3]?.trim() || '',
foto: values[4]?.trim() || '',
nomorWA: values[5]?.trim() || '',
email: values[6]?.trim() || ''
});
}
}
displayGuruData(guruData);
updateGuruStats(guruData);
displayGuruProfiles(guruData);
} catch (error) {
console.error('Error loading guru data:', error);
loadingEl.innerHTML = `
<div class="text-center py-8 text-red-600">
<p>❌ Gagal memuat data guru</p>
<p class="text-sm">Periksa koneksi internet Anda</p>
</div>
`;
}
}
function displayGuruData(data) {
const tbody = document.getElementById('guru-tbody');
const loadingEl = document.getElementById('loading-guru');
const tableEl = document.getElementById('guru-table');
tbody.innerHTML = data.map((guru, index) => `
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm text-gray-900">${guru.no}</td>
<td class="px-4 py-3 text-sm font-medium text-gray-900">${guru.nama}</td>
<td class="px-4 py-3 text-sm text-gray-900">${guru.nip}</td>
<td class="px-4 py-3 text-sm text-gray-900">${guru.jabatan}</td>
<td class="px-4 py-3 text-sm text-blue-600">
${guru.nomorWA ? `<a href="https://wa.me/${guru.nomorWA.replace(/\D/g, '')}" target="_blank" class="hover:underline">📱 ${guru.nomorWA}</a>` : '-'}
</td>
</tr>
`).join('');
loadingEl.classList.add('hidden');
tableEl.classList.remove('hidden');
}
function updateGuruStats(data) {
const totalGuru = data.length;
const withNIP = data.filter(g => g.nip && g.nip.trim() !== '').length;
document.getElementById('total-guru').textContent = totalGuru;
document.getElementById('mata-pelajaran').textContent = withNIP;
document.getElementById('guru-stats').classList.remove('hidden');
}
function displayGuruProfiles(data) {
const profileGrid = document.getElementById('guru-profile-grid');
const profilesSection = document.getElementById('guru-profiles');
profileGrid.innerHTML = data.map((guru, index) => `
<div class="bg-white rounded-xl card-shadow p-6 hover:shadow-lg transition-shadow duration-300">
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<img src="${guru.foto || 'https://via.placeholder.com/80x80/e5e7eb/6b7280?text=👤'}"
alt="Foto ${guru.nama}"
class="w-20 h-20 rounded-full object-cover border-2 border-gray-200"
onerror="this.src='https://via.placeholder.com/80x80/e5e7eb/6b7280?text=👤';">
</div>
<div class="flex-1 min-w-0">
<h5 class="text-lg font-bold text-gray-900 mb-2">${guru.nama}</h5>
<div class="space-y-1 text-sm text-gray-600">
<p><span class="font-medium">NIP:</span> ${guru.nip || '-'}</p>
<p><span class="font-medium">Jabatan:</span> ${guru.jabatan || '-'}</p>
<p><span class="font-medium">Telepon:</span>
${guru.nomorWA ? `<a href="https://wa.me/${guru.nomorWA.replace(/\D/g, '')}" target="_blank" class="text-blue-600 hover:underline">📱 ${guru.nomorWA}</a>` : '-'}
</p>
<p><span class="font-medium">Email:</span>
${guru.email ? `<a href="mailto:${guru.email}" class="text-blue-600 hover:underline">📧 ${guru.email}</a>` : '-'}
</p>
</div>
</div>
</div>
</div>
`).join('');
profilesSection.classList.remove('hidden');
}
// Search functionality
document.getElementById('search-murid').addEventListener('input', function(e) {
const searchTerm = e.target.value.toLowerCase();
const filteredData = muridData.filter(murid =>
murid.nama.toLowerCase().includes(searchTerm) ||
murid.nis.toLowerCase().includes(searchTerm)
);
displayMuridData(filteredData);
});
document.getElementById('search-guru').addEventListener('input', function(e) {
const searchTerm = e.target.value.toLowerCase();
const filteredData = guruData.filter(guru =>
guru.nama.toLowerCase().includes(searchTerm) ||
guru.nip.toLowerCase().includes(searchTerm) ||
guru.jabatan.toLowerCase().includes(searchTerm)
);
displayGuruData(filteredData);
});
// Attendance functions (same as before)
function loadAttendanceData() {
const data = JSON.parse(localStorage.getItem('attendanceData') || '[]');
displayAttendanceData(data);
updateStats(data);
}
function displayAttendanceData(data) {
if (data.length === 0) {
attendanceList.innerHTML = `
<div class="text-center text-gray-500 py-8">
<p class="text-lg">📝 Belum ada data absensi</p>
<p class="text-sm">Isi form untuk mulai mencatat absensi</p>
</div>
`;
statsEl.classList.add('hidden');
return;
}
statsEl.classList.remove('hidden');
attendanceList.innerHTML = data.map((entry, index) => {
const statusIcon = {
'Hadir': '✅',
'Sakit': '🤒',
'Izin': '📝',
'Alpa': '❌'
};
const statusColor = {
'Hadir': 'bg-green-50 border-green-200',
'Sakit': 'bg-yellow-50 border-yellow-200',
'Izin': 'bg-blue-50 border-blue-200',
'Alpa': 'bg-red-50 border-red-200'
};
return `
<div class="border rounded-lg p-4 ${statusColor[entry.keterangan]}">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center mb-2">
<span class="text-lg mr-2">${statusIcon[entry.keterangan]}</span>
<span class="font-bold text-gray-800">${entry.namamurid}</span>
</div>
<div class="text-sm text-gray-600 space-y-1">
<p><span class="font-medium">NIS:</span> ${entry.nis}</p>
<p><span class="font-medium">Kelas:</span> ${entry.kelas}</p>
<p><span class="font-medium">Tanggal:</span> ${entry.tanggal}</p>
<p><span class="font-medium">Status:</span> ${entry.keterangan}</p>
<p><span class="font-medium">Waktu:</span> ${entry.waktupengiriman}</p>
</div>
</div>
<button onclick="deleteEntry(${index})" class="text-red-500 hover:text-red-700 ml-4">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</button>
</div>
</div>
`;
}).join('');
}
function updateStats(data) {
const hadirCount = data.filter(entry => entry.keterangan === 'Hadir').length;
const absentCount = data.length - hadirCount;
hadirCountEl.textContent = hadirCount;
absentCountEl.textContent = absentCount;
}
// Handle form submission
form.addEventListener("submit", async function(e) {
e.preventDefault();
const submitBtn = form.querySelector('button[type="submit"]');
const originalText = submitBtn.innerHTML;
submitBtn.disabled = true;
submitBtn.innerHTML = '⏳ Mengirim...';
const formData = new FormData(form);
const now = new Date();
const witTime = new Date(now.getTime() + (9 * 60 * 60 * 1000));
const formattedTime = new Intl.DateTimeFormat("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false
}).format(witTime);
const entry = {
kelas: formData.get('kelas'),
nis: formData.get('nis'),
namamurid: formData.get('namamurid'),
tanggal: formData.get('tanggal'),
keterangan: formData.get('keterangan'),
waktupengiriman: formattedTime
};
try {
const scriptFormData = new FormData();
Object.keys(entry).forEach(key => {
scriptFormData.append(key, entry[key]);
});
const response = await fetch('https://script.google.com/macros/s/AKfycbyQ8NobWDeZcDOzpbJaUHj9Sn7QQUsrKzyUZzztKl1OLhsFyLLDxO1lSlGfhdI27JSj/exec', {
method: 'POST',
body: scriptFormData
});
if (response.ok) {
const existingData = JSON.parse(localStorage.getItem('attendanceData') || '[]');
existingData.unshift(entry);
localStorage.setItem('attendanceData', JSON.stringify(existingData));
showSuccessPopup();
form.reset();
document.querySelector('input[name="tanggal"]').value = new Date().toISOString().split('T')[0];
loadAttendanceData();
} else {
throw new Error('Server response not OK');
}
} catch (error) {
console.error('Error sending to Google Apps Script:', error);
const existingData = JSON.parse(localStorage.getItem('attendanceData') || '[]');
existingData.unshift(entry);
localStorage.setItem('attendanceData', JSON.stringify(existingData));
showSuccessPopup();
form.reset();
document.querySelector('input[name="tanggal"]').value = new Date().toISOString().split('T')[0];
loadAttendanceData();
} finally {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
}
});
function deleteEntry(index) {
if (confirm('Yakin ingin menghapus data absensi ini?')) {
const data = JSON.parse(localStorage.getItem('attendanceData') || '[]');
data.splice(index, 1);
localStorage.setItem('attendanceData', JSON.stringify(data));
loadAttendanceData();
}
}
clearDataBtn.addEventListener('click', function() {
if (confirm('Yakin ingin menghapus SEMUA data absensi? Tindakan ini tidak dapat dibatalkan.')) {
localStorage.removeItem('attendanceData');
loadAttendanceData();
}
});
// Login functionality
document.getElementById('login-form').addEventListener('submit', function(e) {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const errorEl = document.getElementById('login-error');
if (username === 'admin' && password === 'admin1') {
document.getElementById('login-page').classList.add('hidden');
document.getElementById('main-app').classList.remove('hidden');
loadAttendanceData();
} else {
errorEl.classList.remove('hidden');
setTimeout(() => {
errorEl.classList.add('hidden');
}, 3000);
}
});
// Success popup functions
function showSuccessPopup() {
document.getElementById('success-popup').classList.remove('hidden');
}
function closeSuccessPopup() {
document.getElementById('success-popup').classList.add('hidden');
}
// Make functions global
window.showSuccessPopup = showSuccessPopup;
window.closeSuccessPopup = closeSuccessPopup;
</script>
<script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'971f1e4d00618ce5',t:'MTc1NTY2MzgzOC4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>
</html>