eba ikuntuk emba l itu <!DOCTYPE html><html lang="id"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Aplikasi Penjualan Tiket Wisata</title> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"> <style> body { font-family: 'Roboto', sans-serif; margin: 0; padding: 0; background-color: #f3f4f6; display: flex; justify-content: center; align-items: center; min-height: 100vh; transition: background-color 0.5s ease; } body.dark-mode { background-color: #1a202c; } #app { background-color: #fff; border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); width: 95%; max-width: 800px; padding: 20px; transition: background-color 0.5s ease; display: flex; flex-direction: column; min-height: 90vh; box-sizing: border-box; } #app.dark-mode { background-color: #2d3748; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2); } header { text-align: center; margin-bottom: 20px; transition: color 0.5s ease; } header.dark-mode { color: #f7fafc; } h1{ color: #008000; } #input-section { margin-bottom: 20px; transition: color 0.5s ease; } #input-section.dark-mode { color: #f7fafc; } .input-group { margin-bottom: 15px; display: flex; flex-direction: column; } .input-group label { display: block; margin-bottom: 5px; color: #4a5568; transition: color 0.5s ease; } .input-group.dark-mode label { color: #cbd5e0; } .input-group input { width: 100%; padding: 10px; border: 1px solid #e2e8f0; border-radius: 6px; transition: border-color 0.3s ease, background-color 0.5s ease, color 0.5s ease; box-sizing: border-box; } .input-group input.dark-mode { background-color: #4a5568; border-color: #718096; color: #f7fafc; } .input-group input:focus { outline: none; border-color: #3182ce; box-shadow: 0 0 0 3px rgba(49, 130, 206, 0.1); } .button { padding: 10px 20px; border: none; border-radius: 6px; background-color: #008000; color: white; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease; font-weight: 500; width: 100%; box-sizing: border-box; } .button:hover { background-color: #005000; transform: translateY(-2px); } #ticket-section { margin-top: 20px; text-align: center; transition: color 0.5s ease; display: none; } #ticket-section.dark-mode { color: #f7fafc; } #ticket-section h3{ transition: color 0.5s ease; } #ticket-section.dark-mode h3{ color: #f7fafc; } #qrcode-container { margin-top: 10px; text-align: center; transition: background-color 0.5s ease; } #qrcode-container.dark-mode { background-color: #4a5568; } #print-button { padding: 10px 20px; border: none; border-radius: 6px; background-color: #008000; color: white; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease; font-weight: 500; width: 100%; box-sizing: border-box; margin-top: 20px; } #print-button:hover { background-color: #005000; transform: translateY(-2px); } #error-modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.5); transition: background-color 0.5s ease; } #error-modal.dark-mode { background-color: rgba(0,0,0,0.7); } .modal-content { background-color: #fff; margin: 10% auto; padding: 20px; border-radius: 12px; border: 1px solid #e2e8f0; width: 90%; max-width: 500px; position: relative; transition: background-color 0.5s ease; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); } .modal-content.dark-mode { background-color: #2d3748; border-color: #718096; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2); } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid #e2e8f0; transition: border-color 0.3s ease, color 0.5s ease; } .modal-header.dark-mode { border-color: #718096; color: #f7fafc; } .modal-header h2 { margin: 0; font-size: 20px; transition: color 0.5s ease; } .modal-header.dark-mode h2 { color: #f7fafc; } .close-button { position: absolute; top: 10px; right: 10px; color: #a0aec0; font-size: 24px; font-weight: bold; cursor: pointer; border: none; background: none; padding: 0; transition: color 0.3s ease; } .close-button:hover { color: #718096; } .modal-body { margin-bottom: 20px; transition: color 0.5s ease; } .modal-body.dark-mode{ color: #f7fafc; } .modal-body p{ transition: color 0.5s ease; } .modal-body.dark-mode p{ color: #f7fafc; } .modal-footer { text-align: right; transition: color 0.5s ease; } .modal-footer.dark-mode { color: #f7fafc; } @media print { body { background-color: #fff; } #app { box-shadow: none; padding: 0; } #ticket-section { display: block !important; border: none; padding: 0; } #print-button { display: none; } } .toggle-container { display: flex; align-items: center; margin-left: auto; margin-bottom: 20px; }
.toggle-label { margin-right: 10px; color: #4a5568; font-size: 1rem; transition: color 0.5s ease; } .toggle-label.dark-mode { color: #cbd5e0; }
.switch { position: relative; display: inline-block; width: 48px; height: 24px; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: .4s; transition: .4s; border-radius: 24px; }
.slider:before { position: absolute; content: ""; height: 16px; width: 16px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .4s; transition: .4s; border-radius: 50%; }
input:checked + .slider { background-color: #008000; }
input:focus + .slider { box-shadow: 0 0 1px #008000; }
input:checked + .slider:before { -webkit-transform: translateX(24px); -ms-transform: translateX(24px); transform: translateX(24px); }
/* Rounded sliders */ .slider.round { border-radius: 24px; }
.slider.round:before { border-radius: 50%; } </style></head><body> <div id="app"> <header class=""> <h1>Aplikasi Penjualan Tiket Wisata</h1> </header> <div class="toggle-container"> <span class="toggle-label ">Mode Gelap</span> <label class="switch"> <input type="checkbox" id="dark-mode-toggle"> <span class="slider round"></span> </label> </div> <div id="input-section"> <div class="input-group"> <label for="nama-wisata">Nama Tempat Wisata</label> <input type="text" id="nama-wisata" placeholder="Masukkan nama tempat wisata"> </div> <div class="input-group"> <label for="harga-tiket">Harga Tiket (Rp)</label> <input type="number" id="harga-tiket" placeholder="Masukkan harga tiket"> </div> <button class="button" id="generate-ticket-button">Generate Tiket</button> </div> <div id="ticket-section" class="hidden"> <h3>Tiket Anda</h3> <div id="qrcode-container"> <p>QR Code akan muncul di sini</p> </div> <p>Nama Wisata: <span id="nama-wisata-display"></span></p> <p>Harga Tiket: Rp <span id="harga-tiket-display"></span></p> <button id="print-button" class="hidden">Cetak Tiket</button> </div> <div id="error-modal" class="modal"> <div class="modal-content"> <div class="modal-header"> <h2>Error</h2> <button id="close-error-modal" class="close-button">×</button> </div> <div class="modal-body"> <p id="error-message"></p> </div> <div class="modal-footer"> <button class="button" id="error-ok-button">OK</button> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script> <script> const app = document.getElementById('app'); const namaWisataInput = document.getElementById('nama-wisata'); const hargaTiketInput = document.getElementById('harga-tiket'); const generateTicketButton = document.getElementById('generate-ticket-button'); const ticketSection = document.getElementById('ticket-section'); const qrcodeContainer = document.getElementById('qrcode-container'); const namaWisataDisplay = document.getElementById('nama-wisata-display'); const hargaTiketDisplay = document.getElementById('harga-tiket-display'); const printButton = document.getElementById('print-button'); const errorModal = document.getElementById('error-modal'); const errorMessageText = document.getElementById('error-message'); const closeErrorModalButton = document.getElementById('close-error-modal'); const errorOkButton = document.getElementById('error-ok-button'); const darkModeToggle = document.getElementById('dark-mode-toggle'); const body = document.body; let isDarkMode = false;
function toggleDarkMode() { isDarkMode = !isDarkMode; body.classList.toggle('dark-mode', isDarkMode); app.classList.toggle('dark-mode', isDarkMode); document.querySelectorAll('.input-group').forEach(group => group.classList.toggle('dark-mode', isDarkMode)); ticketSection.classList.toggle('dark-mode', isDarkMode); document.querySelector('.modal-content').classList.toggle('dark-mode', isDarkMode); document.querySelector('.modal-header').classList.toggle('dark-mode', isDarkMode); document.querySelector('.modal-body').classList.toggle('dark-mode', isDarkMode); document.querySelector('.modal-footer').classList.toggle('dark-mode', isDarkMode); document.querySelector('.toggle-label').classList.toggle('dark-mode', isDarkMode); qrcodeContainer.classList.toggle('dark-mode', isDarkMode); localStorage.setItem('darkMode', isDarkMode); }
const savedDarkMode = localStorage.getItem('darkMode'); if (savedDarkMode === 'true') { darkModeToggle.checked = true; toggleDarkMode(); }
darkModeToggle.addEventListener('change', toggleDarkMode);
function showErrorModal(message) { errorMessageText.textContent = message; errorModal.style.display = "block"; }
closeErrorModalButton.addEventListener('click', () => { errorModal.style.display = "none"; });
errorOkButton.addEventListener('click', () => { errorModal.style.display = "none"; });
function generateTicket() { const namaWisata = namaWisataInput.value.trim(); const hargaTiket = parseInt(hargaTiketInput.value.trim());
if (namaWisata === "") { showErrorModal("Masukkan nama tempat wisata."); return; }
if (isNaN(hargaTiket) || hargaTiket <= 0) { showErrorModal("Masukkan harga tiket yang valid."); return; }
namaWisataDisplay.textContent = namaWisata; hargaTiketDisplay.textContent = hargaTiket.toLocaleString();
const qrData = `Nama Wisata: ${namaWisata}, Harga Tiket: Rp ${hargaTiket.toLocaleString()}`; qrcodeContainer.innerHTML = ''; new QRCode(qrcodeContainer, { text: qrData, width: 128, height: 128, });
ticketSection.style.display = "block"; printButton.classList.remove('hidden');
namaWisataInput.value = ""; hargaTiketInput.value = ""; }
function printTicket() { const namaWisata = namaWisataDisplay.textContent; const hargaTiket = hargaTiketDisplay.textContent; const qrCodeDataURL = qrcodeContainer.querySelector('img').src;
let printContent = ` <div style="text-align: center;"> <h2>Tiket Wisata</h2> <p>Nama Wisata: ${namaWisata}</p> <p>Harga Tiket: Rp ${hargaTiket}</p> <div style="margin-top: 10px;"> <img src="${qrCodeDataURL}" style="width: 128px; height: 128px;"> </div> <p>Terima kasih atas kunjungan Anda!</p> </div> `;
if (window.cordova && window.cordova.plugins && window.cordova.plugins.printer) { window.cordova.plugins.printer.isAvailable( function (isAvailable) { if (isAvailable) { window.cordova.plugins.printer.print(printContent, { name: 'Tiket Wisata', duplex: false, landscape: false, graystyle: false }, function (success) { console.log("Pencetakan berhasil: " + success); // Opsional: Tampilkan pesan sukses kepada pengguna }, function (error) { console.error("Terjadi kesalahan saat mencetak: " + error); showErrorModal("Terjadi kesalahan saat mencetak tiket: " + error); // Tampilkan pesan error kepada pengguna }); } else { showErrorModal("Printer tidak tersedia. Pastikan printer Bluetooth Anda terhubung dan aktif."); } }, function (error) { console.error("Terjadi kesalahan: " + error); showErrorModal("Terjadi kesalahan: " + error); } ); } else { console.warn("Plugin printer tidak tersedia. Mencetak via browser."); // Fallback untuk pencetakan browser standar (jika diperlukan) const printWindow = window.open('', '_blank'); printWindow.document.write(printContent); printWindow.document.close(); printWindow.focus(); printWindow.print(); printWindow.close(); } }
generateTicketButton.addEventListener('click', generateTicket); printButton.addEventListener('click', printTicket); </script></body></html>