Files
cataRio/nuxt4/app/components/cata/ResumenMuestra.vue
josedario87 3eb9e987c7
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m6s
Feat: Filtrar chips de ResumenMuestra según tab activa
- 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
2025-10-18 16:06:35 -06:00

327 lines
11 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="resumen-muestra w-full">
<!-- Primera línea: Número, nombre y puntaje -->
<div class="flex items-center gap-1.5 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>
<!-- Puntaje final -->
<div class="puntaje-final flex-shrink-0 px-1.5 py-0.5 rounded" :class="puntajeClass">
<span class="font-bold">{{ muestra.puntajeFinal }}</span>
</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.length > 0" class="chip">
<span class="chip-label">Sen:</span>
<span class="chip-value">{{ muestra.sensacionEnBoca.join(', ') }}</span>
</div>
</template>
<!-- Chips Intensidades (Descriptiva/Afectiva) -->
<template v-if="mostrarChipsIntensidades">
<div v-if="muestra.intensidades.fragancia.afectiva !== null || muestra.intensidades.fragancia.descriptiva !== null" class="chip">
<span class="chip-label">Fra:</span>
<span v-if="muestra.intensidades.fragancia.afectiva !== null" class="chip-value">{{ muestra.intensidades.fragancia.afectiva }}</span>
<span v-if="muestra.intensidades.fragancia.descriptiva !== null" class="chip-value">{{ muestra.intensidades.fragancia.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.aroma.afectiva !== null || muestra.intensidades.aroma.descriptiva !== null" class="chip">
<span class="chip-label">Aro:</span>
<span v-if="muestra.intensidades.aroma.afectiva !== null" class="chip-value">{{ muestra.intensidades.aroma.afectiva }}</span>
<span v-if="muestra.intensidades.aroma.descriptiva !== null" class="chip-value">{{ muestra.intensidades.aroma.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.sabor.afectiva !== null || muestra.intensidades.sabor.descriptiva !== null" class="chip">
<span class="chip-label">Sb:</span>
<span v-if="muestra.intensidades.sabor.afectiva !== null" class="chip-value">{{ muestra.intensidades.sabor.afectiva }}</span>
<span v-if="muestra.intensidades.sabor.descriptiva !== null" class="chip-value">{{ muestra.intensidades.sabor.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.saborResidual.afectiva !== null || muestra.intensidades.saborResidual.descriptiva !== null" class="chip">
<span class="chip-label">S.R:</span>
<span v-if="muestra.intensidades.saborResidual.afectiva !== null" class="chip-value">{{ muestra.intensidades.saborResidual.afectiva }}</span>
<span v-if="muestra.intensidades.saborResidual.descriptiva !== null" class="chip-value">{{ muestra.intensidades.saborResidual.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.acidez.afectiva !== null || muestra.intensidades.acidez.descriptiva !== null" class="chip">
<span class="chip-label">Aci:</span>
<span v-if="muestra.intensidades.acidez.afectiva !== null" class="chip-value">{{ muestra.intensidades.acidez.afectiva }}</span>
<span v-if="muestra.intensidades.acidez.descriptiva !== null" class="chip-value">{{ muestra.intensidades.acidez.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.dulzor.afectiva !== null || muestra.intensidades.dulzor.descriptiva !== null" class="chip">
<span class="chip-label">Dul:</span>
<span v-if="muestra.intensidades.dulzor.afectiva !== null" class="chip-value">{{ muestra.intensidades.dulzor.afectiva }}</span>
<span v-if="muestra.intensidades.dulzor.descriptiva !== null" class="chip-value">{{ muestra.intensidades.dulzor.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.sensacionBoca.afectiva !== null || muestra.intensidades.sensacionBoca.descriptiva !== null" class="chip">
<span class="chip-label">Sn:</span>
<span v-if="muestra.intensidades.sensacionBoca.afectiva !== null" class="chip-value">{{ muestra.intensidades.sensacionBoca.afectiva }}</span>
<span v-if="muestra.intensidades.sensacionBoca.descriptiva !== null" class="chip-value">{{ muestra.intensidades.sensacionBoca.descriptiva }}📊</span>
</div>
<div v-if="muestra.intensidades.impresionGlobal.afectiva !== null || muestra.intensidades.impresionGlobal.descriptiva !== null" class="chip">
<span class="chip-label">Imp:</span>
<span v-if="muestra.intensidades.impresionGlobal.afectiva !== null" class="chip-value">{{ muestra.intensidades.impresionGlobal.afectiva }}</span>
<span v-if="muestra.intensidades.impresionGlobal.descriptiva !== null" class="chip-value">{{ muestra.intensidades.impresionGlobal.descriptiva }}📊</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'
interface ResumenMuestraProps {
/** Muestra a mostrar */
muestra: Muestra
/** Tab activa para filtrar chips */
tabActiva?: TabCatacion
}
const props = withDefaults(defineProps<ResumenMuestraProps>(), {
tabActiva: 'impresion-global',
})
// 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 puntaje final basado en el valor
const puntajeClass = computed(() => {
const puntaje = props.muestra.puntajeFinal
if (puntaje >= 90) return 'puntaje-excelente'
if (puntaje >= 85) return 'puntaje-muy-bueno'
if (puntaje >= 80) return 'puntaje-bueno'
if (puntaje >= 70) return 'puntaje-regular'
return 'puntaje-bajo'
})
// 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;
}
/* Puntaje final */
.puntaje-final {
border: 1px solid;
min-width: 2rem;
text-align: center;
font-size: 0.6875rem;
}
.puntaje-excelente {
background-color: color-mix(in srgb, #10b981 20%, transparent);
border-color: #10b981;
color: #10b981;
}
.puntaje-muy-bueno {
background-color: color-mix(in srgb, #3b82f6 20%, transparent);
border-color: #3b82f6;
color: #3b82f6;
}
.puntaje-bueno {
background-color: color-mix(in srgb, #f59e0b 20%, transparent);
border-color: #f59e0b;
color: #f59e0b;
}
.puntaje-regular {
background-color: color-mix(in srgb, #ef4444 20%, transparent);
border-color: #ef4444;
color: #ef4444;
}
.puntaje-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-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-excelente {
background-color: color-mix(in srgb, #10b981 30%, transparent);
}
.dark .puntaje-muy-bueno {
background-color: color-mix(in srgb, #3b82f6 30%, transparent);
}
.dark .puntaje-bueno {
background-color: color-mix(in srgb, #f59e0b 30%, transparent);
}
.dark .puntaje-regular {
background-color: color-mix(in srgb, #ef4444 30%, transparent);
}
.dark .puntaje-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;
}
.puntaje-final {
font-size: 0.625rem;
min-width: 1.75rem;
}
.chips-container {
font-size: 0.5625rem;
}
.chip {
padding: 0.125rem 0.3rem;
gap: 0.125rem;
}
}
</style>