// Modal utility library to replace native alert/confirm/prompt
class ModalUtil {
static async alert(message, title = 'Aviso') {
return new Promise((resolve) => {
const modal = document.createElement('dialog');
modal.innerHTML = `
${message}
`;
document.body.appendChild(modal);
const acceptButton = modal.querySelector('button');
acceptButton.addEventListener('click', () => {
modal.close();
modal.remove();
resolve();
});
modal.showModal();
});
}
static async confirm(message, title = 'Confirmar') {
return new Promise((resolve) => {
const modal = document.createElement('dialog');
modal.innerHTML = `
${message}
`;
document.body.appendChild(modal);
const [cancelButton, acceptButton] = modal.querySelectorAll('button');
cancelButton.addEventListener('click', () => {
modal.close();
modal.remove();
resolve(false);
});
acceptButton.addEventListener('click', () => {
modal.close();
modal.remove();
resolve(true);
});
modal.showModal();
});
}
static async prompt(message, defaultValue = '', title = 'Ingrese un valor') {
return new Promise((resolve) => {
const modal = document.createElement('dialog');
modal.innerHTML = `
${message}
`;
document.body.appendChild(modal);
const input = modal.querySelector('input');
const [cancelButton, acceptButton] = modal.querySelectorAll('button');
cancelButton.addEventListener('click', () => {
modal.close();
modal.remove();
resolve(null);
});
acceptButton.addEventListener('click', () => {
const value = input.value;
modal.close();
modal.remove();
resolve(value);
});
// Handle enter key
input.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
acceptButton.click();
}
});
modal.showModal();
input.focus();
});
}
static async notify(message, type = 'success', duration = 3000) {
const notification = document.createElement('div');
notification.className = `notification ${type}`;
notification.innerHTML = message;
document.body.appendChild(notification);
// Animate in
setTimeout(() => notification.classList.add('show'), 100);
// Remove after duration
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => notification.remove(), 300);
}, duration);
}
}
// Add notification styles
const style = document.createElement('style');
style.textContent = `
.notification {
position: fixed;
bottom: 20px;
right: 20px;
padding: 1rem;
border-radius: 8px;
background: #fff5f0;
border: 1px solid #ffd4c2;
color: #d64d00;
box-shadow: 0 2px 4px rgba(214, 77, 0, 0.1);
transform: translateY(100%);
opacity: 0;
transition: all 0.3s ease;
z-index: 1000;
}
.notification.show {
transform: translateY(0);
opacity: 1;
}
.notification.success {
background: #ebfbee;
border-color: #b2f2bb;
color: #2b8a3e;
}
.notification.error {
background: #fff5f5;
border-color: #ffc9c9;
color: #c92a2a;
}
`;
document.head.appendChild(style);
// Export for use in other files
window.ModalUtil = ModalUtil;