Commit Graph
172 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 00aee615c5 lugar: cambiar label 'TOMA DE MUESTRAS' → 'ENTREGA DE MUESTRAS'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:25:30 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 17703f0157 fix(chat-turnero): prevent messages mixing between contacts on fast switching
Capture activeUserId at the start of each async function (fetchMessages,
loadMoreMessages, pollMessages) and discard the response if the user changed
contacts while the request was in-flight.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:19:52 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a0979e31e7 recepcion: quitar botón duplicar del historial (va en sección formatos)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:19:27 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 78e71d5926 recepcion: mostrar kiosko + paciente vinculado en dos líneas separadas
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:15:03 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c511da18bd recepcion: fix solo_muestras, reorder fields, duplicar visita, kiosko label
- create_solicitud.php: evitar SQL `IN ()` vacío cuando solo_muestras=1 sin exámenes
- recepcion.php: mover embarazada+médico después del historial del paciente
- recepcion.php: actualizar label kiosko con nombre real al vincular paciente
- recepcion.php: botón "Duplicar" en historial para copiar exámenes y pago de última visita
- recepcion.php: omitir validación de consentimientos pendientes cuando es solo_muestras
- recepcion.php: agregar alias esc() = escHtml() usado en buscarMedico

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:13:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d3826972ad feat(turnero): selector de médico tratante en recepción, visible en toma de muestras
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:55:32 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ec614c2a89 feat(chat-turnero): backend APIs for media upload, reactions, and template messages
- chat_upload_media.php: multipart upload to WhatsApp Media API, sends image/video/audio/document
- chat_react.php: sends emoji reaction to a message via WhatsApp, updates reaction_emoji in DB
- chat_send_message.php: extended to support type=template with lang+params

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:53:23 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a7ab91615f feat(chat-turnero): rich messaging UI — images, video, audio, reactions, emoji, templates
- Attach button with file preview (image thumb for images, name+size for others)
- Audio recording via MediaRecorder API with live timer; sends as voice note
- Emoji panel with 35 common emojis (medical/comms focused)
- Reaction picker on message hover — sends via chat_react.php API
- Template modal (name, lang, JSON params) — sends via chat_send_message.php type=template
- buildBubble() now renders: inline images, <video> player, <audio> player, doc links with type icon
- Shows reaction_emoji below bubble and status tick on outgoing messages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:53:23 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3b378c0d75 feat(medicos): seed 444 médicos + columnas telefonos/email en tabla y modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:51:57 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1574f12275 feat(medicos): módulo CRUD de médicos con tabla, búsqueda y modal edición
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:42:36 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 665fee99a9 fix(turnero): restaurar APIs del chat perdidas por force push del servidor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:41:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d93dccf006 feat(turnero): agregar Verificar Paciente al menú admin/supervisor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:39:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cb77425ca2 feat(turnero): vista verificar_paciente dentro del ERP con Layout
- Crea modules/turnero/views/verificar_paciente.php con Layout::open/close
- Flujo completo: cédula → OTP → éxito, mismo JS que verificar.php público
- Link del módulo ahora apunta a erp.php?m=turnero&v=verificar_paciente

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:35:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ff0fd3284e fix(turnero): usar plantilla correcta según tipo de turno y ajustar sidebar
- create_turno.php: tipo F usa turnero_wa_template_muestra, resto usa turnero_wa_template
- styles.css: has-active ya incluye font-size 0.82rem (verificado)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:30:06 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 fd95e7b38a fix: restaurar todas las optimizaciones móvil/tablet perdidas por force push
- chat.php: recuperado y re-aplicado panel-switch móvil, viewport iOS,
  safe-area, sticky topbar, link ← Menú, botón volver
