(function () { var overlay = null; var loadingMessage = null; var dialog = null; var dialogTitle = null; var dialogBody = null; var dialogIcon = null; function cacheElements() { overlay = document.getElementById('ui-loading-overlay'); loadingMessage = document.getElementById('ui-loading-message'); dialog = document.getElementById('ui-dialog'); dialogTitle = document.getElementById('ui-dialog-title'); dialogBody = document.getElementById('ui-dialog-body'); dialogIcon = document.getElementById('ui-dialog-icon'); } function showLoading(message) { if (!overlay) { return; } if (loadingMessage) { loadingMessage.textContent = message || 'Processing...'; } overlay.hidden = false; overlay.setAttribute('aria-hidden', 'false'); document.body.classList.add('ui-is-loading'); } function hideLoading() { if (!overlay) { return; } overlay.hidden = true; overlay.setAttribute('aria-hidden', 'true'); document.body.classList.remove('ui-is-loading'); document.querySelectorAll('.ui-btn.is-loading').forEach(function (btn) { btn.classList.remove('is-loading'); btn.disabled = false; }); } function showDialog(type, message, title) { if (!dialog || !dialogBody) { return; } var isError = type === 'error'; var isSuccess = type === 'success'; if (dialogTitle) { dialogTitle.textContent = title || (isError ? 'Gagal' : isSuccess ? 'Berhasil' : 'Informasi'); } dialogBody.textContent = message || ''; if (dialogIcon) { dialogIcon.className = 'ui-dialog__icon'; dialogIcon.classList.add(isError ? 'is-error' : isSuccess ? 'is-success' : 'is-info'); dialogIcon.textContent = isError ? '!' : isSuccess ? '✓' : 'i'; } dialog.hidden = false; dialog.setAttribute('aria-hidden', 'false'); var closeBtn = dialog.querySelector('[data-ui-dialog-close].ui-dialog__btn'); if (closeBtn) { closeBtn.focus(); } } function hideDialog() { if (!dialog) { return; } dialog.hidden = true; dialog.setAttribute('aria-hidden', 'true'); } function markButtonLoading(button) { if (!button || button.disabled) { return; } button.classList.add('ui-btn', 'is-loading'); button.disabled = true; } function shouldSkipForm(form) { if (form.dataset.uiNoLoading !== undefined) { return true; } var method = (form.getAttribute('method') || 'get').toLowerCase(); return method === 'get'; } function resolveLoadingMessage(form, submitter) { if (submitter && submitter.dataset.loadingMessage) { return submitter.dataset.loadingMessage; } if (form.dataset.loadingMessage) { return form.dataset.loadingMessage; } return 'Memproses permintaan...'; } function bindForms(root) { var scope = root || document; scope.querySelectorAll('form').forEach(function (form) { if (shouldSkipForm(form) || form.dataset.uiFormBound === '1') { return; } form.dataset.uiFormBound = '1'; form.addEventListener('submit', function (event) { var submitter = event.submitter || form.querySelector('[type="submit"]'); showLoading(resolveLoadingMessage(form, submitter)); if (submitter) { markButtonLoading(submitter); } }); }); } function bindDialog() { if (!dialog) { return; } dialog.querySelectorAll('[data-ui-dialog-close]').forEach(function (el) { el.addEventListener('click', hideDialog); }); document.addEventListener('keydown', function (event) { if (event.key === 'Escape' && dialog && !dialog.hidden) { hideDialog(); } }); } function consumeFlashPayload(root) { var scope = root || document; var node = scope.querySelector ? scope.querySelector('#ui-flash-payload') : document.getElementById('ui-flash-payload'); if (!node) { return; } try { var payload = JSON.parse(node.textContent || '{}'); if (payload.message) { showDialog(payload.type || 'info', payload.message); } node.remove(); } catch (e) { console.warn('[UI] Invalid flash payload', e); } } function onFrameLoad(frame) { hideLoading(); bindForms(frame); consumeFlashPayload(frame); } window.UiFeedback = { showLoading: showLoading, hideLoading: hideLoading, showDialog: showDialog, hideDialog: hideDialog, onFrameLoad: onFrameLoad, }; document.addEventListener('DOMContentLoaded', function () { cacheElements(); bindForms(); bindDialog(); hideLoading(); consumeFlashPayload(); }); window.addEventListener('pageshow', function () { hideLoading(); }); })();