Fix: Corregir bug visual de accordions en sesión de catación
Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 16s
Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 16s
- Crear componente CataResumenMuestra para mostrar resumen de cada muestra en el header del accordion - Crear componente CataFormularioMuestra para mostrar formulario de edición de intensidades por tab - Corregir uso de slots en UAccordion para mostrar correctamente el contenido - Usar slot #default para customizar el header con CataResumenMuestra - Usar slots personalizados por muestra para el body con CataFormularioMuestra - Agregar estilos mejorados para los items del accordion
This commit is contained in:
447
nuxt4/app/components/CataFormularioMuestra.vue
Normal file
447
nuxt4/app/components/CataFormularioMuestra.vue
Normal file
@@ -0,0 +1,447 @@
|
||||
<template>
|
||||
<div class="formulario-muestra cata-text p-4">
|
||||
<!-- Tab: Fragancia/Aroma -->
|
||||
<div v-if="tabActiva === 'fragancia-aroma'" class="tab-content">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- Fragancia -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Fragancia</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="fraganciaDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarFragancia"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="fraganciaAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarFragancia"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Aroma -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Aroma</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="aromaDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarAroma"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="aromaAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarAroma"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notas de Fragancia/Aroma -->
|
||||
<div class="mt-6">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Notas de Fragancia/Aroma</label>
|
||||
<div class="text-xs opacity-60 mb-2">Puedes escribir tus notas libremente</div>
|
||||
<textarea
|
||||
v-model="notasFraganciaAroma"
|
||||
rows="3"
|
||||
class="cata-input w-full"
|
||||
placeholder="Describe las notas de fragancia y aroma..."
|
||||
@blur="actualizarNotasFragancia"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: Sabor -->
|
||||
<div v-else-if="tabActiva === 'sabor'" class="tab-content">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- Sabor -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Sabor</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="saborDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarSabor"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="saborAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarSabor"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sabor Residual -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Sabor Residual</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="saborResidualDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarSaborResidual"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="saborResidualAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarSaborResidual"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Acidez -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Acidez</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="acidezDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarAcidez"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="acidezAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarAcidez"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dulzor -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Dulzor</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="dulzorDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarDulzor"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="dulzorAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarDulzor"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notas de Sabor -->
|
||||
<div class="mt-6">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Notas de Sabor</label>
|
||||
<div class="text-xs opacity-60 mb-2">Puedes escribir tus notas libremente</div>
|
||||
<textarea
|
||||
v-model="notasSabor"
|
||||
rows="3"
|
||||
class="cata-input w-full"
|
||||
placeholder="Describe las notas de sabor..."
|
||||
@blur="actualizarNotasSabor"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: Impresión Global -->
|
||||
<div v-else-if="tabActiva === 'impresion-global'" class="tab-content">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- Sensación en Boca -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Sensación en Boca</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="sensacionBocaDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarSensacionBoca"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="sensacionBocaAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarSensacionBoca"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Impresión Global -->
|
||||
<div class="campo-grupo">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Impresión Global</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Descriptiva (1-10)</label>
|
||||
<input
|
||||
v-model.number="impresionGlobalDescriptiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-10"
|
||||
@change="actualizarImpresionGlobal"
|
||||
>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<label class="text-xs opacity-75 mb-1 block">Afectiva (1-15)</label>
|
||||
<input
|
||||
v-model.number="impresionGlobalAfectiva"
|
||||
type="number"
|
||||
min="1"
|
||||
max="15"
|
||||
class="cata-input w-full"
|
||||
placeholder="1-15"
|
||||
@change="actualizarImpresionGlobal"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notas Adicionales -->
|
||||
<div class="mt-6">
|
||||
<label class="text-sm font-semibold mb-3 block cata-text">Notas Adicionales</label>
|
||||
<div class="text-xs opacity-60 mb-2">Observaciones generales sobre la muestra</div>
|
||||
<textarea
|
||||
v-model="otrasNotas"
|
||||
rows="4"
|
||||
class="cata-input w-full"
|
||||
placeholder="Escribe tus observaciones generales..."
|
||||
@blur="actualizarOtrasNotas"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Muestra } from '~/types/catacion'
|
||||
import type { TabCatacion } from '~/composables/useCatacion'
|
||||
|
||||
const props = defineProps<{
|
||||
muestra: Muestra
|
||||
tabActiva: TabCatacion
|
||||
}>()
|
||||
|
||||
const { actualizarIntensidad, actualizarFraganciaAroma, actualizarSabor, actualizarOtrasNotas: actualizarOtrasNotasComposable } = useCatacion()
|
||||
|
||||
// Valores reactivos para Fragancia
|
||||
const fraganciaDescriptiva = ref(props.muestra.intensidades.fragancia.descriptiva)
|
||||
const fraganciaAfectiva = ref(props.muestra.intensidades.fragancia.afectiva)
|
||||
const aromaDescriptiva = ref(props.muestra.intensidades.aroma.descriptiva)
|
||||
const aromaAfectiva = ref(props.muestra.intensidades.aroma.afectiva)
|
||||
|
||||
// Valores reactivos para Sabor
|
||||
const saborDescriptiva = ref(props.muestra.intensidades.sabor.descriptiva)
|
||||
const saborAfectiva = ref(props.muestra.intensidades.sabor.afectiva)
|
||||
const saborResidualDescriptiva = ref(props.muestra.intensidades.saborResidual.descriptiva)
|
||||
const saborResidualAfectiva = ref(props.muestra.intensidades.saborResidual.afectiva)
|
||||
const acidezDescriptiva = ref(props.muestra.intensidades.acidez.descriptiva)
|
||||
const acidezAfectiva = ref(props.muestra.intensidades.acidez.afectiva)
|
||||
const dulzorDescriptiva = ref(props.muestra.intensidades.dulzor.descriptiva)
|
||||
const dulzorAfectiva = ref(props.muestra.intensidades.dulzor.afectiva)
|
||||
|
||||
// Valores reactivos para Impresión Global
|
||||
const sensacionBocaDescriptiva = ref(props.muestra.intensidades.sensacionBoca.descriptiva)
|
||||
const sensacionBocaAfectiva = ref(props.muestra.intensidades.sensacionBoca.afectiva)
|
||||
const impresionGlobalDescriptiva = ref(props.muestra.intensidades.impresionGlobal.descriptiva)
|
||||
const impresionGlobalAfectiva = ref(props.muestra.intensidades.impresionGlobal.afectiva)
|
||||
|
||||
// Notas de texto
|
||||
const notasFraganciaAroma = ref(props.muestra.fraganciaAromaNotas.notaEspecifica || '')
|
||||
const notasSabor = ref(props.muestra.saborNotas.notaEspecifica || '')
|
||||
const otrasNotas = ref(props.muestra.otrasNotas)
|
||||
|
||||
// Actualizar cuando cambie la prop
|
||||
watch(() => props.muestra, (nuevaMuestra) => {
|
||||
fraganciaDescriptiva.value = nuevaMuestra.intensidades.fragancia.descriptiva
|
||||
fraganciaAfectiva.value = nuevaMuestra.intensidades.fragancia.afectiva
|
||||
aromaDescriptiva.value = nuevaMuestra.intensidades.aroma.descriptiva
|
||||
aromaAfectiva.value = nuevaMuestra.intensidades.aroma.afectiva
|
||||
|
||||
saborDescriptiva.value = nuevaMuestra.intensidades.sabor.descriptiva
|
||||
saborAfectiva.value = nuevaMuestra.intensidades.sabor.afectiva
|
||||
saborResidualDescriptiva.value = nuevaMuestra.intensidades.saborResidual.descriptiva
|
||||
saborResidualAfectiva.value = nuevaMuestra.intensidades.saborResidual.afectiva
|
||||
acidezDescriptiva.value = nuevaMuestra.intensidades.acidez.descriptiva
|
||||
acidezAfectiva.value = nuevaMuestra.intensidades.acidez.afectiva
|
||||
dulzorDescriptiva.value = nuevaMuestra.intensidades.dulzor.descriptiva
|
||||
dulzorAfectiva.value = nuevaMuestra.intensidades.dulzor.afectiva
|
||||
|
||||
sensacionBocaDescriptiva.value = nuevaMuestra.intensidades.sensacionBoca.descriptiva
|
||||
sensacionBocaAfectiva.value = nuevaMuestra.intensidades.sensacionBoca.afectiva
|
||||
impresionGlobalDescriptiva.value = nuevaMuestra.intensidades.impresionGlobal.descriptiva
|
||||
impresionGlobalAfectiva.value = nuevaMuestra.intensidades.impresionGlobal.afectiva
|
||||
|
||||
notasFraganciaAroma.value = nuevaMuestra.fraganciaAromaNotas.notaEspecifica || ''
|
||||
notasSabor.value = nuevaMuestra.saborNotas.notaEspecifica || ''
|
||||
otrasNotas.value = nuevaMuestra.otrasNotas
|
||||
}, { deep: true })
|
||||
|
||||
// Métodos de actualización
|
||||
const actualizarFragancia = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'fragancia', 'descriptiva', fraganciaDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'fragancia', 'afectiva', fraganciaAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarAroma = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'aroma', 'descriptiva', aromaDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'aroma', 'afectiva', aromaAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarSabor = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'sabor', 'descriptiva', saborDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'sabor', 'afectiva', saborAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarSaborResidual = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'saborResidual', 'descriptiva', saborResidualDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'saborResidual', 'afectiva', saborResidualAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarAcidez = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'acidez', 'descriptiva', acidezDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'acidez', 'afectiva', acidezAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarDulzor = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'dulzor', 'descriptiva', dulzorDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'dulzor', 'afectiva', dulzorAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarSensacionBoca = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'sensacionBoca', 'descriptiva', sensacionBocaDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'sensacionBoca', 'afectiva', sensacionBocaAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarImpresionGlobal = async () => {
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'impresionGlobal', 'descriptiva', impresionGlobalDescriptiva.value)
|
||||
await actualizarIntensidad(props.muestra.muestraId, 'impresionGlobal', 'afectiva', impresionGlobalAfectiva.value)
|
||||
}
|
||||
|
||||
const actualizarNotasFragancia = async () => {
|
||||
await actualizarFraganciaAroma(props.muestra.muestraId, null, null, notasFraganciaAroma.value)
|
||||
}
|
||||
|
||||
const actualizarNotasSabor = async () => {
|
||||
await actualizarSabor(props.muestra.muestraId, null, null, notasSabor.value)
|
||||
}
|
||||
|
||||
const actualizarOtrasNotas = async () => {
|
||||
await actualizarOtrasNotasComposable(props.muestra.muestraId, otrasNotas.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.campo-grupo {
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid color-mix(in srgb, var(--cata-primary) 20%, transparent);
|
||||
background: color-mix(in srgb, var(--cata-primary) 5%, transparent);
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
animation: fadeIn 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
132
nuxt4/app/components/CataResumenMuestra.vue
Normal file
132
nuxt4/app/components/CataResumenMuestra.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<div class="resumen-muestra flex items-center justify-between gap-4 w-full">
|
||||
<!-- Información básica -->
|
||||
<div class="flex items-center gap-3 flex-1 min-w-0">
|
||||
<div class="muestra-numero cata-text font-bold text-lg">
|
||||
#{{ muestra.muestraId }}
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="muestra-nombre cata-text font-semibold truncate">
|
||||
{{ muestra.nombre }}
|
||||
</div>
|
||||
<div class="muestra-stats text-xs cata-text opacity-60 flex items-center gap-2">
|
||||
<span>Puntaje {{ muestra.puntajeFinal }}</span>
|
||||
<span class="opacity-40">•</span>
|
||||
<span>{{ porcentajeCompletitud }}% completado</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Indicadores de completitud -->
|
||||
<div class="muestra-indicadores flex items-center gap-2 text-xs">
|
||||
<!-- Fragancia/Aroma -->
|
||||
<div
|
||||
:class="[
|
||||
'indicador-badge px-2 py-1 rounded',
|
||||
tieneFraganciaAroma ? 'bg-success/20 text-success' : 'bg-muted/20 text-muted',
|
||||
]"
|
||||
title="Fragancia/Aroma"
|
||||
>
|
||||
<span class="hidden sm:inline">F:</span>
|
||||
{{ intensidadesFormatted.fragancia }}/{{ intensidadesFormatted.aroma }}
|
||||
</div>
|
||||
|
||||
<!-- Sabor -->
|
||||
<div
|
||||
:class="[
|
||||
'indicador-badge px-2 py-1 rounded',
|
||||
tieneSabor ? 'bg-success/20 text-success' : 'bg-muted/20 text-muted',
|
||||
]"
|
||||
title="Sabor"
|
||||
>
|
||||
<span class="hidden sm:inline">S:</span>
|
||||
{{ intensidadesFormatted.sabor }}/{{ intensidadesFormatted.saborResidual }}
|
||||
</div>
|
||||
|
||||
<!-- Acidez -->
|
||||
<div
|
||||
:class="[
|
||||
'indicador-badge px-2 py-1 rounded',
|
||||
tieneAcidez ? 'bg-success/20 text-success' : 'bg-muted/20 text-muted',
|
||||
]"
|
||||
title="Acidez"
|
||||
>
|
||||
<span class="hidden sm:inline">Ac:</span>
|
||||
{{ intensidadesFormatted.acidez }}/{{ intensidadesFormatted.dulzor }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Barra de progreso -->
|
||||
<div class="progreso-container hidden md:block w-24">
|
||||
<div class="progreso-bg h-2 rounded-full bg-muted/20 overflow-hidden">
|
||||
<div
|
||||
class="progreso-fill h-full bg-primary transition-all"
|
||||
:style="{ width: `${porcentajeCompletitud}%` }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Muestra } from '~/types/catacion'
|
||||
|
||||
const props = defineProps<{
|
||||
muestra: Muestra
|
||||
porcentajeCompletitud: number
|
||||
}>()
|
||||
|
||||
// Formatear intensidades para mostrar
|
||||
const intensidadesFormatted = computed(() => ({
|
||||
fragancia: props.muestra.intensidades.fragancia.afectiva ?? '-',
|
||||
aroma: props.muestra.intensidades.aroma.afectiva ?? '-',
|
||||
sabor: props.muestra.intensidades.sabor.afectiva ?? '-',
|
||||
saborResidual: props.muestra.intensidades.saborResidual.afectiva ?? '-',
|
||||
acidez: props.muestra.intensidades.acidez.afectiva ?? '-',
|
||||
dulzor: props.muestra.intensidades.dulzor.afectiva ?? '-',
|
||||
}))
|
||||
|
||||
// Verificar si las secciones están completas
|
||||
const tieneFraganciaAroma = computed(() =>
|
||||
props.muestra.intensidades.fragancia.afectiva !== null &&
|
||||
props.muestra.intensidades.aroma.afectiva !== null
|
||||
)
|
||||
|
||||
const tieneSabor = computed(() =>
|
||||
props.muestra.intensidades.sabor.afectiva !== null &&
|
||||
props.muestra.intensidades.saborResidual.afectiva !== null
|
||||
)
|
||||
|
||||
const tieneAcidez = computed(() =>
|
||||
props.muestra.intensidades.acidez.afectiva !== null &&
|
||||
props.muestra.intensidades.dulzor.afectiva !== null
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.resumen-muestra {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.muestra-numero {
|
||||
font-size: 1.25rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.indicador-badge {
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.muestra-indicadores {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.indicador-badge {
|
||||
font-size: 0.625rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user