- lugar.php: panel-switch tablet (≤860px), botón ← Cola, JS mobile
- recepcion.php: panel-switch tablet (≤900px), botón ← Cola, JS mobile
- sidebar.php: soporte atributo target en links de módulo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:25:47 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 be4cb88420 fix(turnero): restaurar Chat Turnero en menú admin/supervisor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:19:32 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 98507ad1a5 fix(turnero): restaurar dos plantillas WhatsApp en tab Sesión
- Plantilla con consentimiento (turnero_wa_template)
- Plantilla muestra pendiente (turnero_wa_template_muestra)
- sesion_turno.php guarda ambas en lab_config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:17:17 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a592ddb30d fix: restaurar cambios revertidos por rebase del servidor
- verificar.php: BASE_URL absoluta en fetch, fix paste multi-dígito
- send_otp.php: mensaje SMS correcto sin dos puntos ni expiración
- module.php: Chat Turnero y Verificar Paciente para recepcionistas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:13:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 34004b4d98 feat(turnero): opción solo entrega de muestras con prioridad y badge naranja en cola
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:07:05 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 76dda4722a feat(turnero): pago combinado con desglose por efectivo, transferencia y tarjeta
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:02:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4626ca3f28 feat(display): nombre paciente más grande y visible en overlay de llamada
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:58:09 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 38bd211ca6 feat(kiosko): mostrar nombre/cédula en ticket y quitar posición en cola
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:53:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c9e5744de4 feat(turnero): campo embarazada en recepción y badge en toma de muestras
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:48:03 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7475f3c58e fix(turnero): mostrar nombre del paciente en cola al vincularlo en recepción
Al vincular un paciente al turno, actualiza paciente_nombre con el
nombre_completo real de lab_pacientes. El siguiente poll de la cola
muestra el nombre en lugar de la cédula del kiosko.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:35:45 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 8074f33b32 fix(turnero): eliminar duplicados en pantalla TV al llamar turno
callKey usaba id+llamado_at: si llamado_at llegaba null en el primer
poll y con valor en el segundo, se generaban dos claves distintas para
el mismo evento y el turno se anunciaba dos veces.

Cambia callKey a String(id) — cada turno se anuncia una sola vez
por sesión de pantalla, sin importar cambios en el timestamp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:32:31 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c4154b5b61 fix(turnero): deduplicar historial de llamados por turno en pantalla TV
El array 'llamados' acumulaba una entrada por cada lugar al que pasaba
un turno (recepción + toma de muestras). Al insertar un nuevo llamado
se elimina la entrada previa del mismo turno, dejando solo el último lugar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:28:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 910edeb876 feat(turnero): botón de llamado por registro en lugar/toma de muestras
- Agrega botón campana por cada card en cola (solo turnos en_espera_lugar)
- Click en card abre ficha sin llamar; campana llama ese turno específico
- Llamar siguiente ahora también llama de verdad (antes solo abría ficha)
- Cards en_servicio mantienen indicador de estetoscopio sin botón

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:25:34 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6adbcc3059 feat(turnero): modal completo de paciente en recepción
- Reemplaza window.open a lab_pacientes.php por modal Bootstrap inline
- Modal incluye campos completos: datos personales, contacto (con verificador WA), ubicación y EPS
- Botón Ver/Editar en paciente vinculado carga datos desde API y abre modal en modo edición
- Botón Cambiar desvincula y enfoca el buscador
- Al crear: seleccionarPaciente() auto-vincula al turno y cierra modal
- Al editar: actualiza labels en pantalla sin perder el turno activo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:02:24 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e90cfda3f3 feat(dashboard): accesos rápidos en dropdown por grupo, filtrado por rol
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 09:03:57 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d6e1d083f4 revert(sidebar): eliminar sub-acordeón — restaurar sidebar y module.php a estado estable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:56:42 -05:00
Lizandro Guarnizo f724e2e94c Revert "fix(recepcion): mostrar nombre, cédula y celular en resultados de búsqueda de paciente"
This reverts commit 1af731ee44.
2026-06-24 08:54:17 -05:00
Lizandro Guarnizo 86be0669af Revert "fix(recepcion): reemplazar template literals anidados por concatenación compatible"
This reverts commit 0021af36a5.
2026-06-24 08:54:17 -05:00
Lizandro Guarnizo 3b1b7c9333 Revert "fix(sidebar): null-check en route de children para evitar TypeError en PHP 8.2"
This reverts commit ba27511414.
2026-06-24 08:54:17 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ba27511414 fix(sidebar): null-check en route de children para evitar TypeError en PHP 8.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:52:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 0021af36a5 fix(recepcion): reemplazar template literals anidados por concatenación compatible
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:50:47 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1af731ee44 fix(recepcion): mostrar nombre, cédula y celular en resultados de búsqueda de paciente
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:45:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 af584bcc26 feat(pacientes): verificar WhatsApp al ingresar teléfono, vincular user_id al guardar
fix(recepcion): mostrar nombre_completo en resultados de búsqueda de paciente

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:44:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 bbee9c0a5c feat(sidebar): sub-acordeón para recepción y estaciones de muestras en turnero
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:35:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 90baff34f9 fix(turnero): agregar sidebar toggle en vistas standalone (recepcion, lugar, configuracion)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:31:08 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 da594e0021 fix(dashboard): mostrar todos los escritorios y lugares sin agrupar ni limitar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:28:06 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5f0565eca2 feat(dashboard): quitar botón atrás, agregar accesos rápidos a recepción y lugares
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:24:36 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 841acf9a85 feat(turnero): filtrar sidebar por rol — recep ve solo sus desks, bacteriologo ve sus estaciones
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:56:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 0f07ee22c7 feat: dropdown destino muestra Toma de Muestras, Pediatría y Ginecología
Las 8 estaciones de muestras ya comparten grupo_id=1, así que se
agrupan en una sola opción 'Toma de Muestras'. Pediatría y Ginecología
tienen grupo_id=NULL y aparecen como destinos independientes.
Cualquier estación del grupo ve los turnos asignados a él.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:39:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c0f99fe9bc feat: mostrar todos los lugares destino en dropdown de recepción
El dropdown solo mostraba el primer lugar tipo muestras (LIMIT 1).
Ahora carga todos los lugares activos tipo muestras, incluyendo
Pediatría y Ginecología que ya estaban en la BD.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:37:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f533891c5e fix: transición no permitida al pasar a lugar desde turno en espera
Cuando la recepcionista seleccionaba un turno de la cola sin llamarlo
formalmente (via seleccionarTurno), el turno quedaba en estado espera
en BD. Al intentar pasar a lugar, espera→en_espera_lugar no es válido.

