Fix: Eliminar componentes duplicados que causaban conflicto en el build
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m4s

- Eliminar CataResumenMuestra.vue y CataFormularioMuestra.vue duplicados
- Usar componentes existentes en components/cata/ que ya se auto-registran como CataResumenMuestra y CataFormularioMuestra
- Resolver conflicto de nombres en Nuxt que impedía el build
This commit is contained in:
2025-10-18 02:12:22 -06:00
parent 5e697dbc89
commit 9cbc5f94c3
5 changed files with 121 additions and 591 deletions

View File

@@ -161,5 +161,48 @@ export default defineAppConfig({
root: 'bg-transparent border border-primary/50 dark:border-primary focus:ring-2 focus:ring-primary dark:font-mono', root: 'bg-transparent border border-primary/50 dark:border-primary focus:ring-2 focus:ring-primary dark:font-mono',
}, },
}, },
// Notifications (Toast): Estilo outline con los colores de la app
notification: {
slots: {
root: 'bg-transparent border-2 border-primary/50 dark:border-primary backdrop-blur-sm',
wrapper: 'w-full',
title: 'text-foreground font-semibold dark:font-mono dark:text-shadow',
description: 'text-foreground/80 dark:font-mono dark:font-light',
icon: 'shrink-0',
avatar: 'shrink-0',
actions: 'flex gap-1.5 shrink-0',
close: 'shrink-0',
progress: 'absolute inset-x-0 bottom-0 h-1 z-10',
},
variants: {
color: {
primary: {
root: 'dark:shadow-[0_0_12px_rgba(0,255,0,0.3)]',
progress: 'bg-primary',
},
success: {
root: 'border-green-500/50 dark:border-green-500 dark:shadow-[0_0_12px_rgba(0,255,0,0.3)]',
progress: 'bg-green-500',
},
error: {
root: 'border-red-500/50 dark:border-red-500 dark:shadow-[0_0_12px_rgba(255,0,0,0.3)]',
progress: 'bg-red-500',
},
warning: {
root: 'border-yellow-500/50 dark:border-yellow-500 dark:shadow-[0_0_12px_rgba(255,255,0,0.3)]',
progress: 'bg-yellow-500',
},
info: {
root: 'border-blue-500/50 dark:border-blue-500 dark:shadow-[0_0_12px_rgba(0,150,255,0.3)]',
progress: 'bg-blue-500',
},
neutral: {
root: 'dark:shadow-[0_0_12px_rgba(100,100,100,0.3)]',
progress: 'bg-gray-500',
},
},
},
},
}, },
}) })

View File

@@ -1,447 +0,0 @@
<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>

View File

@@ -1,132 +0,0 @@
<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>

View File

@@ -2,12 +2,16 @@
<div v-if="user" class="cata-user-info"> <div v-if="user" class="cata-user-info">
<div class="cata-outline-box rounded-lg p-4"> <div class="cata-outline-box rounded-lg p-4">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<!-- Avatar simple con inicial --> <!-- Avatar clickeable para verificar sesión -->
<div class="user-avatar cata-outline-box"> <button
class="user-avatar cata-outline-box cursor-pointer transition-all hover:scale-105 active:scale-95"
@click="handleCheckSession"
title="Verificar estado de sesión"
>
<span class="cata-text text-xl font-semibold"> <span class="cata-text text-xl font-semibold">
{{ userInitial }} {{ userInitial }}
</span> </span>
</div> </button>
<!-- Info del usuario --> <!-- Info del usuario -->
<div class="flex-1 min-w-0"> <div class="flex-1 min-w-0">
@@ -19,21 +23,46 @@
</p> </p>
</div> </div>
<!-- Botón de logout compacto --> <!-- Botones de acción -->
<button <div class="flex items-center gap-2">
class="cata-button p-2 flex-shrink-0" <!-- Botón de cambio de tema -->
@click="handleLogout" <button
title="Cerrar sesión" class="cata-button p-2 flex items-center justify-center flex-shrink-0"
> @click="toggleTheme"
<UIcon name="i-lucide-log-out" class="w-4 h-4" /> :title="isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'"
</button> >
<UIcon :name="isDark ? 'i-lucide-sun' : 'i-lucide-moon'" class="w-4 h-4" />
</button>
<!-- Botón de home -->
<button
class="cata-button p-2 flex items-center justify-center flex-shrink-0"
@click="goToHome"
title="Ir al inicio del ecosistema Nucleo"
>
<UIcon name="i-lucide-home" class="w-4 h-4" />
</button>
<!-- Botón de logout -->
<button
class="cata-button p-2 flex items-center justify-center flex-shrink-0"
@click="handleLogout"
title="Cerrar sesión"
>
<UIcon name="i-lucide-log-out" class="w-4 h-4" />
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const { user } = useAuthentik() const { user, checkSessionStatus } = useAuthentik()
const colorMode = useColorMode()
// Estado del tema
const isDark = computed(() => colorMode.value === 'dark')
// Obtener la inicial del usuario // Obtener la inicial del usuario
const userInitial = computed(() => { const userInitial = computed(() => {
@@ -42,6 +71,21 @@ const userInitial = computed(() => {
return name.charAt(0).toUpperCase() return name.charAt(0).toUpperCase()
}) })
// Cambiar tema
const toggleTheme = () => {
colorMode.preference = isDark.value ? 'light' : 'dark'
}
// Ir al home del ecosistema
const goToHome = () => {
window.open('https://inicio.nucleoriofrio.com', '_blank')
}
// Verificar estado de sesión
const handleCheckSession = async () => {
await checkSessionStatus()
}
// Manejar logout // Manejar logout
const handleLogout = () => { const handleLogout = () => {
// Redirigir al endpoint de logout de Authentik // Redirigir al endpoint de logout de Authentik
@@ -63,6 +107,7 @@ const handleLogout = () => {
justify-content: center; justify-content: center;
flex-shrink: 0; flex-shrink: 0;
background-color: color-mix(in srgb, var(--cata-primary) 5%, transparent); background-color: color-mix(in srgb, var(--cata-primary) 5%, transparent);
border: none;
} }
.dark .user-avatar { .dark .user-avatar {
@@ -70,6 +115,15 @@ const handleLogout = () => {
box-shadow: 0 0 8px color-mix(in srgb, var(--cata-primary) 20%, transparent); box-shadow: 0 0 8px color-mix(in srgb, var(--cata-primary) 20%, transparent);
} }
.user-avatar:hover {
background-color: color-mix(in srgb, var(--cata-primary) 10%, transparent);
}
.dark .user-avatar:hover {
background-color: color-mix(in srgb, var(--cata-primary) 15%, transparent);
box-shadow: 0 0 12px color-mix(in srgb, var(--cata-primary) 30%, transparent);
}
/* Responsive adjustments */ /* Responsive adjustments */
@media (max-width: 640px) { @media (max-width: 640px) {
.user-avatar { .user-avatar {

View File

@@ -0,0 +1,12 @@
<template>
<div />
</template>
<script setup lang="ts">
// Redirigir automáticamente al sistema de catación
definePageMeta({
middleware: () => {
return navigateTo('/cata', { replace: true })
}
})
</script>