Fix: múltiples correcciones de UI y funcionalidad
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m6s

Cambios realizados:

1. Favicon:
   - Actualizar configuración en app.vue para usar iconos PNG correctos
   - Agregar links con tamaños 32x32 y 16x16
   - Actualizar theme-color a #16a34a (verde del proyecto)

2. Modal de Crear Operación:
   - Reestructurar con slots #header y #body para scroll correcto
   - Extraer header del Form.vue y moverlo al modal
   - Eliminar UCard del componente Form.vue
   - Agregar max-h-[80vh] para limitar altura
   - Ahora muestra scrollbar vertical cuando el contenido excede el espacio

3. USelect de filtro de operaciones:
   - Corregir de :options a :items (API correcta de NuxtUI v4)
   - Agregar label-key y value-key
   - Agregar computed selectOptions (igual que en Lotes)
   - Cambiar filtroTipo de ref('') a ref<string | null>(null)
   - Ahora el filtro funciona correctamente

Archivos modificados:
- app/app.vue: Configuración favicon y modal operaciones
- app/components/operaciones/Form.vue: Eliminar UCard
- app/components/operaciones/Table.vue: Corregir USelect
This commit is contained in:
2025-11-22 03:29:27 -06:00
parent 19aa26a955
commit cb0261dad3
4 changed files with 32 additions and 21 deletions

View File

@@ -225,9 +225,25 @@
<!-- Modal: Crear Operación --> <!-- Modal: Crear Operación -->
<UModal <UModal
v-model:open="showCreateOperacionModal" v-model:open="showCreateOperacionModal"
:ui="{ content: 'w-[calc(100vw-2rem)] max-w-3xl rounded-lg shadow-lg ring ring-default' }" :ui="{ content: 'w-[calc(100vw-2rem)] max-w-3xl rounded-lg shadow-lg ring ring-default max-h-[80vh]' }"
> >
<template #content> <template #header>
<div class="flex items-center justify-between">
<div>
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">Flujo guiado</p>
<h3 class="text-xl font-semibold">Nueva Operación</h3>
<p class="text-sm text-gray-500 dark:text-gray-400">Define el tipo, selecciona inputs y crea los outputs.</p>
</div>
<UButton
icon="i-heroicons-x-mark"
variant="ghost"
size="sm"
@click="showCreateOperacionModal = false"
/>
</div>
</template>
<template #body>
<OperacionesForm <OperacionesForm
@cancel="showCreateOperacionModal = false" @cancel="showCreateOperacionModal = false"
@success="handleOperacionFormSuccess" @success="handleOperacionFormSuccess"
@@ -536,11 +552,12 @@ useHead({
title: 'Seguidor de Lotes - Trazabilidad de Café', title: 'Seguidor de Lotes - Trazabilidad de Café',
link: [ link: [
{ rel: 'manifest', href: '/manifest.webmanifest' }, { rel: 'manifest', href: '/manifest.webmanifest' },
{ rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' }, { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/icon-32x32.png' },
{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/icon-16x16.png' },
{ rel: 'apple-touch-icon', href: '/apple-touch-icon.png' } { rel: 'apple-touch-icon', href: '/apple-touch-icon.png' }
], ],
meta: [ meta: [
{ name: 'theme-color', content: '#00DC82' }, { name: 'theme-color', content: '#16a34a' },
{ name: 'mobile-web-app-capable', content: 'yes' }, { name: 'mobile-web-app-capable', content: 'yes' },
{ name: 'apple-mobile-web-app-capable', content: 'yes' }, { name: 'apple-mobile-web-app-capable', content: 'yes' },
{ name: 'apple-mobile-web-app-status-bar-style', content: 'default' } { name: 'apple-mobile-web-app-status-bar-style', content: 'default' }

View File

@@ -1,17 +1,5 @@
<template> <template>
<UCard class="bg-gradient-to-br from-white to-slate-50 dark:from-slate-900 dark:to-slate-950 shadow-lg"> <div class="space-y-6">
<template #header>
<div class="flex items-center justify-between">
<div>
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">Flujo guiado</p>
<h3 class="text-xl font-semibold">Nueva Operación</h3>
<p class="text-sm text-gray-500 dark:text-gray-400">Define el tipo, selecciona inputs y crea los outputs.</p>
</div>
<UBadge color="indigo" variant="subtle">3 pasos</UBadge>
</div>
</template>
<div class="space-y-6">
<!-- Paso 1: Tipo de Operación --> <!-- Paso 1: Tipo de Operación -->
<div v-if="step === 1" class="space-y-4"> <div v-if="step === 1" class="space-y-4">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
@@ -193,7 +181,6 @@
</div> </div>
</div> </div>
</div> </div>
</UCard>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@@ -15,8 +15,10 @@
<div class="flex gap-2"> <div class="flex gap-2">
<USelect <USelect
v-model="filtroTipo" v-model="filtroTipo"
:options="[{ value: '', label: 'Todos los tipos' }, ...TIPOS_OPERACION]" :items="selectOptions"
placeholder="Filtrar por tipo" label-key="label"
value-key="value"
searchable
class="w-64" class="w-64"
/> />
<UButton <UButton
@@ -94,9 +96,14 @@ console.log('🟡 OperacionesTable: useLotes() completado, TIPOS_OPERACION:', TI
const operaciones = ref<Operacion[]>([]) const operaciones = ref<Operacion[]>([])
const loading = ref(false) const loading = ref(false)
const filtroTipo = ref('') const filtroTipo = ref<string | null>(null)
const error = ref<string | null>(null) const error = ref<string | null>(null)
const selectOptions = computed(() => [
{ value: null, label: 'Todos los tipos' },
...TIPOS_OPERACION,
])
const columns: ColumnDef<Operacion>[] = [ const columns: ColumnDef<Operacion>[] = [
{ accessorKey: 'tipo', id: 'tipo', header: 'Tipo de Operación' }, { accessorKey: 'tipo', id: 'tipo', header: 'Tipo de Operación' },
{ accessorKey: 'fecha', id: 'fecha', header: 'Fecha' }, { accessorKey: 'fecha', id: 'fecha', header: 'Fecha' },

BIN
nuxt4/public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB