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); }
@@ -6442,7 +6492,13 @@ if (!isset($_SESSION['user_id'])) {
Agendar Domicilio
-
+
+
+
+
@@ -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);
+ });
+ },
+
};
})();