All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m8s
Modificado para que los chips de intensidades muestren valores afectivos cuando los descriptivos no están disponibles. Útil para la calculadora SCAA.
395 lines
12 KiB
Vue
395 lines
12 KiB
Vue
<template>
|
|
<div class="resumen-muestra w-full">
|
|
<!-- Primera línea: Número, nombre y puntaje -->
|
|
<div class="flex items-center gap-2 mb-1">
|
|
<!-- Número de muestra -->
|
|
<div class="muestra-numero cata-text font-bold flex-shrink-0">
|
|
#{{ muestra.muestraId }}
|
|
</div>
|
|
|
|
<!-- Nombre de muestra -->
|
|
<div class="flex-1 min-w-0">
|
|
<div class="muestra-nombre cata-text font-semibold truncate">
|
|
{{ muestra.nombre }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Puntajes - alineados a la derecha -->
|
|
<div class="puntajes-container flex items-center gap-1 flex-shrink-0 ml-auto">
|
|
<!-- Sumatoria Afectiva -->
|
|
<div class="puntaje-badge puntaje-sumatoria px-2 py-0.5 rounded">
|
|
<span class="puntaje-label">Σ</span>
|
|
<span class="font-bold">{{ sumatoriaAfectiva }}</span>
|
|
</div>
|
|
|
|
<!-- SCAA Score -->
|
|
<div class="puntaje-badge puntaje-scaa px-2 py-0.5 rounded" :class="scaaClass">
|
|
<span class="puntaje-label">SCAA</span>
|
|
<span class="font-bold">{{ scaaScore.toFixed(2) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Segunda línea: Chips informativos -->
|
|
<div class="chips-container flex flex-wrap gap-0.5">
|
|
<!-- Chips Organolépticos -->
|
|
<template v-if="mostrarChipsOrganolepticos">
|
|
<!-- Fragancia/Aroma -->
|
|
<div v-if="muestra.fraganciaAromaNotas.categorias.length > 0" class="chip">
|
|
<span class="chip-label">F/A:</span>
|
|
<span class="chip-value">{{ categoriasFragancia }}</span>
|
|
</div>
|
|
|
|
<!-- Sabor -->
|
|
<div v-if="muestra.saborNotas.categorias.length > 0" class="chip">
|
|
<span class="chip-label">Sab:</span>
|
|
<span class="chip-value">{{ categoriasSabor }}</span>
|
|
</div>
|
|
|
|
<!-- Gustos predominantes -->
|
|
<div v-if="muestra.gustosPredominantes.length > 0" class="chip">
|
|
<span class="chip-label">Gus:</span>
|
|
<span class="chip-value">{{ muestra.gustosPredominantes.join(', ') }}</span>
|
|
</div>
|
|
|
|
<!-- Sensación en boca -->
|
|
<div v-if="muestra.sensacionEnBoca" class="chip">
|
|
<span class="chip-label">Sen:</span>
|
|
<span class="chip-value">{{ muestra.sensacionEnBoca }}</span>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Chips Intensidades (Descriptiva o Afectiva con icono) -->
|
|
<template v-if="mostrarChipsIntensidades">
|
|
<div v-if="muestra.intensidades.fragancia.descriptiva !== null || muestra.intensidades.fragancia.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('fragancia')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.fragancia.descriptiva ?? muestra.intensidades.fragancia.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.aroma.descriptiva !== null || muestra.intensidades.aroma.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('aroma')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.aroma.descriptiva ?? muestra.intensidades.aroma.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.sabor.descriptiva !== null || muestra.intensidades.sabor.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('sabor')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.sabor.descriptiva ?? muestra.intensidades.sabor.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.saborResidual.descriptiva !== null || muestra.intensidades.saborResidual.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('saborResidual')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.saborResidual.descriptiva ?? muestra.intensidades.saborResidual.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.acidez.descriptiva !== null || muestra.intensidades.acidez.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('acidez')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.acidez.descriptiva ?? muestra.intensidades.acidez.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.dulzor.descriptiva !== null || muestra.intensidades.dulzor.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('dulzor')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.dulzor.descriptiva ?? muestra.intensidades.dulzor.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.sensacionBoca.descriptiva !== null || muestra.intensidades.sensacionBoca.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('sensacionBoca')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.sensacionBoca.descriptiva ?? muestra.intensidades.sensacionBoca.afectiva }}</span>
|
|
</div>
|
|
|
|
<div v-if="muestra.intensidades.impresionGlobal.descriptiva !== null || muestra.intensidades.impresionGlobal.afectiva !== null" class="chip chip-intensidad">
|
|
<UIcon :name="getCategoryIcon('impresionGlobal')" class="chip-icon" />
|
|
<span class="chip-value">{{ muestra.intensidades.impresionGlobal.descriptiva ?? muestra.intensidades.impresionGlobal.afectiva }}</span>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Chips Defectos -->
|
|
<template v-if="mostrarChipsDefectos">
|
|
<!-- Tazas no uniformes -->
|
|
<div v-if="muestra.tazasNoUniformes.length > 0" class="chip chip-warning">
|
|
<span class="chip-label">NoUnif:</span>
|
|
<span class="chip-value">{{ muestra.tazasNoUniformes.join(',') }}</span>
|
|
</div>
|
|
|
|
<!-- Tazas defectuosas -->
|
|
<div v-if="muestra.tazasDefectuosas.length > 0" class="chip chip-error">
|
|
<span class="chip-label">Defec:</span>
|
|
<span class="chip-value">{{ muestra.tazasDefectuosas.join(',') }}</span>
|
|
<span v-if="muestra.defecto" class="chip-value">({{ muestra.defecto }})</span>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { Muestra } from '~/types/catacion'
|
|
import type { TabCatacion } from '~/composables/useCatacion'
|
|
import { calcularSumatoriaAfectiva, calcularSCAA } from '~/types/catacion'
|
|
|
|
interface ResumenMuestraProps {
|
|
/** Muestra a mostrar */
|
|
muestra: Muestra
|
|
/** Tab activa para filtrar chips */
|
|
tabActiva?: TabCatacion
|
|
}
|
|
|
|
const props = withDefaults(defineProps<ResumenMuestraProps>(), {
|
|
tabActiva: 'impresion-global',
|
|
})
|
|
|
|
// Cálculos de puntajes
|
|
const sumatoriaAfectiva = computed(() => calcularSumatoriaAfectiva(props.muestra))
|
|
const scaaScore = computed(() => calcularSCAA(props.muestra))
|
|
|
|
// Formatear categorías de fragancia/aroma
|
|
const categoriasFragancia = computed(() => {
|
|
return props.muestra.fraganciaAromaNotas.categorias.slice(0, 2).join(', ')
|
|
})
|
|
|
|
// Formatear categorías de sabor
|
|
const categoriasSabor = computed(() => {
|
|
return props.muestra.saborNotas.categorias.slice(0, 2).join(', ')
|
|
})
|
|
|
|
// Clase CSS para el SCAA Score basado en el valor
|
|
const scaaClass = computed(() => {
|
|
const scaa = scaaScore.value
|
|
if (scaa >= 90) return 'scaa-excelente'
|
|
if (scaa >= 85) return 'scaa-muy-bueno'
|
|
if (scaa >= 80) return 'scaa-bueno'
|
|
if (scaa >= 70) return 'scaa-regular'
|
|
return 'scaa-bajo'
|
|
})
|
|
|
|
// Función para obtener el icono de cada categoría
|
|
const getCategoryIcon = (category: string): string => {
|
|
const icons: Record<string, string> = {
|
|
fragancia: 'i-lucide-flower-2',
|
|
aroma: 'i-lucide-wind',
|
|
sabor: 'i-lucide-candy',
|
|
saborResidual: 'i-lucide-timer',
|
|
acidez: 'i-lucide-citrus',
|
|
dulzor: 'i-lucide-cookie',
|
|
sensacionBoca: 'i-lucide-droplets',
|
|
impresionGlobal: 'i-lucide-star',
|
|
}
|
|
return icons[category] || 'i-lucide-circle'
|
|
}
|
|
|
|
// Determinar qué chips mostrar según la tab activa
|
|
const mostrarChipsOrganolepticos = computed(() => {
|
|
return props.tabActiva === 'organoleptica' || props.tabActiva === 'impresion-global'
|
|
})
|
|
|
|
const mostrarChipsIntensidades = computed(() => {
|
|
return props.tabActiva === 'descriptiva-afectiva' || props.tabActiva === 'impresion-global'
|
|
})
|
|
|
|
const mostrarChipsDefectos = computed(() => {
|
|
return props.tabActiva === 'defectos' || props.tabActiva === 'impresion-global'
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.resumen-muestra {
|
|
min-height: 36px;
|
|
}
|
|
|
|
.muestra-numero {
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.muestra-nombre {
|
|
font-size: 0.8125rem;
|
|
}
|
|
|
|
/* Puntajes */
|
|
.puntajes-container {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.puntaje-badge {
|
|
border: 1px solid;
|
|
min-width: 2rem;
|
|
text-align: center;
|
|
font-size: 0.625rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
justify-content: center;
|
|
}
|
|
|
|
.puntaje-label {
|
|
font-size: 0.5625rem;
|
|
opacity: 0.75;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Sumatoria Afectiva - color neutro */
|
|
.puntaje-sumatoria {
|
|
background-color: color-mix(in srgb, var(--cata-primary) 15%, transparent);
|
|
border-color: color-mix(in srgb, var(--cata-primary) 40%, transparent);
|
|
color: var(--cata-text);
|
|
}
|
|
|
|
/* SCAA Score - colores según valor */
|
|
.scaa-excelente {
|
|
background-color: color-mix(in srgb, #10b981 20%, transparent);
|
|
border-color: #10b981;
|
|
color: #10b981;
|
|
}
|
|
|
|
.scaa-muy-bueno {
|
|
background-color: color-mix(in srgb, #3b82f6 20%, transparent);
|
|
border-color: #3b82f6;
|
|
color: #3b82f6;
|
|
}
|
|
|
|
.scaa-bueno {
|
|
background-color: color-mix(in srgb, #f59e0b 20%, transparent);
|
|
border-color: #f59e0b;
|
|
color: #f59e0b;
|
|
}
|
|
|
|
.scaa-regular {
|
|
background-color: color-mix(in srgb, #ef4444 20%, transparent);
|
|
border-color: #ef4444;
|
|
color: #ef4444;
|
|
}
|
|
|
|
.scaa-bajo {
|
|
background-color: color-mix(in srgb, #6b7280 20%, transparent);
|
|
border-color: #6b7280;
|
|
color: #6b7280;
|
|
}
|
|
|
|
/* Chips */
|
|
.chips-container {
|
|
font-size: 0.625rem;
|
|
line-height: 1.1;
|
|
}
|
|
|
|
.chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.15rem;
|
|
padding: 0.15rem 0.35rem;
|
|
border-radius: 0.2rem;
|
|
background-color: color-mix(in srgb, var(--cata-primary) 10%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--cata-primary) 30%, transparent);
|
|
}
|
|
|
|
.chip-icon {
|
|
width: 0.75rem;
|
|
height: 0.75rem;
|
|
flex-shrink: 0;
|
|
color: var(--cata-primary);
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.chip-label {
|
|
font-weight: 600;
|
|
opacity: 0.75;
|
|
color: var(--cata-text);
|
|
}
|
|
|
|
.chip-value {
|
|
color: var(--cata-text);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.chip-warning {
|
|
background-color: color-mix(in srgb, #f59e0b 15%, transparent);
|
|
border-color: #f59e0b;
|
|
}
|
|
|
|
.chip-warning .chip-label,
|
|
.chip-warning .chip-value {
|
|
color: #f59e0b;
|
|
}
|
|
|
|
.chip-error {
|
|
background-color: color-mix(in srgb, #ef4444 15%, transparent);
|
|
border-color: #ef4444;
|
|
}
|
|
|
|
.chip-error .chip-label,
|
|
.chip-error .chip-value {
|
|
color: #ef4444;
|
|
}
|
|
|
|
/* Modo oscuro */
|
|
.dark .puntaje-sumatoria {
|
|
background-color: color-mix(in srgb, var(--cata-primary) 20%, transparent);
|
|
}
|
|
|
|
.dark .scaa-excelente {
|
|
background-color: color-mix(in srgb, #10b981 30%, transparent);
|
|
}
|
|
|
|
.dark .scaa-muy-bueno {
|
|
background-color: color-mix(in srgb, #3b82f6 30%, transparent);
|
|
}
|
|
|
|
.dark .scaa-bueno {
|
|
background-color: color-mix(in srgb, #f59e0b 30%, transparent);
|
|
}
|
|
|
|
.dark .scaa-regular {
|
|
background-color: color-mix(in srgb, #ef4444 30%, transparent);
|
|
}
|
|
|
|
.dark .scaa-bajo {
|
|
background-color: color-mix(in srgb, #6b7280 30%, transparent);
|
|
}
|
|
|
|
.dark .chip {
|
|
background-color: color-mix(in srgb, var(--cata-primary) 15%, transparent);
|
|
}
|
|
|
|
.dark .chip-warning {
|
|
background-color: color-mix(in srgb, #f59e0b 20%, transparent);
|
|
}
|
|
|
|
.dark .chip-error {
|
|
background-color: color-mix(in srgb, #ef4444 20%, transparent);
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 640px) {
|
|
.muestra-numero {
|
|
font-size: 0.8125rem;
|
|
}
|
|
|
|
.muestra-nombre {
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.puntajes-container {
|
|
gap: 0.125rem;
|
|
}
|
|
|
|
.puntaje-badge {
|
|
font-size: 0.5625rem;
|
|
min-width: 1.5rem;
|
|
gap: 0.125rem;
|
|
padding: 0.125rem 0.25rem;
|
|
}
|
|
|
|
.puntaje-label {
|
|
font-size: 0.5rem;
|
|
}
|
|
|
|
.chips-container {
|
|
font-size: 0.5625rem;
|
|
}
|
|
|
|
.chip {
|
|
padding: 0.125rem 0.3rem;
|
|
gap: 0.125rem;
|
|
}
|
|
}
|
|
</style>
|