// Tambah Pengunjung JavaScript document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('addVisitorForm'); const namaAnakInput = document.getElementById('namaAnak'); const scanStatusDiv = document.getElementById('scanStatus'); const kodeGelangInput = document.getElementById('kodeGelang'); const noHpOrtuInput = document.getElementById('noHpOrtu'); const durationSelect = document.getElementById('durasi'); const priceDisplay = document.getElementById('priceDisplay'); const errorMessage = document.getElementById('errorMessage'); const successMessage = document.getElementById('successMessage'); const submitBtn = document.getElementById('submitBtn'); const loadingSpinner = document.getElementById('loadingSpinner'); const btnText = document.getElementById('btnText'); const endSessionModal = document.getElementById('endSessionModal'); const endSessionBtn = document.getElementById('endSessionBtn'); const cancelEndBtn = document.getElementById('cancelEndBtn'); const currentUserInfo = document.getElementById('currentUserInfo'); const unknownRfidModal = document.getElementById('unknownRfidModal'); // Get the new modal from HTML const displayUnknownRfidCode = document.getElementById('displayUnknownRfidCode'); const closeUnknownRfidModalBtn = document.getElementById('closeUnknownRfidModalBtn'); // Price configuration const prices = { 30: 15000, // 30 menit 60: 25000, // 1 jam 90: 35000, // 1.5 jam 120: 45000, // 2 jam 180: 60000, // 3 jam 240: 75000 // 4 jam }; let currentKodeGelang = null; let isFormEnabled = false; let scanInterval = null; // Start scanning process function startScanning() { if (scanInterval) { clearInterval(scanInterval); } scanInterval = setInterval(async () => { try { const response = await fetch('../api/tambah_pengunjung.php?action=get_scanned_rfid'); const result = await response.json(); if (result.status === 'success' && result.data.scanned && result.data.kode_gelang) { // Stop scanning while processing clearInterval(scanInterval); scanInterval = null; // Check RFID status await handleRfidScan(result.data.kode_gelang); } } catch (error) { console.log('Background scan check failed:', error); } }, 2000); } // Handle RFID scan result async function handleRfidScan(kodeGelang) { try { const response = await fetch('../api/tambah_pengunjung.php?action=check_rfid'); const result = await response.json(); // Sembunyikan pesan sukses/error yang mungkin ada sebelumnya successMessage.style.display = 'none'; errorMessage.style.display = 'none'; if (result.status === 'available') { // Gelang tersedia - bisa digunakan kodeGelangInput.value = result.data.kode_gelang; kodeGelangInput.classList.add('success'); kodeGelangInput.classList.remove('error'); currentKodeGelang = result.data.kode_gelang; // Hide scan info const scanInfo = document.querySelector('.scan-info'); if (scanInfo) scanInfo.style.display = 'none'; // Enable form setFormEnabled(true); showSuccess('Gelang berhasil di-scan, silakan isi data pengunjung.'); // Tambahkan pesan sukses } else if (result.status === 'in_use') { // Gelang sedang digunakan - tampilkan modal setFormEnabled(false); // Nonaktifkan form utama kodeGelangInput.classList.remove('success'); kodeGelangInput.classList.add('error'); showEndSessionModal(result.data); // Ini akan mengatur currentKodeGelang } else if (result.status === 'error') { // Gelang tidak dikenali (termasuk "Belum ada gelang yang di-scan" jika rfid_temp kosong) setFormEnabled(false); // Nonaktifkan form utama kodeGelangInput.classList.remove('success'); kodeGelangInput.classList.add('error'); // Tentukan pesan dan modal yang tampil if (result.message === 'Gelang tidak dikenali') { showUnknownRfidModal(kodeGelang); // Tampilkan modal gelang tidak dikenali } else { // Ini akan menangani 'Belum ada gelang yang di-scan' atau error lain dari check_rfid showError(result.message || 'Terjadi kesalahan saat memeriksa gelang.'); } // Penting: Clear temp dan restart scanning setelah menampilkan modal error/unknown await clearRfidTemp(); setTimeout(() => { startScanning(); }, 1000); // Tunggu sebentar sebelum restart } } catch (error) { console.error('Error checking RFID:', error); showError('Error memeriksa status gelang: ' + error.message); // Tampilkan detail error // Clear temp dan restart scanning jika ada error koneksi await clearRfidTemp(); setTimeout(() => { startScanning(); }, 1000); } } // Format currency function formatCurrency(amount) { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0 }).format(amount); } // Format duration function formatDuration(minutes) { if (minutes < 60) { return `${minutes} menit`; } else { const hours = minutes / 60; return hours % 1 === 0 ? `${hours} jam` : `${hours} jam`; } } // Update price display function updatePriceDisplay() { const selectedDuration = durationSelect.value; if (selectedDuration) { const duration = parseInt(selectedDuration); const price = prices[duration]; const durationText = formatDuration(duration); const priceText = formatCurrency(price); priceDisplay.innerHTML = ` ${durationText}
${priceText} `; } else { priceDisplay.textContent = 'Pilih durasi untuk melihat harga'; } } // Enable/disable form function setFormEnabled(enabled) { isFormEnabled = enabled; submitBtn.disabled = !enabled || !currentKodeGelang; if (enabled) { namaAnakInput.focus(); } } // Show end session modal function showEndSessionModal(userData) { const nama = userData.nama; const kodeGelang = userData.kode_gelang; const sisaWaktu = userData.sisa_waktu; const statusWaktu = userData.status_waktu; const colorClass = userData.color_class; currentUserInfo.innerHTML = `

