document.addEventListener('DOMContentLoaded', () => { if (window.bootstrap && window.bootstrap.Toast) { document.querySelectorAll('.toast').forEach((element) => { const toast = new window.bootstrap.Toast(element); toast.show(); }); } document.querySelectorAll('[data-qty-target][data-qty-step]').forEach((button) => { button.addEventListener('click', () => { const targetId = button.getAttribute('data-qty-target'); const input = targetId ? document.getElementById(targetId) : null; if (!input) { return; } const min = parseInt(input.getAttribute('min') || '1', 10); const max = parseInt(input.getAttribute('max') || '20', 10); const step = parseInt(button.getAttribute('data-qty-step') || '0', 10); const current = parseInt(input.value || String(min), 10) || min; const next = Math.max(min, Math.min(max, current + step)); input.value = String(next); input.dispatchEvent(new Event('change', { bubbles: true })); }); }); document.querySelectorAll('[data-copy-text]').forEach((button) => { button.addEventListener('click', async () => { const value = button.getAttribute('data-copy-text'); if (!value || !navigator.clipboard) { return; } const originalText = button.textContent; try { await navigator.clipboard.writeText(value); button.textContent = 'Tersalin'; button.classList.remove('btn-outline-success'); button.classList.add('btn-success'); window.setTimeout(() => { button.textContent = originalText; button.classList.remove('btn-success'); button.classList.add('btn-outline-success'); }, 1500); } catch (error) { console.error('Clipboard error', error); } }); }); document.querySelectorAll('[data-auto-disable]').forEach((form) => { form.addEventListener('submit', () => { const submitButton = form.querySelector('button[type="submit"]'); if (!submitButton || submitButton.disabled) { return; } submitButton.dataset.originalText = submitButton.innerHTML; submitButton.disabled = true; submitButton.innerHTML = 'Memproses…'; }); }); });