Revert "feat: soporte multi-archivo en modal Agendar Domicilio"
This reverts commit 45ef99991b.
This commit is contained in:
+105
-113
@@ -6589,13 +6589,30 @@ if (!isUserLoggedIn()) {
|
|||||||
<!-- ── FORMULARIO ── -->
|
<!-- ── FORMULARIO ── -->
|
||||||
<div id="labdom-form-panel" class="modal-body pb-2">
|
<div id="labdom-form-panel" class="modal-body pb-2">
|
||||||
|
|
||||||
<!-- Órdenes médicas (múltiples archivos permitidos) -->
|
<!-- Orden médica (adjunta / agregar / cambiar) -->
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div id="labdom-files-list" class="d-none mb-2"></div>
|
<div id="labdom-img-prev" class="d-flex align-items-center gap-3 p-2 bg-light rounded border" style="display:none">
|
||||||
<button type="button" id="labdom-btn-add-orden" class="btn btn-sm btn-outline-primary w-100 py-1" onclick="labDomicilio._agregarArchivo()">
|
<div id="labdom-file-thumb" class="flex-shrink-0">
|
||||||
|
<img id="labdom-img-el" src="" class="rounded border" style="max-height:80px;max-width:110px;object-fit:cover">
|
||||||
|
<div id="labdom-file-icon" class="rounded border bg-white text-center" style="width:80px;height:80px;display:none;align-items:center;justify-content:center"></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1 overflow-hidden">
|
||||||
|
<p class="mb-1 fw-semibold small text-secondary"><i class="fas fa-paperclip me-1"></i>Orden médica adjunta</p>
|
||||||
|
<small id="labdom-file-name" class="text-muted d-block mb-2" style="max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"></small>
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-secondary py-0 px-2" onclick="labDomicilio._cambiarOrden()" title="Cambiar archivo">
|
||||||
|
<i class="fas fa-exchange-alt me-1"></i>Cambiar
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger py-0 px-2" onclick="labDomicilio._eliminarOrden()" title="Eliminar orden">
|
||||||
|
<i class="fas fa-trash me-1"></i>Eliminar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" id="labdom-btn-add-orden" class="btn btn-sm btn-outline-primary w-100 py-1" onclick="labDomicilio._cambiarOrden()" style="display:none">
|
||||||
<i class="fas fa-paperclip me-1"></i>Adjuntar orden médica <span class="fw-normal text-muted">(opcional)</span>
|
<i class="fas fa-paperclip me-1"></i>Adjuntar orden médica <span class="fw-normal text-muted">(opcional)</span>
|
||||||
</button>
|
</button>
|
||||||
<input type="file" id="labdom-orden-input" accept="image/*,.pdf,.doc,.docx" multiple style="display:none">
|
<input type="file" id="labdom-orden-input" accept="image/*,.pdf,.doc,.docx" style="display:none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── TIPO (particular/seguro) — PRIMERO y llamativo ── -->
|
<!-- ── TIPO (particular/seguro) — PRIMERO y llamativo ── -->
|
||||||
@@ -6850,10 +6867,10 @@ if (!isUserLoggedIn()) {
|
|||||||
// ══════════════════════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
const labDomicilio = (() => {
|
const labDomicilio = (() => {
|
||||||
// Estado interno
|
// Estado interno
|
||||||
let _msgId = null;
|
let _msgId = null;
|
||||||
let _localFiles = []; // string[] — nombres de archivos ya en el servidor
|
let _localFile = null;
|
||||||
let _newOrderFiles = []; // File[] — archivos nuevos pendientes de subir
|
let _newOrderFile = null; // nuevo archivo de orden cargado desde el modal
|
||||||
let _convId = null;
|
let _convId = null;
|
||||||
let _pacienteId = null;
|
let _pacienteId = null;
|
||||||
let _isNewPaciente = false; // true = paciente nuevo (no existe en BD aún)
|
let _isNewPaciente = false; // true = paciente nuevo (no existe en BD aún)
|
||||||
let _pacNombre = '';
|
let _pacNombre = '';
|
||||||
@@ -6945,9 +6962,9 @@ const labDomicilio = (() => {
|
|||||||
|
|
||||||
/* Abre el modal desde el botón del mensaje imagen */
|
/* Abre el modal desde el botón del mensaje imagen */
|
||||||
abrir(msgId, localFile, convId) {
|
abrir(msgId, localFile, convId) {
|
||||||
_msgId = msgId || null;
|
_msgId = msgId || null;
|
||||||
_localFiles = localFile ? [localFile] : [];
|
_localFile = localFile|| null;
|
||||||
_convId = convId ? parseInt(convId) : null;
|
_convId = convId ? parseInt(convId) : null;
|
||||||
// Guardar también el userId actual para usarContacto cuando convId no esté disponible
|
// Guardar también el userId actual para usarContacto cuando convId no esté disponible
|
||||||
if (!_convId && typeof chatApp !== 'undefined' && chatApp.currentUserId) {
|
if (!_convId && typeof chatApp !== 'undefined' && chatApp.currentUserId) {
|
||||||
_convId = '__user:' + chatApp.currentUserId;
|
_convId = '__user:' + chatApp.currentUserId;
|
||||||
@@ -6956,7 +6973,7 @@ const labDomicilio = (() => {
|
|||||||
mostrarFormulario();
|
mostrarFormulario();
|
||||||
labDomicilio._resetFull();
|
labDomicilio._resetFull();
|
||||||
|
|
||||||
labDomicilio._renderFilesPanel();
|
labDomicilio._updateOrdenPreview();
|
||||||
|
|
||||||
if (!_bsModal) _bsModal = new bootstrap.Modal('#modalAgendarDomicilio', { backdrop: true, keyboard: true });
|
if (!_bsModal) _bsModal = new bootstrap.Modal('#modalAgendarDomicilio', { backdrop: true, keyboard: true });
|
||||||
_bsModal.show();
|
_bsModal.show();
|
||||||
@@ -6967,10 +6984,10 @@ const labDomicilio = (() => {
|
|||||||
|
|
||||||
/* Reset completo (nombre paciente + todos los campos) */
|
/* Reset completo (nombre paciente + todos los campos) */
|
||||||
_resetFull() {
|
_resetFull() {
|
||||||
_pacienteId = null;
|
_pacienteId = null;
|
||||||
_pacNombre = '';
|
_pacNombre = '';
|
||||||
_histDirs = [];
|
_histDirs = [];
|
||||||
_newOrderFiles = [];
|
_newOrderFile = null;
|
||||||
$('labdom-pac-busq').value = '';
|
$('labdom-pac-busq').value = '';
|
||||||
$('labdom-pac-list').style.display = 'none';
|
$('labdom-pac-list').style.display = 'none';
|
||||||
$('labdom-pac-buscar').classList.remove('d-none');
|
$('labdom-pac-buscar').classList.remove('d-none');
|
||||||
@@ -6992,94 +7009,71 @@ const labDomicilio = (() => {
|
|||||||
labDomicilio._resetDomicilio();
|
labDomicilio._resetDomicilio();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Renderiza la lista de órdenes médicas adjuntas (soporta múltiples archivos) */
|
/* Actualiza la previa de orden médica en el modal (imagen o icono de archivo) */
|
||||||
_renderFilesPanel() {
|
_updateOrdenPreview() {
|
||||||
const listDiv = document.getElementById('labdom-files-list');
|
const prevDiv = document.getElementById('labdom-img-prev');
|
||||||
const addBtn = document.getElementById('labdom-btn-add-orden');
|
const addBtn = document.getElementById('labdom-btn-add-orden');
|
||||||
if (!listDiv) return;
|
const imgEl = document.getElementById('labdom-img-el');
|
||||||
const iconMap = { pdf: 'fas fa-file-pdf text-danger', doc: 'fas fa-file-word text-primary', docx: 'fas fa-file-word text-primary', mp4: 'fas fa-file-video text-warning', mkv: 'fas fa-file-video text-warning', mp3: 'fas fa-file-audio text-success', ogg: 'fas fa-file-audio text-success', webm: 'fas fa-file-video text-warning' };
|
const iconEl = document.getElementById('labdom-file-icon');
|
||||||
const total = _localFiles.length + _newOrderFiles.length;
|
const nameEl = document.getElementById('labdom-file-name');
|
||||||
if (total === 0) {
|
if (!prevDiv) return;
|
||||||
listDiv.classList.add('d-none');
|
if (_localFile || _newOrderFile) {
|
||||||
listDiv.innerHTML = '';
|
prevDiv.style.display = '';
|
||||||
if (addBtn) addBtn.innerHTML = '<i class="fas fa-paperclip me-1"></i>Adjuntar orden médica <span class="fw-normal text-muted">(opcional)</span>';
|
if (addBtn) addBtn.style.display = 'none';
|
||||||
return;
|
const fileName = _newOrderFile ? _newOrderFile.name : (_localFile || '');
|
||||||
}
|
if (nameEl) nameEl.textContent = fileName;
|
||||||
if (addBtn) addBtn.innerHTML = '<i class="fas fa-plus me-1"></i>Añadir otro archivo';
|
const isImage = /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(fileName);
|
||||||
let html = '<div class="d-flex flex-column gap-1">';
|
if (isImage) {
|
||||||
_localFiles.forEach((fname, i) => {
|
if (imgEl) {
|
||||||
const isImg = /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(fname);
|
imgEl.style.display = '';
|
||||||
const ext = (fname || '').split('.').pop().toLowerCase();
|
if (_newOrderFile) {
|
||||||
const iCls = iconMap[ext] || 'fas fa-file text-secondary';
|
const reader = new FileReader();
|
||||||
const thumb = isImg
|
reader.onload = ev => { imgEl.src = ev.target.result; };
|
||||||
? `<img src="uploads/media/${escAtr(fname)}" class="rounded" style="height:38px;width:52px;object-fit:cover">`
|
reader.readAsDataURL(_newOrderFile);
|
||||||
: `<i class="${iCls}" style="font-size:1.5rem"></i>`;
|
} else {
|
||||||
html += `<div class="d-flex align-items-center gap-2 py-1 px-2 bg-light rounded border">
|
imgEl.src = `uploads/media/${_localFile}`;
|
||||||
<div class="flex-shrink-0 d-flex align-items-center justify-content-center" style="width:52px;height:38px">${thumb}</div>
|
}
|
||||||
<small class="flex-grow-1 text-muted text-truncate" style="max-width:180px">${escLab(fname)}</small>
|
}
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger py-0 px-1 ms-1" onclick="labDomicilio._eliminarArchivo('local',${i})" title="Quitar"><i class="fas fa-trash-alt"></i></button>
|
if (iconEl) iconEl.style.display = 'none';
|
||||||
</div>`;
|
} else {
|
||||||
});
|
if (imgEl) imgEl.style.display = 'none';
|
||||||
_newOrderFiles.forEach((file, i) => {
|
if (iconEl) {
|
||||||
const isImg = /^image\//.test(file.type);
|
const ext = (fileName || '').split('.').pop().toLowerCase();
|
||||||
const ext = file.name.split('.').pop().toLowerCase();
|
const iconMap = { pdf: 'fas fa-file-pdf text-danger', doc: 'fas fa-file-word text-primary', docx: 'fas fa-file-word text-primary', mp4: 'fas fa-file-video text-warning', mkv: 'fas fa-file-video text-warning', mp3: 'fas fa-file-audio text-success', ogg: 'fas fa-file-audio text-success', webm: 'fas fa-file-video text-warning' };
|
||||||
const iCls = iconMap[ext] || 'fas fa-file text-secondary';
|
iconEl.innerHTML = `<i class="${iconMap[ext] || 'fas fa-file text-secondary'}" style="font-size:2rem"></i>`;
|
||||||
const tid = `labdom-nth-${i}`;
|
iconEl.style.display = 'flex';
|
||||||
const thumb = isImg
|
}
|
||||||
? `<img id="${tid}" src="" class="rounded" style="height:38px;width:52px;object-fit:cover">`
|
|
||||||
: `<i class="${iCls}" style="font-size:1.5rem"></i>`;
|
|
||||||
html += `<div class="d-flex align-items-center gap-2 py-1 px-2 bg-light rounded border">
|
|
||||||
<div class="flex-shrink-0 d-flex align-items-center justify-content-center" style="width:52px;height:38px">${thumb}</div>
|
|
||||||
<small class="flex-grow-1 text-muted text-truncate" style="max-width:180px">${escLab(file.name)} <span class="badge bg-warning text-dark ms-1" style="font-size:.6rem">nuevo</span></small>
|
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger py-0 px-1 ms-1" onclick="labDomicilio._eliminarArchivo('new',${i})" title="Quitar"><i class="fas fa-trash-alt"></i></button>
|
|
||||||
</div>`;
|
|
||||||
});
|
|
||||||
html += '</div>';
|
|
||||||
listDiv.innerHTML = html;
|
|
||||||
listDiv.classList.remove('d-none');
|
|
||||||
// Cargar previsualizaciones de imágenes nuevas
|
|
||||||
_newOrderFiles.forEach((file, i) => {
|
|
||||||
if (/^image\//.test(file.type)) {
|
|
||||||
const img = document.getElementById(`labdom-nth-${i}`);
|
|
||||||
if (img) { const rd = new FileReader(); rd.onload = ev => { img.src = ev.target.result; }; rd.readAsDataURL(file); }
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
prevDiv.style.display = 'none';
|
||||||
|
if (addBtn) addBtn.style.display = '';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Abre el selector de archivo para agregar una o más órdenes médicas */
|
/* Abre el selector de archivo para cambiar o agregar la orden médica */
|
||||||
_agregarArchivo() {
|
_cambiarOrden() {
|
||||||
const inp = document.getElementById('labdom-orden-input');
|
const inp = document.getElementById('labdom-orden-input');
|
||||||
if (!inp) return;
|
if (!inp) return;
|
||||||
const handler = (e) => {
|
const handler = (e) => {
|
||||||
inp.removeEventListener('change', handler);
|
inp.removeEventListener('change', handler);
|
||||||
const files = e.target.files;
|
const file = e.target.files && e.target.files[0];
|
||||||
if (!files || !files.length) return;
|
if (!file) return;
|
||||||
for (const f of files) _newOrderFiles.push(f);
|
_newOrderFile = file;
|
||||||
labDomicilio._renderFilesPanel();
|
_localFile = null;
|
||||||
|
labDomicilio._updateOrdenPreview();
|
||||||
inp.value = '';
|
inp.value = '';
|
||||||
};
|
};
|
||||||
inp.addEventListener('change', handler);
|
inp.addEventListener('change', handler);
|
||||||
inp.click();
|
inp.click();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Elimina un archivo concreto de la lista (local = del servidor, new = pendiente subir) */
|
/* Elimina la orden médica adjunta */
|
||||||
_eliminarArchivo(source, index) {
|
|
||||||
if (source === 'local') {
|
|
||||||
if (index === 0) _msgId = null;
|
|
||||||
_localFiles.splice(index, 1);
|
|
||||||
} else {
|
|
||||||
_newOrderFiles.splice(index, 1);
|
|
||||||
}
|
|
||||||
labDomicilio._renderFilesPanel();
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Mantiene compatibilidad con código externo que llame _eliminarOrden() */
|
|
||||||
_eliminarOrden() {
|
_eliminarOrden() {
|
||||||
if (!confirm('¿Eliminar todas las órdenes médicas adjuntas?')) return;
|
if (!confirm('¿Eliminar la orden médica adjunta?')) return;
|
||||||
_localFiles = [];
|
_localFile = null;
|
||||||
_newOrderFiles = [];
|
_newOrderFile = null;
|
||||||
_msgId = null;
|
_msgId = null;
|
||||||
labDomicilio._renderFilesPanel();
|
labDomicilio._updateOrdenPreview();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Muestra/oculta el campo «nombre del seguro» según la selección */
|
/* Muestra/oculta el campo «nombre del seguro» según la selección */
|
||||||
@@ -7416,23 +7410,22 @@ const labDomicilio = (() => {
|
|||||||
notas_admin: fv('labdom-notas') || null,
|
notas_admin: fv('labdom-notas') || null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Subir todos los archivos nuevos y añadirlos a _localFiles
|
// Subir nuevo archivo de orden si el usuario cambió o agregó uno desde el modal
|
||||||
for (const file of _newOrderFiles) {
|
if (_newOrderFile) {
|
||||||
try {
|
try {
|
||||||
const fd = new FormData();
|
const fd = new FormData();
|
||||||
fd.append('file', file);
|
fd.append('file', _newOrderFile);
|
||||||
const upRes = await fetch('api/lab/upload_orden.php', { method: 'POST', body: fd });
|
const upRes = await fetch('api/lab/upload_orden.php', { method: 'POST', body: fd });
|
||||||
const upData = await upRes.json();
|
const upData = await upRes.json();
|
||||||
if (upData.success && upData.local_file) {
|
if (upData.success && upData.local_file) {
|
||||||
_localFiles.push(upData.local_file);
|
_localFile = upData.local_file;
|
||||||
|
_newOrderFile = null;
|
||||||
}
|
}
|
||||||
} catch (_e) { /* silencioso — no bloquea el flujo */ }
|
} catch (_e) { /* silencioso — no bloquea el flujo */ }
|
||||||
}
|
}
|
||||||
_newOrderFiles = [];
|
|
||||||
|
|
||||||
// Crear registro de orden por cada archivo y enlazarlo al domicilio
|
// Si hay orden médica (original o recién subida), crear registro y enlazar
|
||||||
let firstOrdenId = null;
|
if (_localFile) {
|
||||||
for (let _fi = 0; _fi < _localFiles.length; _fi++) {
|
|
||||||
try {
|
try {
|
||||||
const convIdNum = (_convId && !String(_convId).startsWith('__user:'))
|
const convIdNum = (_convId && !String(_convId).startsWith('__user:'))
|
||||||
? parseInt(_convId) : null;
|
? parseInt(_convId) : null;
|
||||||
@@ -7441,20 +7434,19 @@ const labDomicilio = (() => {
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
paciente_id: _pacienteId,
|
paciente_id: _pacienteId,
|
||||||
local_file: _localFiles[_fi],
|
local_file: _localFile,
|
||||||
media_message_id: (_fi === 0 ? _msgId : null) || null,
|
media_message_id: _msgId || null,
|
||||||
conversation_id: convIdNum,
|
conversation_id: convIdNum,
|
||||||
examenes_solicitados: datos.examenes_solicitados,
|
examenes_solicitados: datos.examenes_solicitados,
|
||||||
estado: 'pendiente',
|
estado: 'pendiente',
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const orData = await orRes.json();
|
const orData = await orRes.json();
|
||||||
if (orData.success && orData.orden_id && firstOrdenId === null) {
|
if (orData.success && orData.orden_id) {
|
||||||
firstOrdenId = orData.orden_id;
|
datos.orden_id = orData.orden_id;
|
||||||
}
|
}
|
||||||
} catch (_) { /* no bloquea si falla la creación de la orden */ }
|
} catch (_) { /* no bloquea si falla la creación de la orden */ }
|
||||||
}
|
}
|
||||||
if (firstOrdenId) datos.orden_id = firstOrdenId;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = await fetch('api/lab/save_domicilio.php', {
|
const r = await fetch('api/lab/save_domicilio.php', {
|
||||||
@@ -7606,9 +7598,9 @@ const labDomicilio = (() => {
|
|||||||
pacienteId: _pacienteId,
|
pacienteId: _pacienteId,
|
||||||
pacNombre: _pacNombre,
|
pacNombre: _pacNombre,
|
||||||
histDirs: [..._histDirs],
|
histDirs: [..._histDirs],
|
||||||
msgId: _msgId,
|
msgId: _msgId,
|
||||||
localFiles: [..._localFiles],
|
localFile: _localFile,
|
||||||
newOrderFiles: [..._newOrderFiles],
|
newOrderFile: _newOrderFile,
|
||||||
cardVisible: !document.getElementById('labdom-pac-card')?.classList.contains('d-none'),
|
cardVisible: !document.getElementById('labdom-pac-card')?.classList.contains('d-none'),
|
||||||
pacInfo: {
|
pacInfo: {
|
||||||
nombre: document.getElementById('labdom-pac-nombre')?.value || '',
|
nombre: document.getElementById('labdom-pac-nombre')?.value || '',
|
||||||
@@ -7691,13 +7683,13 @@ const labDomicilio = (() => {
|
|||||||
labDomicilio._resetFull(); // limpia el DOM
|
labDomicilio._resetFull(); // limpia el DOM
|
||||||
|
|
||||||
// Restaurar estado interno DESPUÉS del reset (para que no se sobreescriba)
|
// Restaurar estado interno DESPUÉS del reset (para que no se sobreescriba)
|
||||||
_convId = sesion.convId;
|
_convId = sesion.convId;
|
||||||
_pacienteId = sesion.pacienteId;
|
_pacienteId = sesion.pacienteId;
|
||||||
_pacNombre = sesion.pacNombre;
|
_pacNombre = sesion.pacNombre;
|
||||||
_histDirs = sesion.histDirs || [];
|
_histDirs = sesion.histDirs || [];
|
||||||
_msgId = sesion.msgId;
|
_msgId = sesion.msgId;
|
||||||
_localFiles = sesion.localFiles || [];
|
_localFile = sesion.localFile;
|
||||||
_newOrderFiles = sesion.newOrderFiles || [];
|
_newOrderFile = sesion.newOrderFile || null;
|
||||||
|
|
||||||
// Restaurar campos del formulario
|
// Restaurar campos del formulario
|
||||||
const f = sesion.fields || {};
|
const f = sesion.fields || {};
|
||||||
@@ -7742,7 +7734,7 @@ const labDomicilio = (() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
labDomicilio._calcTotal();
|
labDomicilio._calcTotal();
|
||||||
labDomicilio._renderFilesPanel();
|
labDomicilio._updateOrdenPreview();
|
||||||
|
|
||||||
// Abrir el modal
|
// Abrir el modal
|
||||||
if (!_bsModal) _bsModal = new bootstrap.Modal('#modalAgendarDomicilio', { backdrop: true, keyboard: true });
|
if (!_bsModal) _bsModal = new bootstrap.Modal('#modalAgendarDomicilio', { backdrop: true, keyboard: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user