Fix: en create_solicitud.php, si el turno está en espera al guardar
la solicitud, se promueve a en_recepcion en el mismo transaction,
preservando timestamps existentes con COALESCE.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:36:36 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 64f2e7c784 fix: recepcion_desk_id quedaba NULL en historial
Agregado selector de escritorio al abrir recepcion.php sin desk_id.
Si hay múltiples escritorios muestra un modal para elegir; si hay uno
solo se asigna automáticamente. Así recepcion_desk_id siempre queda
registrado en el turno y aparece correctamente en el historial.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:27:28 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e80c1d180d fix: eliminar auto-llamado al siguiente turno tras pasar a lugar
La recepcionista debe llamar manualmente al siguiente turno.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:04:44 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 449b492eea fix: turno aparecía 3 veces en lista de llamados en display_global
El llamados.unshift no estaba protegido por callKey, así que el mismo
turno se agregaba una vez por cada escritorio de recepción. Ahora tanto
el anuncio como la entrada en la lista usan el mismo guard callKey.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 01:00:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 92adee6285 fix: display global sonaba 3 veces con 3 escritorios de recepción
Cuando recepcion_desk_id es NULL, el mismo turno aparecía en los 3
escritorios de recepción con claves distintas (incluían el nombre del
escritorio). Eso generaba 3 entradas nuevas en lastSeenKeys → 3 anuncios.

Fix: añadir announcedCalls Set con clave id|llamado_at (sin destino).
El sonido/anuncio solo se encola una vez por evento de llamada,
independientemente de cuántos escritorios devuelvan el mismo turno.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:54:56 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4058cfe929 fix: sonido del turno se disparaba 3 veces en la pantalla TV
Dos causas:
1. sse_turno.php inicializaba \$lastPing = null, haciendo que la primera
   iteración del loop (2s después del emit inicial) siempre emitiera
   un snapshot extra aunque no hubiera cambios reales.
   Fix: inicializar \$lastPing con el sse_ping_at actual de la BD.

2. display.php comparaba activo.codigo para detectar nueva llamada.
   Si el poll y el SSE llegaban casi simultáneamente antes de que
   lastCodigoActivo se actualizara, ambos disparaban el sonido.
   Fix: comparar llamado_at en vez del código — el timestamp es
   único por llamada, por lo que sonidos duplicados son imposibles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:48:33 -05:00