221 lines
8.5 KiB
Vue
221 lines
8.5 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted, computed } from 'vue';
|
|
import { useRouter, useRoute } from 'vue-router';
|
|
import { useToast } from 'primevue/usetoast';
|
|
import Toast from 'primevue/toast';
|
|
import { useWarehouseStore } from '../../../stores/warehouseStore';
|
|
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
const toast = useToast();
|
|
const warehouseStore = useWarehouseStore();
|
|
|
|
const searchQuery = ref('');
|
|
const selectedStatus = ref('all');
|
|
const selectedLocation = ref('all');
|
|
|
|
// Usar el estado del store
|
|
const warehouses = computed(() => warehouseStore.warehouses);
|
|
const loading = computed(() => warehouseStore.loading);
|
|
|
|
const statusOptions = [
|
|
{ label: 'All', value: 'all' },
|
|
{ label: 'Active', value: 'active' },
|
|
{ label: 'Full', value: 'full' },
|
|
{ label: 'Inactive', value: 'inactive' },
|
|
{ label: 'Needs Attention', value: 'needs_attention' },
|
|
];
|
|
|
|
const locationOptions = [
|
|
{ label: 'All', value: 'all' },
|
|
{ label: 'Springfield, IL', value: 'springfield' },
|
|
{ label: 'Riverside, CA', value: 'riverside' },
|
|
{ label: 'Atlanta, GA', value: 'atlanta' },
|
|
{ label: 'Columbus, OH', value: 'columbus' },
|
|
{ label: 'Seattle, WA', value: 'seattle' },
|
|
];
|
|
|
|
const getStatusConfig = (isActive: boolean) => {
|
|
return isActive
|
|
? { label: 'Activo', severity: 'success' }
|
|
: { label: 'Inactivo', severity: 'secondary' };
|
|
};
|
|
|
|
const clearFilters = () => {
|
|
searchQuery.value = '';
|
|
selectedStatus.value = 'all';
|
|
selectedLocation.value = 'all';
|
|
};
|
|
|
|
const createWarehouse = () => {
|
|
router.push({ name: 'WarehouseCreate' });
|
|
};
|
|
|
|
const viewWarehouseDetails = (warehouse: any) => {
|
|
router.push({
|
|
name: 'WarehouseDetails',
|
|
params: { id: warehouse.id }
|
|
});
|
|
};
|
|
|
|
onMounted(async () => {
|
|
// Reload warehouses to show new data
|
|
await warehouseStore.refreshWarehouses();
|
|
|
|
// Check if we just created a warehouse
|
|
if (route.query.created === 'true') {
|
|
const warehouseName = route.query.name as string || 'el almacén';
|
|
toast.add({
|
|
severity: 'success',
|
|
summary: 'Almacén Creado',
|
|
detail: `El almacén "${warehouseName}" ha sido creado exitosamente.`,
|
|
life: 4000
|
|
});
|
|
|
|
// Clean up the query params
|
|
router.replace({ path: '/warehouse' });
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-6">
|
|
<!-- Toast Notifications -->
|
|
<Toast position="bottom-right" />
|
|
|
|
<!-- Header -->
|
|
<div class="flex flex-wrap justify-between gap-4 items-center">
|
|
<div class="flex min-w-72 flex-col gap-1">
|
|
<h1 class="text-surface-900 dark:text-white text-3xl md:text-4xl font-black leading-tight tracking-tight">
|
|
Almacenes
|
|
</h1>
|
|
<p class="text-surface-500 dark:text-surface-400 text-base font-normal leading-normal">
|
|
Administra, rastrea y organiza todos tus almacenes en un solo lugar.
|
|
</p>
|
|
</div>
|
|
<Button
|
|
label="Crear Nuevo Almacén "
|
|
icon="pi pi-plus"
|
|
@click="createWarehouse"
|
|
class="min-w-[200px]"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Table Card -->
|
|
<Card class="shadow-sm">
|
|
<template #content>
|
|
<!-- Search and Filters -->
|
|
<div class="flex flex-col md:flex-row justify-between gap-4 mb-4">
|
|
<div class="flex-1">
|
|
<IconField iconPosition="left">
|
|
<InputIcon class="pi pi-search" />
|
|
<InputText
|
|
v-model="searchQuery"
|
|
placeholder="Search by name or location..."
|
|
class="w-full"
|
|
/>
|
|
</IconField>
|
|
</div>
|
|
<div class="flex gap-2 flex-wrap">
|
|
<Dropdown
|
|
v-model="selectedStatus"
|
|
:options="statusOptions"
|
|
optionLabel="label"
|
|
optionValue="value"
|
|
placeholder="Status: All"
|
|
class="w-40"
|
|
/>
|
|
<Dropdown
|
|
v-model="selectedLocation"
|
|
:options="locationOptions"
|
|
optionLabel="label"
|
|
optionValue="value"
|
|
placeholder="Location: All"
|
|
class="w-40"
|
|
/>
|
|
<Button
|
|
label="Clear"
|
|
icon="pi pi-times"
|
|
outlined
|
|
@click="clearFilters"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table -->
|
|
<DataTable
|
|
:value="warehouses"
|
|
:loading="loading"
|
|
:paginator="true"
|
|
:rows="5"
|
|
:rowsPerPageOptions="[5, 10, 20]"
|
|
stripedRows
|
|
responsiveLayout="scroll"
|
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown CurrentPageReport"
|
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} results"
|
|
class="cursor-pointer"
|
|
@row-click="(event) => viewWarehouseDetails(event.data)"
|
|
>
|
|
<Column field="code" header="Código" sortable>
|
|
<template #body="slotProps">
|
|
<span class="font-mono text-surface-700 dark:text-surface-300">
|
|
{{ slotProps.data.code }}
|
|
</span>
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="name" header="Nombre" sortable>
|
|
<template #body="slotProps">
|
|
<div>
|
|
<span class="font-medium text-surface-900 dark:text-white block">
|
|
{{ slotProps.data.name }}
|
|
</span>
|
|
<span class="text-xs text-surface-500 dark:text-surface-400">
|
|
{{ slotProps.data.description }}
|
|
</span>
|
|
</div>
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="address" header="Ubicación" sortable>
|
|
<template #body="slotProps">
|
|
<span class="text-surface-500 dark:text-surface-400 text-sm">
|
|
{{ slotProps.data.address }}
|
|
</span>
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="is_active" header="Estado" sortable>
|
|
<template #body="slotProps">
|
|
<Tag
|
|
:value="getStatusConfig(slotProps.data.is_active).label"
|
|
:severity="getStatusConfig(slotProps.data.is_active).severity"
|
|
/>
|
|
</template>
|
|
</Column>
|
|
|
|
<Column header="Acciones" headerStyle="text-align: right" bodyStyle="text-align: right">
|
|
<template #body="slotProps">
|
|
<div class="flex gap-2 justify-end">
|
|
<Button
|
|
icon="pi pi-eye"
|
|
text
|
|
size="small"
|
|
@click="(event) => { event.stopPropagation(); viewWarehouseDetails(slotProps.data); }"
|
|
/>
|
|
<Button
|
|
icon="pi pi-ellipsis-v"
|
|
text
|
|
rounded
|
|
size="small"
|
|
@click="(event) => event.stopPropagation()"
|
|
/>
|
|
</div>
|
|
</template>
|
|
</Column>
|
|
</DataTable>
|
|
</template>
|
|
</Card>
|
|
</div>
|
|
</template>
|