- Sabores ahora usa mismo formato de 2 columnas que Fragancia-Aroma
- Ambas secciones con fuente más pequeña y espaciado compacto (2.6mm)
- Sensación en boca: layout horizontal en 2 filas (3 + 2)
- Gustos predominantes: layout horizontal en 2 filas (3 + 2)
- Ajustadas posiciones Y de las secciones inferiores
- Cambiar a 2 formularios por hoja para más espacio vertical
- Corregir distribución de familias de notas (Floral, Afrutado, Verde/Vegetal, Otra, Tostado, etc.)
- Aumentar margen vertical entre checkboxes
- Corregir "beberse" → "haberse" en sección de defectos
- Alinear checkboxes de defectos bajo el header
- Quitar recuadro de Notas y mostrar solo "Notas: valor"
- Implementar módulo de generación PDF con jsPDF
- Crear composable usePdfExport para exportar muestras y sesiones
- Añadir botones de exportación PDF en header y por muestra
- Replicar layout exacto del formulario físico IHCAFE
- Soportar máximo 3 formularios por hoja carta
- Actualizar límites de input HTML de min=3/max=7 a min=1/max=10
- Actualizar validación JavaScript para permitir entre 1 y 10 muestras
- Actualizar textos de ayuda y placeholder
- Mantener valor por defecto en 5 muestras
- Remover fondos rellenos de intensidades, defectos, organoléptica y notas
- Mantener fondo relleno solo en elementos seleccionados (categoria-chip)
- Aplicar cambios tanto en modo claro como oscuro
- Cambiar botón expandir a estilo texto (solo icono)
- Agregar colores específicos por categoría a iconos de intensidades
- Agregar sección de características organolépticas con notas
- Agregar sección de notas adicionales
- Cambiar badges de puntajes a solo outline (sin relleno)
- Respetar preferencias de color del usuario en badges excepto SCAA
- Corregir tipo de longPressTimer (ReturnType<typeof setTimeout>)
Implementación completa de vista detallada para muestras:
Componentes nuevos:
- ResumenMuestraExpandido: Vista no compacta con valores claramente visibles
- ModalResumenExpandido: Modal reutilizable para mostrar vista expandida
Integraciones:
- Calculadora SCAA: Usa vista expandida en paso 3
- Página de sesión:
* Long press en móvil (500ms) en header del accordion
* Botón expandir en desktop cerca del título
* Vibración háptica en móvil al activar
Características:
- Grid responsivo de intensidades afectivas
- Puntajes destacados (Σ y SCAA) con colores según valor
- Visualización clara de penalizaciones
- Diseño adaptativo móvil/desktop
Implementado flujo de asignación rápida reutilizable en modo calculadora
para la página principal, permitiendo calcular SCAA Score sin sesión.
Cambios:
- ModalAsignacionRapida: Nuevo modo 'calculadora' con paso 3
- Paso 3 incluye ResumenMuestra y penalizaciones configurables
- Función generadora de muestra genérica para vista previa
- Botón "Calculadora SCAA" en página principal
- Navegación mejorada entre pasos (Volver/Continuar)
RESTAURADO:
- capture_links: 'existing-client-navigate'
- handle_links: 'preferred'
- url_handlers: [{ origin: 'https://riocata.nucleoriofrio.com' }]
SOLUCIÓN:
- Agregados comentarios @ts-ignore antes de cada propiedad
- Propiedades experimentales no incluidas en tipos oficiales
- PWA manifest sigue funcionando correctamente
- TypeScript typecheck sigue pasando sin errores
NOTAS:
Estas propiedades son parte del estándar PWA experimental
para captura de enlaces y manejo de URLs, esenciales para
la funcionalidad de la aplicación.
ERRORES RESUELTOS:
1. Colores de botones inválidos → colores válidos:
- 'orange' → 'warning' (BackendVerificationButton)
- 'purple' → 'primary' (FrontendVerificationButton)
- 'red' → 'error' (CheckAuthentikAdminsButton)
- 'blue' → 'info' (CheckGrupoPruebaButton)
- 'green' → 'success' (CheckLvl0Button)
- 'gray' → 'neutral' (CheckPublicAccessButton, UserMetadata)
2. Tipos no exportados en Nuxt UI v4:
- Removidos imports: ButtonColor, ButtonVariant, ButtonSize
- Reemplazados con tipos literales inline
- Removido 'none' de variant (no válido en v4)
3. Subcategoria puede ser null:
- FormularioMuestra: tipo cambiado a Exclude<Subcategoria, null>
- sesion.vue: agregado ?? 'null' para key y guards para null
4. process.client no definido:
- useCatacion.ts: process.client → import.meta.client (2 lugares)
- Nuxt 4 usa import.meta.client en lugar de process.client
5. process.env en nuxt.config.ts:
- Removido process.env.NUXT_PUBLIC_AUTHENTIK_URL
- Nuxt runtimeConfig lee automáticamente de .env
- Solo valor por defecto necesario
6. Propiedades no válidas en PWA manifest:
- Removido: capture_links (no existe en ManifestOptions)
- Removido: url_handlers (no existe en ManifestOptions)
- Removido: handle_links (no existe en ManifestOptions)
7. Toast props no válidas:
- Removido: timeout (no existe en Toast type)
- BackendVerificationButton y FrontendVerificationButton
RESULTADO:
✅ npx nuxi typecheck pasa sin errores
✅ Solo warnings de @nuxt/content (no críticos)
CAMBIOS EN OVERLAY:
1. Blur más agresivo:
- Antes: blur(10px)
- Ahora: blur(16px)
- Efecto mucho más pronunciado
2. Opacidad aumentada:
- Antes: 0.90 (90%)
- Ahora: 0.95 (95%)
- Fondo casi completamente opaco
ESTILOS PERSONALIZADOS PARA UInputNumber:
1. Input principal:
- background-color: var(--cata-bg)
- color: var(--cata-text)
- border-color: var(--cata-primary) con transparencia
2. Estado focus:
- border-color: var(--cata-primary) sólido
- box-shadow con color primario
- En dark mode: glow effect adicional
3. Placeholder:
- color: var(--cata-text) al 50% de opacidad
- Respeta el color del texto del usuario
4. Botones +/-:
- color: var(--cata-primary)
- Hover: opacity 0.8
- Active: scale 0.95 (feedback táctil)
5. Modo oscuro:
- Border más visible (40% de primary)
- Box-shadow con glow effect en focus
RESULTADO:
- UInputNumber ahora respeta completamente los colores del usuario
- Overlay con blur muy pronunciado para mejor enfoque
- Consistencia visual con el resto de la aplicación
CAMBIOS:
1. Blur aumentado de 4px a 10px:
- Antes: backdrop-filter: blur(4px)
- Ahora: backdrop-filter: blur(10px)
- Efecto más agresivo en el fondo
2. Opacidad aumentada de 0.85 a 0.90:
- Fondo ligeramente más oscuro
- Mejor enfoque en el modal
3. Compatibilidad mejorada:
- Agregado -webkit-backdrop-filter para WebKit
- Mejor soporte en Safari y navegadores basados en Chromium
RESULTADO:
El modal ahora tiene un efecto de blur medianamente agresivo
que ayuda a enfocar la atención en el contenido del modal.
CAMBIOS PRINCIPALES:
1. Reemplazar inputs normales por UInputNumber:
- Ahora tienen botones +/- integrados
- Mejor UX con controles visuales
- Validación automática de min/max/step
2. Configuración de cada input:
- Sumatoria Afectiva: step="1" (8-72)
- SCAA Score: step="0.25" (58.00-100.00)
- SCAA con format-options para 2 decimales
3. Doble sistema de handlers:
a) Para botones +/- (@update:model-value):
- onSumatoriaChangeFromButtons()
- onScaaChangeFromButtons()
- Sincronización AUTOMÁTICA e INMEDIATA
- No espera blur, actualiza al instante
b) Para escritura manual (@blur):
- onSumatoriaBlur()
- onScaaBlur()
- Validación solo al perder foco
- Permite edición libre
4. Sincronización bidireccional:
- Modificar Sumatoria → actualiza SCAA
- Modificar SCAA → actualiza Sumatoria
- Funciona con botones +/- Y con escritura manual
BENEFICIOS:
✅ Botones +/- funcionan de 1 en 1 y 0.25 en 0.25
✅ Sincronización automática al usar botones
✅ Edición manual sigue funcionando (solo valida en blur)
✅ Mejor UX con controles visuales
✅ SCAA Score muestra siempre 2 decimales
PROBLEMAS RESUELTOS:
1. Inputs actualizaban en cada tecla (@input):
- Impedía borrar números (ej: no se podía borrar el 9)
- Hacía malabares para cambiar valores
2. Rango incorrecto de Sumatoria Afectiva:
- Era 9-90 pero debería ser 8-72
- 8 categorías × 1 punto mínimo = 8
- 8 categorías × 9 puntos máximo = 72
SOLUCIONES:
1. Cambio de eventos:
- @input → @blur en ambos inputs
- Ahora solo actualiza al perder el foco
- Permite editar libremente (borrar, reescribir)
2. Rangos corregidos:
- Sumatoria Afectiva: 8-72 (antes 9-90)
- SCAA Score: 58.00-100.00 (antes 58.75-112.00)
- Valor por defecto: 40 (antes 45)
3. Validaciones mejoradas:
- No valida mientras se escribe
- Solo valida al perder foco (blur)
- Maneja valores inválidos (NaN, null) reseteando a 40
- Permite borrar y reescribir sin restricciones
BENEFICIOS:
- Ahora se puede borrar el 9 sin problemas
- Se puede escribir cualquier número sin interferencias
- La sincronización ocurre solo al terminar de editar
PROBLEMA:
El SCAA Score debe moverse en steps de 0.25 (no aceptar
cualquier valor decimal racional).
SOLUCIÓN:
1. Nueva función en catacion.ts:
- redondearA025(): Redondea al múltiplo de 0.25 más cercano
- Math.round(valor / 0.25) * 0.25
2. Aplicado en todas las funciones de SCAA:
- calcularSCAA(): redondea el resultado final
- sumatoriaAfectivaASCAA(): redondea la conversión
3. ModalAsignacionRapida.vue:
- Input step cambiado de 0.01 a 0.25
- onScaaChange(): redondea el valor ingresado
- Placeholder actualizado: 58.75-112.00
VALORES VÁLIDOS:
Ahora el SCAA Score solo puede tener valores como:
- 85.00, 85.25, 85.50, 85.75, 86.00, etc.
- Nunca valores como 85.17 o 85.33
La visualización con .toFixed(2) sigue mostrando 2 decimales
correctamente.
CAMBIOS EN ResumenMuestra.vue:
1. Header de acordeón ahora muestra DOS puntajes:
- Sumatoria Afectiva (Σ): suma de valores afectivos (1-9)
- SCAA Score: score calculado con fórmula completa
2. Layout:
- Ambos badges alineados a la derecha
- Centrados verticalmente en el header
- Sumatoria con color neutro (primary)
- SCAA con colores según valor (excelente/muy-bueno/bueno/regular/bajo)
3. Badges compactos:
- Label abreviado: "Σ" para Sumatoria, "SCAA" para SCAA Score
- Valores con 2 decimales para SCAA
- Responsive: se ajustan en mobile
4. Colores según SCAA Score:
- ≥90: Verde (excelente)
- ≥85: Azul (muy bueno)
- ≥80: Naranja (bueno)
- ≥70: Rojo (regular)
- <70: Gris (bajo)
- Reemplazar texto "Target:" por icono de diana (i-lucide-target)
- Mostrar icono con color primario + puntaje deseado
- Más visual e intuitivo
- Igualar opacidad de badges descriptivo y afectivo
- Cambiar todos los badges descriptivos de opacity: 0.4 a 0.7
- Ahora ambos badges tienen la misma tonalidad/visibilidad
- Aplica en todas las categorías (Fragancia, Aroma, Sabor, etc.)
- Hacer badges de filtro rectangulares
- Cambiar border-radius de subcategoria-chip de 9999px a 0.375rem
- Consistencia visual con el resto de badges y botones rectangulares
- Aplica a filtros de subcategorías debajo de tabs
- Cambiar color del backdrop/overlay del modal
- Usar color de fondo del usuario (var(--cata-bg))
- Aplicar opacidad de 0.85
- Mantener blur de 4px para efecto de profundidad
- Agregar puntaje target en footer del paso 2
- Mostrar "Target: [puntaje]" alineado a la izquierda
- Botones (Cancelar/Aplicar) alineados a la derecha
- Usar justify-between para distribución espaciada
- Mejorar experiencia visual con colores personalizados del usuario
- Eliminar componente BotonNubeCaustica.vue (ya no necesario)
- Reemplazar botón especial por botón estándar con clase cata-button
- Arreglar estilos del modal para respetar colores personalizados del usuario
- Aplicar clases cata-bg a content, header, body y footer
- Aplicar clase cata-text al título mediante slot personalizado
- Aplicar clase cata-outline-box al content para bordes consistentes
- Agregar backdrop-blur-sm al overlay
- Mantener consistencia visual con el resto de la aplicación
- Agregar watcher que resetea el estado cuando el modal se abre
- Asegurar que puntajeDeseado siempre inicie en 40
- Eliminar setTimeout del método cerrar() (ya no necesario)
- Soluciona problema donde el botón Continuar no funcionaba con valor 40
- Eliminar descripción del modal
- Simplificar paso 1: solo input sin textos explicativos
- Simplificar paso 2: subtítulo compacto con [icono] + "Sobresale"/"Palidece" + x/t
- Eliminar texto de contador duplicado
- Eliminar sección de resumen de distribución
- Interfaz más limpia y directa
- Categorías que sobresalen: flecha arriba (i-heroicons-arrow-up-circle-solid)
- Categorías que palidecen: flecha abajo (i-heroicons-arrow-down-circle-solid)
- Mantener color del icono según el color de cada categoría
- Actualizar ModalAsignacionRapida a sintaxis correcta de Nuxt UI v4
- Usar v-model:open en lugar de v-model
- Usar slots #body y #footer directamente
- Eliminar UCard (deprecado)
- Aplicar clases cata-* para mantener consistencia con el resto de la app
- Usar cata-text para textos
- Usar cata-button para botones
- Usar cata-input para inputs
- Usar cata-outline-box para bordes
- Respetar colores personalizados del usuario mediante variables CSS
- selected-category usa var(--cata-primary)
- Soporte para modo oscuro con efectos de sombra
- Eliminar icono de estrella/rayo del BotonNubeCaustica
- Simplificar diseño dejando solo la nube con patrones cáusticos
- Eliminar animación sparkle asociada
- Integrar modal correctamente en FormularioMuestra
- Mover botón dentro del slot por defecto del modal
- Eliminar modal duplicado del template
- Crear ModalAsignacionRapida.vue con lógica de distribución por múltiplos de 8
- Input numérico (8-80) para puntaje total deseado
- Cálculo automático del múltiplo de 8 más cercano
- Si múltiplo < valor: permite seleccionar categorías que sobresalen (+1)
- Si múltiplo > valor: permite seleccionar categorías que palidecen (-1)
- Si múltiplo = valor: asignación directa sin ajustes
- Crear BotonNubeCaustica.vue con diseño especial
- Forma de nube usando SVG path
- Animación de patrones de luz cáustica con gradientes animados
- Efectos de brillo y ondas al hacer hover
- Icono de rayo mágico con animación sparkle
- Integrar funcionalidad en FormularioMuestra.vue
- Ubicar botón en esquina superior izquierda de sección Descriptiva/Afectiva
- Aplicar puntajes calculados a todas las categorías descriptivas
- Actualizar puntaje final automáticamente
- Corregir comentario: "Suma de valores descriptivos" (era "afectivos")
- Modificar calcularPuntajeFinal para sumar intensidades descriptivas
en lugar de afectivas
- Actualizar comentarios JSDoc para reflejar el cambio
- El puntaje final ahora refleja correctamente la suma de todas las
puntuaciones descriptivas (1-10) de cada categoría
- Evitar deselección al presionar el mismo corazón/círculo ya seleccionado
- Cambiar iconos de corazón de Lucide a Heroicons para mejor distinción visual
- No seleccionado: i-heroicons-heart (outline)
- Seleccionado: i-heroicons-heart-solid (relleno)
- Eliminar clase CSS icono-filled innecesaria
- Crear subcategorías dinámicas basadas en las muestras de la sesión
- Los filtros en Impresión Global ahora controlan qué muestras se muestran
- Filtrar accordionItems según subcategorías activas en impresion-global
- Cada muestra aparece como opción de filtro con su nombre o "Muestra #"
- Incluir selector de Sensación en la Boca en la sección Organoléptica de Impresión Global
- Incluir selector de Gustos Predominantes en la sección Organoléptica de Impresión Global
- Mantener la misma funcionalidad y estilos que en la tab Organoléptica
- Reducir tamaño de iconos de 1.5rem a 1rem en SelectorIntensidad
- Reducir espaciado entre iconos y padding del contenedor
- Cambiar gap de grids de sliders de 4 a 2
- Implementar filtrado restrictivo por tipo (descriptiva/afectiva) y categoría
- Agregar computed properties individuales para cada slider
- Cuando se selecciona "Afectiva" + "Sensación en la Boca", solo se muestra ese slider específico
- Eliminar grid en desktop para categorías principales de SelectorFamilia
- Usar flex-wrap en todos los tamaños de pantalla (igual que subcategorías)
- Mantener solo incremento de min-height en desktop (40px vs 32px)
- Resultado: categorías ahora fluyen en una sola fila con wrap cuando es necesario
CAMBIOS EN SENSACIONES EN BOCA:
- Reducir opciones a solo 5: Áspero, Aceitoso, Metálico, Deja seca la boca, Suave
- Cambiar de selección múltiple a selección única
- Actualizar tipo de sensacionEnBoca: SensacionBoca[] → SensacionBoca | null
CAMBIOS EN CHECKBOXES (sensaciones y gustos):
- Hacer checkboxes tan compactos como subcategorías de SelectorFamilia
- Usar flex-wrap en todos los breakpoints (eliminar grid en desktop)
- Dimensiones ultra compactas:
* Desktop: min-height 32px, padding 0.375rem 0.5rem, font-size 0.75rem
* Mobile: min-height 28px, padding 0.25rem 0.375rem, font-size 0.6875rem
* Touch: min-height 36px para dispositivos táctiles
ARCHIVOS MODIFICADOS:
- app/types/catacion.ts: Actualizar SensacionBoca y SENSACIONES_BOCA
- app/composables/useCatacion.ts: Cambiar actualizarSensacionBoca a selección única
- app/components/cata/FormularioMuestra.vue: UI compacta y selección única
- app/components/cata/ResumenMuestra.vue: Adaptar a sensacionEnBoca única
- Cambiar layout de grid fijo a flex-wrap en mobile para sensaciones y gustos
- Mantener grid responsive en desktop (3 columnas para sensaciones, 5 para gustos)
- Reducir significativamente todas las dimensiones para mayor compactación:
* Desktop: min-height 36px, padding 0.375rem 0.5rem
* Mobile: min-height 28px, padding 0.25rem 0.375rem
* Font-size: 0.75rem desktop, 0.6875rem mobile
- Agregar animaciones y estados focus consistentes
- Touch-friendly en dispositivos táctiles (36px min-height)
- Cambiar de type='multiple' a type='single' (solo un item abierto a la vez)
- Todos los accordions pueden estar cerrados (collapsible: true por defecto)
- Actualizar estado accordionAbierto de string[] a string | undefined
- Actualizar lógica toggleCollapseAll para modo single
- Agregar border-t al content del accordion para mejor separación visual
- Actualizar títulos del botón flotante: 'Abrir primera muestra' / 'Cerrar muestra abierta'
- Alinear puntaje final a la derecha en ResumenMuestra (ml-auto)
- Cambiar estilo de accordion: underline simple sin gap entre items
- Ajustar ancho 100% en móviles sin padding lateral (px-0 sm:px-4)
- Eliminar headers redundantes en tabs específicas:
* Organoléptica: eliminar 'Características Organolépticas'
* Descriptiva/Afectiva: eliminar 'Intensidades Descriptivas y Afectivas'
* Defectos: eliminar 'Defectos y Uniformidad'
- Mantener headers en tab Impresión Global para mejor navegación
- Agregar función getCategoryIcon() en FormularioMuestra y ResumenMuestra
- Iconos Lucide para cada categoría:
* fragancia: flower-2, aroma: wind, sabor: candy
* saborResidual: timer, acidez: citrus, dulzor: cookie
* sensacionBoca: droplets, impresionGlobal: star
- Actualizar todos los títulos de sección con iconos
- Modificar chips de ResumenMuestra para mostrar solo icono + valor descriptivo
- Eliminar valores afectivos y emojis de chips
- Agregar estilos CSS para .chip-icon
- Agregar prop tabActiva a ResumenMuestra.vue
- Implementar computed properties para filtrado:
* mostrarChipsOrganolepticos (organoleptica + impresion-global)
* mostrarChipsIntensidades (descriptiva-afectiva + impresion-global)
* mostrarChipsDefectos (defectos + impresion-global)
- Envolver grupos de chips con template v-if según filtrado
- Pasar prop :tab-activa desde sesion.vue a ResumenMuestra
- En impresion-global se muestran TODOS los chips
- En otras tabs solo chips pertinentes a esa categoría
- Reducir font-size de chips de 0.75rem a 0.625rem (0.5625rem en mobile)
- Reducir padding de chips de 0.25/0.5rem a 0.15/0.35rem
- Reducir gaps: entre chips de 1rem a 0.5rem, en línea de 2rem a 1.5rem
- Reducir tamaño de puntaje final y nombre de muestra
- Abreviar todas las etiquetas de chips:
* F/A (Fragancia/Aroma), Sab (Sabor), Gus (Gustos), Sen (Sensación)
* Fra, Aro, Sb, S.R (Sabor Residual), Aci, Dul, Sn, Imp
* NoUnif (No Uniformes), Defec (Defectuosas)
- Eliminar espacios en arrays join (coma sin espacio)
- Optimizar responsive para mobile aún más compacto
- Cambiar 'cuerpo' por 'sensacionBoca' (propiedad correcta del tipo)
- Cambiar 'balance' por 'impresionGlobal' (propiedad correcta del tipo)
- Las propiedades ahora coinciden con la interfaz Intensidades definida en catacion.ts
- Agregar puntaje final con badge color-coded según rangos
- Agregar chips para categorías organolépticas (fragancia/aroma, sabor, gustos, sensación)
- Agregar chips para todos los valores de intensidad (afectiva ❤️ y descriptiva 📊)
- Agregar chips condicionales para tazas no uniformes (warning)
- Agregar chips condicionales para tazas defectuosas con tipo de defecto (error)
- Layout de dos líneas: header con #/nombre/puntaje y chips informativos
- Diseño compacto y responsive