- 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
Limpia la UI del selector de intensidad para una experiencia más minimalista:
- Eliminado atributo title que mostraba tooltips con el valor
- Eliminada sección completa de indicadores numéricos (min/valor/max)
- El componente ahora solo muestra los iconos interactivos
- Mantiene toda la funcionalidad (selección, hover, deselección)
La interfaz es ahora más limpia y el usuario puede confiar en el feedback visual de los iconos activos para conocer el valor seleccionado.
Crea nuevo componente SelectorIntensidad que reemplaza los sliders tradicionales por un selector tipo "rating" con iconos clicables:
Características del nuevo componente:
- Usa círculos (circle/circle-dot) para intensidad descriptiva
- Usa corazones (heart) para intensidad afectiva
- Los iconos se llenan hasta el valor seleccionado
- Efecto hover para preview
- Mismo rango: descriptiva (1-10), afectiva (1-15)
- Click en mismo valor lo deselecciona (vuelve a null)
- Soporte para colores personalizados
- Efectos de glow en modo oscuro
- Responsive (iconos más pequeños en móvil)
Cambios técnicos:
- Nuevo archivo: app/components/cata/SelectorIntensidad.vue
- Modificado: app/components/cata/FormularioMuestra.vue
- Reemplazado CataSliderIntensidad por CataSelectorIntensidad (global)
- Mantiene la misma interfaz de props y eventos que SliderIntensidad