feat: modal agendar domicilio es minimizable y arrastrable

This commit is contained in:
Lizandro Guarnizo
2026-03-12 23:16:14 -05:00
parent 5c4ddd1cd8
commit 2b46057ac1
+147 -2
View File
@@ -6431,6 +6431,56 @@ if (!isset($_SESSION['user_id'])) {
#modalAgendarDomicilio .field-err { display:none; font-size:.8rem; color:#dc3545; margin-top:3px; }
#modalAgendarDomicilio .is-invalid ~ .field-err,
#modalAgendarDomicilio .is-invalid + .field-err { display:block; }
/* ── Modo flotante (minimizado) ── */
#modalAgendarDomicilio.dom-flotante {
position: fixed !important;
top: auto !important;
left: auto !important;
bottom: 16px !important;
right: 16px !important;
width: auto !important;
margin: 0 !important;
z-index: 1055;
display: block !important;
pointer-events: auto;
}
#modalAgendarDomicilio.dom-flotante .modal-dialog {
margin: 0;
width: 320px;
max-height: none;
transform: none !important;
}
#modalAgendarDomicilio.dom-flotante .modal-body,
#modalAgendarDomicilio.dom-flotante #labdom-form-panel,
#modalAgendarDomicilio.dom-flotante #labdom-footer,
#modalAgendarDomicilio.dom-flotante #labdom-ok-panel { display: none !important; }
#modalAgendarDomicilio.dom-flotante .modal-content {
box-shadow: 0 8px 32px rgba(0,0,0,.28);
border-radius: 12px;
}
#modalAgendarDomicilio.dom-flotante .modal-header {
cursor: move;
border-radius: 12px;
user-select: none;
}
/* Botón restaurar dentro del header minimizado */
.labdom-restore-hint {
font-size:.72rem; opacity:.8; white-space:nowrap;
}
/* Botón minimizar */
#labdom-btn-minimizar {
background: rgba(255,255,255,.18);
border: 1px solid rgba(255,255,255,.35);
color: #fff;
border-radius: 6px;
padding: 2px 8px;
font-size: .8rem;
line-height: 1.4;
cursor: pointer;
transition: background .15s;
}
#labdom-btn-minimizar:hover { background: rgba(255,255,255,.32); }
</style>
<div class="modal fade" id="modalAgendarDomicilio" tabindex="-1">
@@ -6442,7 +6492,13 @@ if (!isset($_SESSION['user_id'])) {
<h5 class="modal-title mb-0"><i class="fas fa-house-medical me-2"></i>Agendar Domicilio</h5>
<small id="labdom-header-pac" class="opacity-75"></small>
</div>
<button class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
<div class="d-flex align-items-center gap-2">
<button id="labdom-btn-minimizar" title="Minimizar — sigue agendando mientras copias datos"
onclick="labDomicilio.minimizar()">
<i class="fas fa-window-minimize"></i> Minimizar
</button>
<button class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
</div>
<!-- ── PANEL ÉXITO (se muestra al guardar) ── -->
@@ -6816,7 +6872,7 @@ const labDomicilio = (() => {
$('labdom-img-prev').style.display = 'none';
}
if (!_bsModal) _bsModal = new bootstrap.Modal('#modalAgendarDomicilio');
if (!_bsModal) _bsModal = new bootstrap.Modal('#modalAgendarDomicilio', { backdrop: true, keyboard: true });
_bsModal.show();
// Pre-cargar contacto de la conversación de forma silenciosa
@@ -7225,6 +7281,95 @@ const labDomicilio = (() => {
return el ? el.textContent.trim() : '';
},
/* ─── Minimizar / restaurar modal ───
* Al minimizar: oculta backdrop, convierte el modal en flotante
* sin perder ningún dato del formulario.
* Al restaurar: vuelve al estado normal de Bootstrap. */
minimizar() {
const modalEl = document.getElementById('modalAgendarDomicilio');
const isMin = !modalEl.classList.contains('dom-flotante');
if (isMin) {
/* — Pasar a modo flotante — */
// 1. Quitar backdrop
document.querySelectorAll('.modal-backdrop').forEach(b => b.remove());
document.body.classList.remove('modal-open');
document.body.style.overflow = '';
document.body.style.paddingRight = '';
// 2. Desvincular de Bootstrap para posicionarlo libre
modalEl.removeAttribute('aria-modal');
modalEl.removeAttribute('role');
// Mantener visible pero fuera del flujo Bootstrap
modalEl.style.display = 'block';
modalEl.classList.add('dom-flotante');
// 3. Título del botón
const icon = document.querySelector('#labdom-btn-minimizar i');
if (icon) { icon.className = 'fas fa-window-restore'; }
const btn = document.getElementById('labdom-btn-minimizar');
if (btn) btn.title = 'Restaurar modal';
// 4. Activar drag
labDomicilio._initDrag();
} else {
/* — Restaurar modo normal — */
modalEl.classList.remove('dom-flotante');
// Limpiar posición manual que puso _initDrag
const dialog = modalEl.querySelector('.modal-dialog');
if (dialog) {
dialog.style.position = '';
dialog.style.left = '';
dialog.style.top = '';
dialog.style.margin = '';
}
// Re-mostrar con Bootstrap para restaurar backdrop
if (_bsModal) {
// Bootstrap detecta el estado por aria-modal
modalEl.setAttribute('aria-modal', 'true');
modalEl.setAttribute('role', 'dialog');
_bsModal.show();
}
const icon = document.querySelector('#labdom-btn-minimizar i');
if (icon) { icon.className = 'fas fa-window-minimize'; }
const btn = document.getElementById('labdom-btn-minimizar');
if (btn) btn.title = 'Minimizar — sigue agendando mientras copias datos';
}
},
/* ─── Drag de la ventana flotante ─── */
_initDrag() {
const dialog = document.querySelector('#modalAgendarDomicilio .modal-dialog');
const handle = document.querySelector('#modalAgendarDomicilio .modal-header');
if (!handle || handle._dragInit) return;
handle._dragInit = true;
let sx, sy, sl, st;
handle.addEventListener('mousedown', ev => {
if (ev.target.closest('button')) return;
const r = dialog.getBoundingClientRect();
sx = ev.clientX; sy = ev.clientY;
sl = r.left; st = r.top;
dialog.style.position = 'fixed';
dialog.style.margin = '0';
dialog.style.left = sl + 'px';
dialog.style.top = st + 'px';
ev.preventDefault();
const move = e => {
dialog.style.left = (sl + e.clientX - sx) + 'px';
dialog.style.top = (st + e.clientY - sy) + 'px';
};
const up = () => {
document.removeEventListener('mousemove', move);
document.removeEventListener('mouseup', up);
};
document.addEventListener('mousemove', move);
document.addEventListener('mouseup', up);
});
},
};
})();