El filtro brightness(0) invert(1) hacía invisible logos con fondo claro.
Ahora el logo se muestra sobre una píldora blanca semitransparente,
visible independientemente de los colores del logo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- item-row con flex-wrap para que los tags pasen a la siguiente línea
- consent-tag con word-break y max-width para textos largos
- Botones de acción agrupados en .item-actions con margin-left:auto
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Logo:
- Carga doc_logo_base64 y empresa_nombre desde lab_config
- Header muestra logo (filtro invert para fondo oscuro) o ícono fallback
- Nombre del laboratorio siempre visible debajo, nunca cambia por página
- Ícono de configuración reposicionado en esquina superior derecha
Colapso de módulos:
- Bug: transición CSS se disparaba durante init causando estado inconsistente
- Fix: inyecta <style> temporal con transition:none antes de aplicar estados,
lo remueve en el siguiente frame para que las animaciones funcionen luego
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Header con avatar de iniciales + gradiente brand + subtítulo
- Secciones agrupadas en cards con fondo sutil y borde brand
- Todos los campos usan form-floating (labels animados)
- Footer con botones mejor definidos y gradiente brand
- Avatar se actualiza en tiempo real al escribir el nombre
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Builder:
- Picker de valor ahora es <select multiple> — Ctrl+clic para varios
- Al re-editar un separador, los valores guardados quedan preseleccionados
- aplicarCampo() guarda siempre como condicion.valores (array)
- Badge en canvas muestra todos los valores separados por coma
form_cliente.php / iniciarCondiciones():
- Soporta tanto .valor (string legacy) como .valores (array nuevo)
- Evaluación: activo si CUALQUIER valor de la lista está marcado
BD (ya aplicado):
- Formulario id=15 actualizado con condiciones en los separadores
- Taukit → valor único; Heliprobe → valor único
- Glicemia/Prolactina/etc. → valores[] con todos los prolongados
- Cortisol AM/PM → valores[] para sección de tomas hora fija
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nueva sección WEBSms en lab_configuracion.php con:
- Switch activo/inactivo (sms_activo)
- Campo URL base de la API (sms_url)
- Campo API key / Bearer token (sms_api_key)
- Campos de prueba: número + mensaje + botón Enviar
- api/lab/test_sms.php: proxy al endpoint POST /api/sms/send
con Authorization: Bearer, valida respuesta ok/error
- save_config.php: permite guardar sms_url, sms_api_key, sms_activo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Builder:
- Separadores tienen nuevo panel "Visible solo si [campo] = [valor]"
- Selector de campo (checkbox/radio/select del mismo form)
- Selector de valor se actualiza dinámicamente al elegir el campo
- Badge visual en el canvas muestra la condición configurada
- Condición se guarda en campo.condicion { campo_id, valor }
form_cliente.php:
- iniciarCondiciones() evalúa condiciones al cargar y al cambiar campos
- Secciones sin la opción marcada se ocultan (max-height:0, pointer-events:none)
- Se muestran con transición suave al marcar la opción correspondiente
- Cada campo tiene data-campo-id para que la lógica pueda localizarlo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Toggle activo/inactivo en configuración → guarda ia_activa en lab_config
- Botón "Probar" llama api/lab/test_gemini.php con la clave actual
- test_gemini.php envía pregunta mínima a Gemini y confirma respuesta
- Dashboard oculta botón y panel IA cuando ia_activa != '1'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Campo N.° Orden editable en la ficha, antes de seleccionar paciente
- Se carga automáticamente al abrir un turno (YYYYMMDD-001, 002…)
- Botón para regenerar el siguiente consecutivo
- Columna numero_orden en turnero_solicitudes (VARCHAR 20)
- Nuevo endpoint get_consecutivo.php calcula el siguiente del día
- create_solicitud.php guarda el numero_orden junto con la solicitud
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Icono de engranaje (⚙) en cabecera del sidebar → lab_configuracion.php
- Buscador de texto que filtra ítems del menú en tiempo real
- Al borrar la búsqueda restaura el estado colapsado guardado
- CSS integrado en el mismo componente
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Columnas añadidas: Recepción (desk + recepcionista), Lugar/Bacteriólogo, Exámenes
- Elimina columnas Lugar y Entrada que eran menos informativas
- colspan actualizado a 10
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cada sección del menú se puede abrir/cerrar con clic
- Estado persiste en localStorage por categoría
- La sección con el link activo siempre se auto-expande
- Chevron rota al colapsar con transición suave
- CSS en styles.css actualizado para que sidebar-section sea clickeable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- sidebar.php inyecta --brand/--brand-dark desde DB si no fueron definidos ya
por Layout.php, solucionando que lab_*.php mostraran el sidebar azul (fallback)
mientras las páginas ERP mostraban verde (#a0a59c del doc_color)
- Gradiente del sidebar invertido: ahora va de más oscuro (top) a brand (bottom)
en lugar de terminar con mezcla blanca que perdía las letras
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Si llega con desk_id redirige a la URL canónica erp.php?m=turnero&v=recepcion&desk_id=N
- Si llega sin desk_id muestra lista de turnero_lugares activos para elegir
- Elimina acceso directo sin contexto de desk
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ai_chat.php: contexto completo (tiempos, facturación, franjas, turnos detallados)
- Preguntas soportadas: demoras por recepcionista, total facturado, horas pico,
tiempo total por paciente, exámenes, búsqueda por cédula
- Panel flotante de chat en dashboard (botón robot azul)
- Búsqueda de tabla ahora filtra por cédula/documento
- Ícono de fila gira al expandir detalle (flecha → rotada)
- lab_configuracion.php: nueva sección IA con campo token Gemini
- save_config.php: permite guardar gemini_api_key
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Columnas nuevas en tabla principal:
- Recepción: módulo de desk + nombre del recepcionista
- Lugar / Bacteriólogo: lugar destino + quien atendió toma de muestras
- Exámenes: badges con código de cada examen solicitado
Los datos ya venían del API (get_historial.php), solo se exponen en la tabla.
Se elimina columna Teléfono y Entrada de la vista principal (siguen en detalle).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- table-hover, form-control:focus, btn-primary, menu-item hover
- Usar var(--brand, fallback) para que funcione sin Layout.php
- Contextos chat/WhatsApp mantienen su verde propio
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Eliminar comentarios {{-- --}} de Blade que se renderizaban como texto visible
- Inyectar --brand/--brand-dark desde doc_color de BD (igual que Layout.php)
- Modal header con gradiente brand igual que login/sidebar
- Secciones de formulario con separadores visuales (Datos, Contacto, Ubicación)
- Panel detalle con header brand en lugar de card-header blanco
- Actualizar version CSS a v=13
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Layout.php inyecta --brand y --brand-dark desde doc_color de BD
- Sidebar usa el mismo gradiente azul del login (brand-dark → brand)
- Círculos decorativos animados igual que el login
- Items activos: fondo blanco con texto brand (inverso al fondo)
- Hover: overlay blanco sutil + translateX(3px)
- Ancho unificado en --sidebar-width (270px)
- Breakpoint responsive consistente en 991.98px
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Eliminar .env del tracking de git (credenciales no deben ir en repo)
- Agregar .env y .env.* al .dockerignore (no hornear credenciales en imagen)
- Quitar extension=redis.so duplicada en php.ini
- Activar cache 7d para assets estáticos en nginx
- Corregir 5 migraciones: eliminar INSERT INTO migrations con columna incorrecta
y remover semicolons en comentarios -- que partian el parser SQL
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
El servidor Redis vive fuera (recurso gestionado por Coolify); el app se
conecta vía REDIS_HOST. El servicio redis local era un contenedor muerto.
La extensión PHP phpredis se sigue compilando en la imagen (es el cliente).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
validate_timestamps=0 hacía que PHP-FPM sirviera código viejo para siempre;
el opcache_reset del entrypoint corre en CLI (OPcache separado) y no limpiaba
el de FPM. Ahora valida mtimes cada 2s — costo despreciable para un ERP.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dos despliegues que comparten el mismo Redis pisaban las sesiones.
session.save_path ahora incluye &database=${REDIS_DB} (default 0).
Despliegue secundario usa REDIS_DB=1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
create_consent_token.php ahora acepta paciente_id y lo vincula al turno
si aún no lo tiene, eliminando la carrera con vincular_paciente.php
(fire-and-forget). Ya no hace falta refrescar para firmar el consentimiento.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Escribir manualmente ya no dispara el turno: la persona oprime el botón.
El lector de cédula sí lo dispara porque mete los dígitos en ráfaga
(<35ms entre cada uno) o termina con Enter. Guard contra doble envío.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
La firma se guardaba en datos_cliente[campo_svg] pero el display
solo leía firma_profesional_svg (columna inexistente en lab_form_envios).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Kiosko: detector scanner (gap < 80ms), iconos 90px, fa-person-pregnant, ticket Arial
- Recepción: vincular_paciente.php para persistir paciente_id antes de firmar consentimiento
- Historial y dashboard: recepción desk, empleado recepción/muestras, exámenes y comentarios
- display_global: turno más pequeño, lugar-nombre más grande
- lab_pacientes: modal compacta con form-sm
- Configuración: icono embarazada fa-person-pregnant en prioridades
- ver_formulario_enviado: firma por campo (fix doble firma)
- docker-compose.local.yml: override BD producción para dev local
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>