agdar/templates/partial/alert_modal.html
Marwan Alwali f6329ffa10 update
2025-11-04 13:44:58 +03:00

195 lines
7.4 KiB
HTML

{% load i18n %}
<!-- Global Alert Modal -->
<style>
/* Ensure modal header has rounded corners */
#alertModal .modal-header {
border-top-left-radius: calc(0.5rem - 1px);
border-top-right-radius: calc(0.5rem - 1px);
}
#alertModal .modal-content {
border-radius: 0.5rem;
}
</style>
<div class="modal fade" id="alertModal" tabindex="-1" aria-labelledby="alertModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="true">
<div class="modal-dialog modal-sm modal-dialog-centered">
<div class="modal-content">
<div class="modal-header " id="alertModalHeader">
<h5 class="modal-title" id="alertModalLabel">
<i class="fas fa-exclamation-circle me-2" id="alertModalIcon"></i>
<span id="alertModalTitle">{% trans "Alert" %}</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body" id="alertModalBody">
<!-- Message will be inserted here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="alertModalOkBtn">
{% trans "OK" %}
</button>
</div>
</div>
</div>
</div>
<script>
/**
* Show a Bootstrap modal alert instead of browser alert()
* @param {string} message - The message to display
* @param {string} type - The alert type: 'error', 'warning', 'info', 'success'
* @param {string} title - Optional custom title
* @returns {Promise} - Resolves when modal is closed
*/
function showAlertModal(message, type = 'warning', title = null) {
return new Promise((resolve) => {
const modal = document.getElementById('alertModal');
const modalHeader = document.getElementById('alertModalHeader');
const modalTitle = document.getElementById('alertModalTitle');
const modalIcon = document.getElementById('alertModalIcon');
const modalBody = document.getElementById('alertModalBody');
const modalOkBtn = document.getElementById('alertModalOkBtn');
// Set message
modalBody.innerHTML = message;
// Configure based on type
let iconClass, headerClass, titleText, btnClass;
switch(type) {
case 'error':
case 'danger':
iconClass = 'fas fa-times-circle';
headerClass = 'bg-danger text-white';
titleText = title || '{% trans "Error" %}';
btnClass = 'btn-danger';
break;
case 'warning':
iconClass = 'fas fa-exclamation-triangle';
headerClass = 'bg-warning text-dark';
titleText = title || '{% trans "Warning" %}';
btnClass = 'btn-warning';
break;
case 'info':
iconClass = 'fas fa-info-circle';
headerClass = 'bg-info text-white';
titleText = title || '{% trans "Information" %}';
btnClass = 'btn-info';
break;
case 'success':
iconClass = 'fas fa-check-circle';
headerClass = 'bg-success text-white';
titleText = title || '{% trans "Success" %}';
btnClass = 'btn-success';
break;
default:
iconClass = 'fas fa-exclamation-circle';
headerClass = 'bg-primary text-white';
titleText = title || '{% trans "Alert" %}';
btnClass = 'btn-primary';
}
// Apply styling
modalIcon.className = iconClass + ' me-2';
modalTitle.textContent = titleText;
modalHeader.className = 'modal-header ' + headerClass;
modalOkBtn.className = 'btn ' + btnClass;
// Show modal
const bsModal = new bootstrap.Modal(modal);
bsModal.show();
// Focus OK button when modal is shown
modal.addEventListener('shown.bs.modal', function() {
modalOkBtn.focus();
}, { once: true });
// Resolve promise when modal is hidden
modal.addEventListener('hidden.bs.modal', function() {
resolve();
}, { once: true });
});
}
/**
* Show a confirmation modal with Yes/No buttons
* @param {string} message - The message to display
* @param {string} title - Optional custom title
* @returns {Promise<boolean>} - Resolves to true if confirmed, false if cancelled
*/
function showConfirmModal(message, title = null) {
return new Promise((resolve) => {
const modal = document.getElementById('alertModal');
const modalHeader = document.getElementById('alertModalHeader');
const modalTitle = document.getElementById('alertModalTitle');
const modalIcon = document.getElementById('alertModalIcon');
const modalBody = document.getElementById('alertModalBody');
const modalFooter = modal.querySelector('.modal-footer');
// Set message
modalBody.innerHTML = message;
// Configure for confirmation
const iconClass = 'fas fa-question-circle';
const headerClass = 'bg-warning text-dark';
const titleText = title || '{% trans "Confirm Action" %}';
// Apply styling
modalIcon.className = iconClass + ' me-2';
modalTitle.textContent = titleText;
modalHeader.className = 'modal-header ' + headerClass;
// Replace footer with Yes/No buttons
modalFooter.innerHTML = `
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="confirmNoBtn">
{% trans "No" %}
</button>
<button type="button" class="btn btn-warning" id="confirmYesBtn">
{% trans "Yes" %}
</button>
`;
// Show modal
const bsModal = new bootstrap.Modal(modal);
bsModal.show();
// Track if user clicked Yes
let userConfirmed = false;
// Handle Yes button
document.getElementById('confirmYesBtn').addEventListener('click', function() {
userConfirmed = true;
bsModal.hide();
}, { once: true });
// Handle No button - explicitly set to false
document.getElementById('confirmNoBtn').addEventListener('click', function() {
userConfirmed = false;
}, { once: true });
// Handle modal close - resolve with the confirmation status
modal.addEventListener('hidden.bs.modal', function() {
// Restore original footer
modalFooter.innerHTML = `
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="alertModalOkBtn">
{% trans "OK" %}
</button>
`;
resolve(userConfirmed);
}, { once: true });
// Focus Yes button when modal is shown
modal.addEventListener('shown.bs.modal', function() {
document.getElementById('confirmYesBtn').focus();
}, { once: true });
});
}
/**
* Backward compatibility - replace window.alert with modal
* Uncomment if you want to override all alert() calls globally
*/
// window.alert = function(message) {
// showAlertModal(message, 'info');
// };
</script>