up
This commit is contained in:
@@ -211,6 +211,42 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
.rec-toast.info .ico { color: #3b82f6; }
|
||||
.rec-toast.warn .ico { color: #f59e0b; }
|
||||
.rec-toast.error .ico { color: #ef4444; }
|
||||
|
||||
/* ── Historial del paciente ── */
|
||||
.hist-toggle-btn {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
width: 100%; padding: 6px 10px; margin-top: 8px;
|
||||
background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px;
|
||||
font-size: .78rem; font-weight: 600; color: #475569;
|
||||
cursor: pointer; text-align: left; transition: background .15s;
|
||||
}
|
||||
.hist-toggle-btn:hover { background: #f1f5f9; }
|
||||
.hist-toggle-btn .hist-chev { margin-left: auto; transition: transform .2s; }
|
||||
.hist-toggle-btn.open .hist-chev { transform: rotate(180deg); }
|
||||
.hist-pac-body {
|
||||
border: 1px solid #e2e8f0; border-top: none;
|
||||
border-radius: 0 0 8px 8px; background: #fff;
|
||||
max-height: 260px; overflow-y: auto;
|
||||
}
|
||||
.pac-timeline { padding: 10px 12px; }
|
||||
.timeline-item {
|
||||
display: flex; gap: 10px; align-items: flex-start;
|
||||
padding-bottom: 10px; position: relative;
|
||||
}
|
||||
.timeline-item:not(:last-child)::before {
|
||||
content: ''; position: absolute; left: 6px; top: 14px;
|
||||
width: 2px; bottom: 0; background: #e2e8f0;
|
||||
}
|
||||
.timeline-dot {
|
||||
width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0;
|
||||
margin-top: 2px; border: 2px solid #fff;
|
||||
box-shadow: 0 0 0 2px currentColor;
|
||||
}
|
||||
.timeline-content { flex: 1; min-width: 0; }
|
||||
.timeline-fecha { font-size: .68rem; color: #94a3b8; }
|
||||
.timeline-codigo { font-size: .82rem; font-weight: 700; }
|
||||
.timeline-lugar { font-size: .73rem; color: #64748b; }
|
||||
.timeline-eb { font-size: .62rem; padding: 1px 7px; border-radius: 99px; font-weight: 700; display: inline-block; margin-top: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -327,6 +363,22 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php';
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Historial colapsable del paciente -->
|
||||
<div id="sec-historial-pac" class="d-none">
|
||||
<button class="hist-toggle-btn" id="btn-hist-toggle" onclick="toggleHistorialPaciente()">
|
||||
<i class="fas fa-history" style="color:#6366f1"></i>
|
||||
Historial del paciente
|
||||
<i class="fas fa-chevron-down hist-chev"></i>
|
||||
</button>
|
||||
<div id="hist-pac-body" class="hist-pac-body d-none">
|
||||
<div id="hist-pac-content" class="pac-timeline">
|
||||
<div class="text-center text-muted py-2 small">
|
||||
<i class="fas fa-spinner fa-spin me-1"></i>Cargando…
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -802,12 +854,27 @@ function seleccionarPaciente(pac) {
|
||||
document.getElementById('lbl-pac-cel').textContent =
|
||||
pac.telefono || pac.celular || '';
|
||||
document.getElementById('lista-pacientes-res').innerHTML = '';
|
||||
|
||||
// Mostrar historial del paciente
|
||||
const secHist = document.getElementById('sec-historial-pac');
|
||||
secHist.classList.remove('d-none');
|
||||
// Resetear estado colapsado
|
||||
document.getElementById('hist-pac-body').classList.add('d-none');
|
||||
document.getElementById('btn-hist-toggle').classList.remove('open');
|
||||
// Precargar en background (usuario decide si abre)
|
||||
_historialPacienteCargado = false;
|
||||
_historialPacienteId = pac.id;
|
||||
}
|
||||
|
||||
function desvincularPaciente() {
|
||||
pacienteActivo = null;
|
||||
_historialPacienteId = null;
|
||||
_historialPacienteCargado = false;
|
||||
document.getElementById('bloque-pac-no-vinculado').classList.remove('d-none');
|
||||
document.getElementById('bloque-pac-seleccionado').classList.add('d-none');
|
||||
document.getElementById('sec-historial-pac').classList.add('d-none');
|
||||
document.getElementById('hist-pac-body').classList.add('d-none');
|
||||
document.getElementById('btn-hist-toggle').classList.remove('open');
|
||||
document.getElementById('lista-pacientes-res').innerHTML = '';
|
||||
document.getElementById('inp-buscar-pac').value = '';
|
||||
}
|
||||
@@ -816,6 +883,74 @@ function abrirNuevoPaciente(nombre) {
|
||||
window.open('<?= BASE_URL ?>lab_pacientes.php?nuevo=1&nombre=' + encodeURIComponent(nombre), '_blank');
|
||||
}
|
||||
|
||||
// ── Historial del paciente ──────────────────────────────────────
|
||||
let _historialPacienteId = null;
|
||||
let _historialPacienteCargado = false;
|
||||
|
||||
async function toggleHistorialPaciente() {
|
||||
const body = document.getElementById('hist-pac-body');
|
||||
const btn = document.getElementById('btn-hist-toggle');
|
||||
const open = !body.classList.contains('d-none');
|
||||
body.classList.toggle('d-none', open);
|
||||
btn.classList.toggle('open', !open);
|
||||
if (!open && !_historialPacienteCargado && _historialPacienteId) {
|
||||
_historialPacienteCargado = true;
|
||||
await cargarHistorialPaciente(_historialPacienteId);
|
||||
}
|
||||
}
|
||||
|
||||
async function cargarHistorialPaciente(pacienteId) {
|
||||
const content = document.getElementById('hist-pac-content');
|
||||
content.innerHTML = '<div class="text-center text-muted py-2 small"><i class="fas fa-spinner fa-spin me-1"></i>Cargando historial…</div>';
|
||||
try {
|
||||
const res = await fetch(`${API}get_historial.php?paciente_id=${pacienteId}&per_page=15&page=1`);
|
||||
const json = await res.json();
|
||||
if (!json.ok || !json.turnos || !json.turnos.length) {
|
||||
content.innerHTML = '<div class="text-center text-muted py-3 small"><i class="fas fa-inbox me-1"></i>Sin visitas anteriores registradas</div>';
|
||||
return;
|
||||
}
|
||||
content.innerHTML = renderHistorialTimeline(json.turnos, json.total);
|
||||
} catch(_) {
|
||||
content.innerHTML = '<div class="text-center text-danger py-2 small">Error al cargar historial</div>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderHistorialTimeline(turnos, total) {
|
||||
const ESTADO_LBL = {
|
||||
espera:'Espera', en_recepcion:'Recepción', en_espera_lugar:'Esp. lugar',
|
||||
en_servicio:'En servicio', finalizado:'Finalizado', ausente:'Ausente', cancelado:'Cancelado',
|
||||
};
|
||||
const ESTADO_STYLE = {
|
||||
finalizado: 'background:#f1f5f9;color:#334155',
|
||||
ausente: 'background:#fee2e2;color:#991b1b',
|
||||
cancelado: 'background:#f1f5f9;color:#9ca3af',
|
||||
en_servicio: 'background:#dcfce7;color:#166534',
|
||||
en_espera_lugar:'background:#fde68a;color:#92400e',
|
||||
en_recepcion: 'background:#dbeafe;color:#1e40af',
|
||||
espera: 'background:#fef9c3;color:#78350f',
|
||||
};
|
||||
const totalLabel = total > turnos.length ? `<div class="text-end px-3 pb-1" style="font-size:.67rem;color:#94a3b8">Mostrando ${turnos.length} de ${total} visitas</div>` : '';
|
||||
const items = turnos.map(t => {
|
||||
const color = t.prioridad_color || '#6366f1';
|
||||
const lugar = escHtml(t.lugar_nombre || 'Recepción');
|
||||
const fecha = t.fecha_sesion || '—';
|
||||
const est = t.estado || '';
|
||||
const eStyle = ESTADO_STYLE[est] || 'background:#f1f5f9;color:#334155';
|
||||
const eLbl = ESTADO_LBL[est] || est;
|
||||
const mins = t.servicio_min != null ? `<span style="font-size:.65rem;color:#94a3b8;margin-left:4px">${t.servicio_min} min</span>` : '';
|
||||
return `<div class="timeline-item">
|
||||
<div class="timeline-dot" style="color:${color};background:${color}"></div>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-fecha">${escHtml(fecha)}</div>
|
||||
<div class="timeline-codigo" style="color:${color}">${escHtml(t.codigo)}</div>
|
||||
<div class="timeline-lugar">${lugar}</div>
|
||||
<span class="timeline-eb" style="${eStyle}">${escHtml(eLbl)}</span>${mins}
|
||||
</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
return `<div class="pac-timeline">${items}</div>${totalLabel}`;
|
||||
}
|
||||
|
||||
// ── Guardar solicitud ─────────────────────────────────────────
|
||||
async function guardarSolicitud() {
|
||||
if (!turnoActivo) return;
|
||||
|
||||
Reference in New Issue
Block a user