Nama: ${nama}

Kode Gelang: ${kodeGelang}

Sisa Waktu: ${sisaWaktu}

${statusWaktu === 'tersisa' ? 'Waktu masih tersisa' : 'Waktu sudah habis'}

`; endSessionModal.style.display = 'flex'; currentKodeGelang = kodeGelang; } // Hide end session modal function hideEndSessionModal() { endSessionModal.style.display = 'none'; currentKodeGelang = null; } // Show unknown RFID modal function showUnknownRfidModal(kodeGelang) { displayUnknownRfidCode.textContent = kodeGelang; unknownRfidModal.style.display = 'flex'; // currentKodeGelang = kodeGelang; // Bisa disimpan atau tidak, tergantung kebutuhan lebih lanjut } // Hide unknown RFID modal function hideUnknownRfidModal() { unknownRfidModal.style.display = 'none'; } // Clear RFID temp async function clearRfidTemp() { try { await fetch('../api/tambah_pengunjung.php?action=clear_temp', { method: 'POST' }); } catch (error) { console.error('Error clearing temp:', error); } } // End play session async function endPlaySession() { if (!currentKodeGelang) return; try { setLoading(true); const formData = new FormData(); formData.append('action', 'end_session'); formData.append('kode_gelang', currentKodeGelang); const response = await fetch('../api/tambah_pengunjung.php', { method: 'POST', body: formData }); const result = await response.json(); if (result.status === 'success') { showSuccess(result.message); hideEndSessionModal(); // Clear form and restart scanning resetForm(); setTimeout(() => { startScanning(); }, 2000); } else { showError(result.message); } } catch (error) { console.error('Error ending session:', error); showError('Error mengakhiri sesi permainan'); } finally { setLoading(false); } } // Reset form to initial state function resetForm() { form.reset(); // Reset all visual states document.querySelectorAll('.form-input, .form-select').forEach(field => { field.classList.remove('error', 'success'); }); // Reset kodeGelang input kodeGelangInput.value = ''; kodeGelangInput.classList.remove('error', 'success'); // Reset price display priceDisplay.textContent = 'Pilih durasi untuk melihat harga'; // Show scan info again const scanInfo = document.querySelector('.scan-info'); if (scanInfo) scanInfo.style.display = 'block'; // Reset form state setFormEnabled(false); currentKodeGelang = null; // Penting: Reset currentKodeGelang // NEW: Hide all modals and messages hideEndSessionModal(); hideUnknownRfidModal(); // Sembunyikan modal baru errorMessage.style.display = 'none'; successMessage.style.display = 'none'; } // Setup event listeners durationSelect.addEventListener('change', updatePriceDisplay); // Nama anak validation namaAnakInput.addEventListener('input', function() { const nama = this.value.trim(); if (nama.length >= 2) { this.classList.remove('error'); this.classList.add('success'); } else if (nama.length > 0) { this.classList.add('error'); this.classList.remove('success'); } else { this.classList.remove('error', 'success'); } }); // Phone number validation noHpOrtuInput.addEventListener('input', function() { let value = this.value.replace(/\D/g, ''); // Remove non-digits // Format phone number as user types if (value.startsWith('0')) { // Indonesian format starting with 0 if (value.length > 4) { value = value.substring(0, 4) + '-' + value.substring(4); } if (value.length > 9) { value = value.substring(0, 9) + '-' + value.substring(9); } } else if (value.startsWith('62')) { // Indonesian format starting with 62 if (value.length > 3) { value = value.substring(0, 3) + '-' + value.substring(3); } if (value.length > 8) { value = value.substring(0, 8) + '-' + value.substring(8); } } this.value = value; // Validation const cleanNumber = value.replace(/\D/g, ''); if (cleanNumber.length >= 10 && cleanNumber.length <= 15) { this.classList.remove('error'); this.classList.add('success'); } else if (cleanNumber.length > 0) { this.classList.add('error'); this.classList.remove('success'); } else { this.classList.remove('error', 'success'); } }); // Form validation function validateForm() { const namaAnak = namaAnakInput.value.trim(); const noHpOrtu = noHpOrtuInput.value.replace(/\D/g, ''); const selectedDuration = durationSelect.value; const kodeGelang = kodeGelangInput.value.trim(); let isValid = true; let errorMsg = ''; // Reset all field states document.querySelectorAll('.form-input, .form-select').forEach(field => { field.classList.remove('error'); }); // RFID validation first if (!kodeGelang) { isValid = false; errorMsg = 'Silakan scan gelang terlebih dahulu'; kodeGelangInput.classList.add('error'); return { isValid, errorMsg }; } // Nama anak validation if (namaAnak.length < 2) { isValid = false; errorMsg = 'Nama anak harus minimal 2 karakter'; namaAnakInput.classList.add('error'); } // Phone number validation if (noHpOrtu.length < 10 || noHpOrtu.length > 15) { isValid = false; errorMsg = 'Nomor HP harus 10-15 digit'; noHpOrtuInput.classList.add('error'); } // Duration validation if (!selectedDuration) { isValid = false; errorMsg = 'Silakan pilih durasi bermain'; durationSelect.classList.add('error'); } return { isValid, errorMsg }; } // Show error message function showError(message) { errorMessage.textContent = message; errorMessage.style.display = 'block'; successMessage.style.display = 'none'; // Scroll to top to show error document.querySelector('.login-right').scrollTop = 0; setTimeout(() => { errorMessage.style.display = 'none'; }, 5000); } // Show success message function showSuccess(message) { successMessage.textContent = message; successMessage.style.display = 'block'; errorMessage.style.display = 'none'; // Scroll to top to show success document.querySelector('.login-right').scrollTop = 0; setTimeout(() => { successMessage.style.display = 'none'; }, 3000); } // Set loading state function setLoading(loading) { if (loading) { submitBtn.disabled = true; loadingSpinner.style.display = 'inline-block'; btnText.textContent = 'Mendaftarkan...'; } else { // Tombol daftar harus tetap disabled jika form tidak enabled atau kode gelang belum valid submitBtn.disabled = !isFormEnabled || !currentKodeGelang; loadingSpinner.style.display = 'none'; btnText.textContent = 'Daftarkan Pengunjung'; } } // Form submission form.addEventListener('submit', async function(e) { e.preventDefault(); const validation = validateForm(); if (!validation.isValid) { showError(validation.errorMsg); return; } setLoading(true); // Prepare form data const formData = new FormData(); formData.append('action', 'add_visitor'); formData.append('kodeGelang', currentKodeGelang); formData.append('namaAnak', namaAnakInput.value.trim()); formData.append('noHpOrtu', noHpOrtuInput.value.replace(/\D/g, '')); formData.append('durasi', parseInt(durationSelect.value)); try { const response = await fetch('../api/tambah_pengunjung.php', { method: 'POST', body: formData }); // Check if response is ok if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const contentType = response.headers.get('content-type'); if (!contentType || !contentType.includes('application/json')) { const text = await response.text(); console.error('Non-JSON response:', text); throw new Error('Server returned non-JSON response'); } const result = await response.json(); if (result.status === 'success') { showSuccess(result.message); // Stop scanning if (scanInterval) { clearInterval(scanInterval); scanInterval = null; } // Redirect after 2 seconds setTimeout(() => { window.location.href = 'dashboard.html'; }, 2000); } else { showError(result.message || 'Terjadi kesalahan saat mendaftarkan pengunjung'); // Handle specific field errors if (result.field === 'namaAnak') { namaAnakInput.classList.add('error'); namaAnakInput.focus(); } else if (result.field === 'noHpOrtu') { noHpOrtuInput.classList.add('error'); noHpOrtuInput.focus(); } else if (result.field === 'durasi') { durationSelect.classList.add('error'); durationSelect.focus(); } } } catch (error) { console.error('Error:', error); showError('Terjadi kesalahan koneksi. Silakan coba lagi.'); } finally { setLoading(false); } }); // End session modal handlers endSessionBtn.addEventListener('click', endPlaySession); cancelEndBtn.addEventListener('click', function() { hideEndSessionModal(); // Clear temp and start new scanning clearRfidTemp().then(() => { setTimeout(() => { startScanning(); }, 500); }); }); // Close modal when clicking outside endSessionModal.addEventListener('click', function(e) { if (e.target === endSessionModal) { hideEndSessionModal(); // Clear temp and start new scanning clearRfidTemp().then(() => { setTimeout(() => { startScanning(); }, 500); }); } }); // Close unknown RFID modal handlers closeUnknownRfidModalBtn.addEventListener('click', function() { hideUnknownRfidModal(); // Clear temp dan restart scanning setelah modal ditutup clearRfidTemp().then(() => { setTimeout(() => { startScanning(); }, 500); }); }); // Close unknown RFID modal when clicking outside unknownRfidModal.addEventListener('click', function(e) { if (e.target === unknownRfidModal) { hideUnknownRfidModal(); // Clear temp dan restart scanning setelah modal ditutup clearRfidTemp().then(() => { setTimeout(() => { startScanning(); }, 500); }); } }); // Clear temp when page is about to unload window.addEventListener('beforeunload', function() { if (scanInterval) { clearInterval(scanInterval); } // Clear temp data navigator.sendBeacon('../api/tambah_pengunjung.php?action=clear_temp'); }); // Clear temp when page loses focus window.addEventListener('blur', function() { clearRfidTemp(); }); // Check authentication status async function checkAuth() { try { const response = await fetch('../api/dashboard.php'); const result = await response.json(); if (result.status === 'error' && result.redirect) { window.location.href = result.redirect; } } catch (error) { console.error('Auth check failed:', error); } } // Initialize page checkAuth(); resetForm(); // Panggil resetForm untuk mengatur UI ke keadaan awal startScanning(); // Kemudian baru mulai scanning updatePriceDisplay(); // Pastikan harga tampil jika ada default selected });