From 2b46057ac1dd33003b1dcb5a07187f25f5a0daf6 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:16:14 -0500 Subject: [PATCH] feat: modal agendar domicilio es minimizable y arrastrable --- conversations.php | 149 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/conversations.php b/conversations.php index 27385b9..36199bb 100644 --- a/conversations.php +++ b/conversations.php @@ -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); } - +
+ + +
@@ -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); + }); + }, + }; })();