feature-comercial-module-ts #13

Merged
edgar.mendez merged 38 commits from feature-comercial-module-ts into develop 2026-03-04 15:07:09 +00:00
Showing only changes of commit c6eaa2ef75 - Show all commits

View File

@ -1,5 +1,314 @@
<script setup lang="ts">
import { ref } from 'vue';
import Card from 'primevue/card';
import InputText from 'primevue/inputtext';
import Button from 'primevue/button';
import DataTable from 'primevue/datatable';
import Column from 'primevue/column';
import Tag from 'primevue/tag';
import IconField from 'primevue/iconfield';
import InputIcon from 'primevue/inputicon';
import Dropdown from 'primevue/dropdown';
// Search and filters
const searchQuery = ref('');
const selectedStatus = ref('all');
const selectedType = ref('all');
const selectedLocation = ref('all');
// Filter options
const statusOptions = [
{ label: 'Todos', value: 'all' },
{ label: 'Activo', value: 'active' },
{ label: 'Inactivo', value: 'inactive' },
{ label: 'Archivado', value: 'archived' },
];
const typeOptions = [
{ label: 'Todos', value: 'all' },
{ label: 'Tienda', value: 'store' },
{ label: 'Kiosco', value: 'kiosk' },
{ label: 'Almacén', value: 'warehouse' },
];
const locationOptions = [
{ label: 'Todas', value: 'all' },
{ label: 'Centro', value: 'centro' },
{ label: 'Norte', value: 'norte' },
{ label: 'Sur', value: 'sur' },
];
// Sample data
const stores = ref([
{
id: 1,
name: 'Tienda Principal',
location: 'Av. Siempre Viva 742',
status: 'active',
terminals: 5,
lastActivity: 'Hoy, 10:45 AM'
},
{
id: 2,
name: 'Sucursal Centro',
location: 'Calle Falsa 123',
status: 'active',
terminals: 3,
lastActivity: 'Ayer, 08:15 PM'
},
{
id: 3,
name: 'Kiosco del Parque',
location: 'Parque Central, Stand 4',
status: 'inactive',
terminals: 1,
lastActivity: '25/08/2023'
},
{
id: 4,
name: 'Almacén Norte',
location: 'Blvd. Industrial 500',
status: 'active',
terminals: 8,
lastActivity: 'Hoy, 11:00 AM'
},
{
id: 5,
name: 'Pop-Up de Verano',
location: 'Playa Grande, Paseo Marítimo',
status: 'archived',
terminals: 2,
lastActivity: '15/07/2023'
}
]);
// Methods
const handleCreateStore = () => {
console.log('Create new store');
};
const handleEdit = (store: any) => {
console.log('Edit store:', store);
};
const handleView = (store: any) => {
console.log('View store:', store);
};
const handleToggleStatus = (store: any) => {
console.log('Toggle status:', store);
};
const clearFilters = () => {
searchQuery.value = '';
selectedStatus.value = 'all';
selectedType.value = 'all';
selectedLocation.value = 'all';
};
// Get status label
const getStatusLabel = (status: string) => {
const statusMap: Record<string, string> = {
active: 'Activo',
inactive: 'Inactivo',
archived: 'Archivado'
};
return statusMap[status] || status;
};
// Get status severity
const getStatusSeverity = (status: string) => {
const severityMap: Record<string, 'success' | 'warning' | 'secondary'> = {
active: 'success',
inactive: 'warning',
archived: 'secondary'
};
return severityMap[status] || 'secondary';
};
</script>
<template>
<p>
Stores Index Component
</p>
</template>
<div class="space-y-6">
<!-- 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">
Gestión de Puntos de Venta
</h1>
<p class="text-surface-500 dark:text-surface-400 text-base font-normal leading-normal">
Administra, rastrea y organiza todos tus puntos de venta en un solo lugar.
</p>
</div>
<Button
label="Crear Nuevo Punto de Venta"
icon="pi pi-plus"
@click="handleCreateStore"
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="Buscar por nombre o ID..."
class="w-full"
/>
</IconField>
</div>
<div class="flex gap-2 flex-wrap">
<Dropdown
v-model="selectedStatus"
:options="statusOptions"
optionLabel="label"
optionValue="value"
placeholder="Estado: Todos"
class="w-40"
/>
<Dropdown
v-model="selectedType"
:options="typeOptions"
optionLabel="label"
optionValue="value"
placeholder="Tipo: Todos"
class="w-40"
/>
<Dropdown
v-model="selectedLocation"
:options="locationOptions"
optionLabel="label"
optionValue="value"
placeholder="Ubicación: Todas"
class="w-40"
/>
<Button
label="Limpiar"
icon="pi pi-times"
outlined
@click="clearFilters"
/>
</div>
</div>
<!-- Table -->
<DataTable
:value="stores"
:paginator="true"
:rows="5"
:rowsPerPageOptions="[5, 10, 20, 50]"
stripedRows
responsiveLayout="scroll"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown CurrentPageReport"
currentPageReportTemplate="Mostrando {first} a {last} de {totalRecords} resultados"
>
<!-- Name Column -->
<Column field="name" header="Nombre del Punto de Venta" :sortable="true">
<template #body="{ data }">
<span class="font-medium text-surface-900 dark:text-white">
{{ data.name }}
</span>
</template>
</Column>
<!-- Location Column -->
<Column field="location" header="Ubicación" :sortable="true">
<template #body="{ data }">
<span class="text-surface-500 dark:text-surface-400 text-sm">
{{ data.location }}
</span>
</template>
</Column>
<!-- Status Column -->
<Column field="status" header="Estado" :sortable="true">
<template #body="{ data }">
<Tag
:value="getStatusLabel(data.status)"
:severity="getStatusSeverity(data.status)"
/>
</template>
</Column>
<!-- Terminals Column -->
<Column field="terminals" header="Terminales" :sortable="true">
<template #body="{ data }">
<span class="text-center block text-surface-500 dark:text-surface-400 text-sm">
{{ data.terminals }}
</span>
</template>
</Column>
<!-- Last Activity Column -->
<Column field="lastActivity" header="Última Actividad" :sortable="true">
<template #body="{ data }">
<span class="text-surface-500 dark:text-surface-400 text-sm">
{{ data.lastActivity }}
</span>
</template>
</Column>
<!-- Actions Column -->
<Column header="Acciones" headerStyle="text-align: right" bodyStyle="text-align: right">
<template #body="{ data }">
<div class="flex gap-2 justify-end">
<Button
icon="pi pi-pencil"
severity="secondary"
text
rounded
@click="handleEdit(data)"
v-tooltip.top="'Editar'"
/>
<Button
icon="pi pi-eye"
severity="secondary"
text
rounded
@click="handleView(data)"
v-tooltip.top="'Ver detalles'"
/>
<Button
v-if="data.status === 'active'"
icon="pi pi-power-off"
severity="danger"
text
rounded
@click="handleToggleStatus(data)"
v-tooltip.top="'Desactivar'"
/>
<Button
v-else-if="data.status === 'inactive'"
icon="pi pi-check"
severity="success"
text
rounded
@click="handleToggleStatus(data)"
v-tooltip.top="'Activar'"
/>
<Button
v-else
icon="pi pi-inbox"
severity="secondary"
text
rounded
@click="handleToggleStatus(data)"
v-tooltip.top="'Desarchivar'"
/>
</div>
</template>
</Column>
</DataTable>
</template>
</Card>
</div>
</template>
<style scoped>
/* Custom styles if needed */
</style>