subir mas de un archivo, reprogramados

This commit is contained in:
Lizandro Guarnizo
2026-04-08 10:31:12 -05:00
parent 882ce56e96
commit c68a79a3a7
3 changed files with 267 additions and 230 deletions
+37 -11
View File
@@ -58,6 +58,7 @@ $hoy = date('Y-m-d');
.domcard.estado-en_domicilio { border-color:#20c997; }
.domcard.estado-completado { border-color:#198754; opacity:.75; }
.domcard.estado-cancelado { border-color:#dc3545; opacity:.6; }
.domcard.estado-reprogramado { border-color:#6f42c1; opacity:.65; }
/* ── Badges estado ── */
.badge-programado { background:#6c757d; }
@@ -66,6 +67,7 @@ $hoy = date('Y-m-d');
.badge-en_domicilio { background:#20c997; }
.badge-completado { background:#198754; }
.badge-cancelado { background:#dc3545; }
.badge-reprogramado { background:#6f42c1; }
/* ── Botones acción ── */
.btn-accion { font-size:.78rem; padding:.28rem .65rem; border-radius:20px; }
@@ -434,6 +436,7 @@ const ESTADOS_LABEL = {
en_domicilio: { label:'En domicilio', icon:'🏠', cls:'badge-en_domicilio' },
completado: { label:'Completado', icon:'🎉', cls:'badge-completado' },
cancelado: { label:'Cancelado', icon:'❌', cls:'badge-cancelado' },
reprogramado: { label:'Reprogramado', icon:'📅', cls:'badge-reprogramado' },
};
// Transiciones que el enfermero puede hacer
@@ -507,7 +510,7 @@ const portal = {
return;
}
const ACTIVOS = ['programado','confirmado','en_camino','en_domicilio'];
const CERRADOS = ['completado','cancelado'];
const CERRADOS = ['completado','cancelado','reprogramado'];
const sorted = [...this._agenda].sort((a,b) =>
(a.hora_programada||'99:99').localeCompare(b.hora_programada||'99:99'));
const activos = sorted.filter(i => ACTIVOS.includes(i.domicilio_estado||'programado'));
@@ -516,9 +519,12 @@ const portal = {
let html = activos.map((item, idx) => this._cardHTML(item, idx === 0)).join('');
if (cerrados.length) {
const secLabel = cerrados.some(i => !['completado','cancelado'].includes(i.domicilio_estado||''))
? `Cerrados / Reprogramados (${cerrados.length})`
: `Finalizados (${cerrados.length})`;
html += `<button class="fin-section-toggle" onclick="toggleFinalizados(this)">
<i class="fas fa-check-circle text-success"></i>
Finalizados (${cerrados.length})
${secLabel}
<i class="fas fa-chevron-down fin-chev"></i>
</button>
<div id="seccion-fin">
@@ -1225,14 +1231,16 @@ const formVer = {
placeholder="Instrucciones adicionales para el servicio…"></textarea>
</div>
<!-- Orden médica / Archivo -->
<!-- Orden médica / Archivos -->
<div class="mb-2">
<label class="form-label small fw-semibold">
Orden médica / Archivo <span class="text-muted fw-normal">(opcional)</span>
Orden médica / Archivos <span class="text-muted fw-normal">(opcional, puedes elegir varios)</span>
</label>
<input type="file" id="na-orden-file" accept=".pdf,.jpg,.jpeg,.png"
class="form-control form-control-sm">
<div id="na-orden-preview" class="mt-1 small text-muted"></div>
<input type="file" id="na-orden-file"
accept=".pdf,.jpg,.jpeg,.png,.gif,.webp,.doc,.docx,.xls,.xlsx,.txt,.csv"
class="form-control form-control-sm" multiple
onchange="agendaNueva._previsualizarArchivos(this.files)">
<div id="na-orden-preview" class="mt-1 d-flex flex-wrap gap-1"></div>
</div>
<div id="na-error" class="alert alert-danger py-2 d-none small"></div>
@@ -1336,6 +1344,9 @@ const agendaNueva = {
document.getElementById('na-valor-dom').value = '';
document.getElementById('na-valor-cop').value = '';
document.getElementById('na-fecha').value = document.getElementById('portal-fecha').value;
// Reset archivo adjunto
document.getElementById('na-orden-file').value = '';
document.getElementById('na-orden-preview').innerHTML = '';
document.getElementById('na-sugerencias').classList.add('d-none');
document.getElementById('na-paciente-elegido').classList.add('d-none');
document.getElementById('na-paciente-buscar').classList.remove('d-none');
@@ -1447,6 +1458,20 @@ const agendaNueva = {
document.getElementById('na-direccion').focus();
},
_previsualizarArchivos(files) {
const prev = document.getElementById('na-orden-preview');
prev.innerHTML = '';
for (const f of files) {
const isImg = f.type.startsWith('image/');
const chip = document.createElement('span');
chip.className = 'badge bg-light text-dark border';
chip.style.cssText = 'font-size:.74rem;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block';
chip.title = `${f.name} (${(f.size/1024).toFixed(0)} KB)`;
chip.innerHTML = `<i class="fas fa-${isImg ? 'image' : 'file'} me-1"></i>${esc(f.name)}`;
prev.appendChild(chip);
}
},
limpiarPaciente() {
document.getElementById('na-paciente-id').value = '';
document.getElementById('na-paciente-buscar').value = '';
@@ -1568,19 +1593,20 @@ const agendaNueva = {
const d = await r.json();
if (!d.success) throw new Error(d.error || 'Error al guardar');
// Subir archivo adjunto si el usuario seleccionó uno
// Subir archivos adjuntos si el usuario seleccionó alguno
const archivoInput = document.getElementById('na-orden-file');
if (archivoInput?.files?.length && d.id) {
const fd = new FormData();
fd.append('file', archivoInput.files[0]);
for (const f of archivoInput.files) fd.append('files[]', f);
fd.append('domicilio_id', d.id);
fd.append('paciente_id', pacId);
try {
const rFile = await fetch('api/lab/upload_orden.php', { method: 'POST', body: fd });
// Si falla el upload no bloqueamos; el domicilio ya fue creado
const dFile = await rFile.json();
if (!dFile.success) console.warn('No se pudo adjuntar el archivo:', dFile.error);
if (!dFile.success) console.warn('No se pudo adjuntar archivos:', dFile.error);
} catch (eFile) {
console.warn('Error al subir archivo:', eFile);
console.warn('Error al subir archivos:', eFile);
}
}