// Minimal modal helpers for non-app pages (alert/confirm/prompt) // Uses the existing modal markup if present; falls back to native dialogs. const modalOverlay = document.getElementById('modal-overlay'); const modalTitle = document.getElementById('modal-title'); const modalMessage = document.getElementById('modal-message'); const modalInput = document.getElementById('modal-input'); const modalPrimary = document.getElementById('modal-primary'); const modalSecondary = document.getElementById('modal-secondary'); function showModal({ title, message, mode = 'alert', defaultValue = '', primaryLabel = null, secondaryLabel = null } = {}) { return new Promise((resolve) => { const hasParts = modalOverlay && modalTitle && modalMessage && modalInput && modalPrimary && modalSecondary; if (!hasParts) { if (mode === 'confirm') return resolve(confirm(`${title ? title + '\n\n' : ''}${message}`)); if (mode === 'prompt') return resolve(prompt(`${title ? title + '\n\n' : ''}${message}`, defaultValue)); alert(`${title ? title + '\n\n' : ''}${message}`); return resolve(true); } modalTitle.textContent = title || 'Notice'; modalMessage.innerHTML = message || ''; modalInput.style.display = mode === 'prompt' ? 'block' : 'none'; modalInput.value = defaultValue || ''; const cleanup = () => { modalOverlay.classList.remove('show'); modalPrimary.onclick = null; modalSecondary.onclick = null; document.removeEventListener('keydown', onKeyDown); }; const onKeyDown = (e) => { if (e.key === 'Escape') { cleanup(); resolve(mode === 'confirm' ? false : mode === 'prompt' ? null : true); } if (e.key === 'Enter' && mode === 'prompt') { cleanup(); resolve(modalInput.value); } }; document.addEventListener('keydown', onKeyDown); modalSecondary.style.display = mode === 'alert' ? 'none' : 'inline-flex'; modalSecondary.textContent = secondaryLabel || 'Cancel'; modalPrimary.textContent = primaryLabel || 'OK'; modalSecondary.onclick = () => { cleanup(); resolve(mode === 'confirm' ? false : null); }; modalPrimary.onclick = () => { cleanup(); resolve(mode === 'prompt' ? modalInput.value : true); }; modalOverlay.classList.add('show'); setTimeout(() => (mode === 'prompt' ? modalInput : modalPrimary).focus(), 25); }); } function uiAlert(message, title = 'Notice') { return showModal({ title, message, mode: 'alert' }); } function uiConfirm(message, title = 'Confirm') { return showModal({ title, message, mode: 'confirm' }); } function uiPrompt(message, title = 'Input', defaultValue = '') { return showModal({ title, message, mode: 'prompt', defaultValue }); } window.uiModal = { alert: uiAlert, confirm: uiConfirm, prompt: uiPrompt }; window.uiAlert = uiAlert; window.uiConfirm = uiConfirm; window.uiPrompt = uiPrompt; async function copyTextToClipboard(text) { try { await navigator.clipboard.writeText(String(text ?? '')); return true; } catch (e) { return false; } } window.copyTextToClipboard = copyTextToClipboard;