Fix: Restaurar componentes completos de Lotes y Operaciones
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m5s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m5s
- Restaurar LotesTable completo con onMounted y watch - Habilitar carga automática de datos - Base de datos recreada con credenciales correctas - Conexión PostgreSQL funcionando correctamente
This commit is contained in:
@@ -1,16 +1,169 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<h2 class="text-2xl font-bold">TEST: Componente LotesTable Simplificado</h2>
|
<div class="flex justify-between items-center">
|
||||||
<p>Si ves este mensaje, el componente se renderizó correctamente.</p>
|
<div>
|
||||||
<p>Contador: {{ contador }}</p>
|
<h2 class="text-2xl font-bold">Lotes</h2>
|
||||||
<UButton @click="contador++">Incrementar</UButton>
|
<p class="text-gray-500">Gestión de lotes de café</p>
|
||||||
|
</div>
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-plus"
|
||||||
|
label="Nuevo Lote"
|
||||||
|
@click="$emit('create')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<USelect
|
||||||
|
v-model="filtroTipo"
|
||||||
|
:options="[{ value: '', label: 'Todos los tipos' }, ...TIPOS_LOTE]"
|
||||||
|
placeholder="Filtrar por tipo"
|
||||||
|
class="w-64"
|
||||||
|
/>
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-arrow-path"
|
||||||
|
label="Refrescar"
|
||||||
|
variant="outline"
|
||||||
|
@click="loadLotes"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UCard>
|
||||||
|
<UTable
|
||||||
|
v-model="selected"
|
||||||
|
:rows="lotes"
|
||||||
|
:columns="columns"
|
||||||
|
:loading="loading"
|
||||||
|
:empty-state="{
|
||||||
|
icon: 'i-heroicons-inbox',
|
||||||
|
label: 'No hay lotes registrados'
|
||||||
|
}"
|
||||||
|
@select="handleSelect"
|
||||||
|
>
|
||||||
|
<template #codigo-data="{ row }">
|
||||||
|
<span class="font-mono font-semibold">{{ row.codigo || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #tipo-data="{ row }">
|
||||||
|
<UBadge :color="getTipoColor(row.tipo)" variant="subtle">
|
||||||
|
{{ getTipoLabel(row.tipo) }}
|
||||||
|
</UBadge>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cantidad_kg-data="{ row }">
|
||||||
|
<span v-if="row.cantidad_kg" class="font-medium">
|
||||||
|
{{ row.cantidad_kg.toLocaleString('es-AR') }} kg
|
||||||
|
</span>
|
||||||
|
<span v-else class="text-gray-400">-</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #fecha_creado-data="{ row }">
|
||||||
|
{{ formatDate(row.fecha_creado) }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #actions-data="{ row }">
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-eye"
|
||||||
|
size="xs"
|
||||||
|
variant="ghost"
|
||||||
|
@click="$emit('view', row)"
|
||||||
|
/>
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-pencil"
|
||||||
|
size="xs"
|
||||||
|
variant="ghost"
|
||||||
|
@click="$emit('edit', row)"
|
||||||
|
/>
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-chart-bar"
|
||||||
|
size="xs"
|
||||||
|
variant="ghost"
|
||||||
|
color="green"
|
||||||
|
@click="$emit('trazabilidad', row)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</UCard>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
console.log('🟢 LotesTable SIMPLE: Script ejecutado')
|
import type { Lote } from '~/composables/useLotes'
|
||||||
|
|
||||||
const contador = ref(0)
|
const emit = defineEmits<{
|
||||||
|
create: []
|
||||||
|
view: [lote: Lote]
|
||||||
|
edit: [lote: Lote]
|
||||||
|
trazabilidad: [lote: Lote]
|
||||||
|
}>()
|
||||||
|
|
||||||
console.log('🟢 LotesTable SIMPLE: Setup completado')
|
const { fetchLotes, TIPOS_LOTE } = useLotes()
|
||||||
|
|
||||||
|
const lotes = ref<Lote[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const selected = ref<Lote[]>([])
|
||||||
|
const filtroTipo = ref('')
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ key: 'codigo', label: 'Código' },
|
||||||
|
{ key: 'tipo', label: 'Tipo' },
|
||||||
|
{ key: 'cantidad_kg', label: 'Cantidad' },
|
||||||
|
{ key: 'fecha_creado', label: 'Fecha Creación' },
|
||||||
|
{ key: 'actions', label: 'Acciones' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const loadLotes = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
lotes.value = await fetchLotes({
|
||||||
|
tipo: filtroTipo.value || undefined,
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelect = (rows: Lote[]) => {
|
||||||
|
selected.value = rows
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTipoLabel = (tipo: string) => {
|
||||||
|
const found = TIPOS_LOTE.find((t) => t.value === tipo)
|
||||||
|
return found?.label || tipo
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTipoColor = (tipo: string): string => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
uva: 'purple',
|
||||||
|
despulpado_primera: 'green',
|
||||||
|
despulpado_segunda: 'yellow',
|
||||||
|
despulpado_rechazos: 'red',
|
||||||
|
oreado: 'orange',
|
||||||
|
presecado: 'amber',
|
||||||
|
reposo: 'blue',
|
||||||
|
secado: 'emerald',
|
||||||
|
}
|
||||||
|
return colorMap[tipo] || 'gray'
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDate = (dateString: string) => {
|
||||||
|
return new Date(dateString).toLocaleDateString('es-AR', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cargar lotes al montar
|
||||||
|
onMounted(() => {
|
||||||
|
loadLotes()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Recargar cuando cambia el filtro
|
||||||
|
watch(filtroTipo, () => {
|
||||||
|
loadLotes()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user