From 83f0abff133f7007ce1ac9e0c423b40476843ca4 Mon Sep 17 00:00:00 2001 From: "edgar.mendez" Date: Sat, 4 Oct 2025 09:23:04 -0600 Subject: [PATCH] ADD: Administrador de productos(WIP) --- src/components/ui/Input.vue | 114 +++++++++++++ src/layouts/AdminLayout.vue | 5 + src/pages/Products/Index.vue | 229 ++++++++++++++++++++++++++ src/pages/Products/Module.js | 23 +++ src/pages/Products/a.jsx | 300 +++++++++++++++++++++++++++++++++++ src/router/Index.js | 34 ++++ 6 files changed, 705 insertions(+) create mode 100644 src/components/ui/Input.vue create mode 100644 src/pages/Products/Index.vue create mode 100644 src/pages/Products/Module.js create mode 100644 src/pages/Products/a.jsx diff --git a/src/components/ui/Input.vue b/src/components/ui/Input.vue new file mode 100644 index 0000000..1ca7f58 --- /dev/null +++ b/src/components/ui/Input.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/src/layouts/AdminLayout.vue b/src/layouts/AdminLayout.vue index 2733699..3956bd5 100644 --- a/src/layouts/AdminLayout.vue +++ b/src/layouts/AdminLayout.vue @@ -100,6 +100,11 @@ onMounted(() => { name="Clasificaciones Comerciales" to="admin.comercial-classifications.index" /> +
diff --git a/src/pages/Products/Index.vue b/src/pages/Products/Index.vue new file mode 100644 index 0000000..663d362 --- /dev/null +++ b/src/pages/Products/Index.vue @@ -0,0 +1,229 @@ + + + \ No newline at end of file diff --git a/src/pages/Products/Module.js b/src/pages/Products/Module.js new file mode 100644 index 0000000..943a378 --- /dev/null +++ b/src/pages/Products/Module.js @@ -0,0 +1,23 @@ +import { lang } from '@Lang/i18n'; +import { hasPermission } from '@Plugins/RolePermission.js'; + +// Ruta API +const apiTo = (name, params = {}) => route(`products.${name}`, params) + +// Ruta visual +const viewTo = ({ name = '', params = {}, query = {} }) => view({ + name: `admin.products.${name}`, params, query +}) + +// Obtener traducción del componente +const transl = (str) => lang(`admin.products.${str}`) + +// Control de permisos +const can = (permission) => hasPermission(`admin.products.${permission}`) + +export { + can, + viewTo, + apiTo, + transl +} \ No newline at end of file diff --git a/src/pages/Products/a.jsx b/src/pages/Products/a.jsx new file mode 100644 index 0000000..4bbb939 --- /dev/null +++ b/src/pages/Products/a.jsx @@ -0,0 +1,300 @@ +import { useState } from "react" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Badge } from "@/components/ui/badge" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table" +import { + Plus, + Search, + Filter, + Edit, + Trash2, + Package, + MoreHorizontal +} from "lucide-react" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" + +// Mock data +const products = [ + { + id: 1, + code: "PROD-001", + name: "Laptop Dell Inspiron 15", + description: "Laptop empresarial de alto rendimiento", + category: "Electrónicos > Computadoras", + brand: "Dell", + price: 15999.00, + stock: 45, + minStock: 10, + status: "active", + lastUpdated: "2024-01-15" + }, + { + id: 2, + code: "PROD-002", + name: "Mouse Inalámbrico Logitech", + description: "Mouse óptico inalámbrico con receptor USB", + category: "Electrónicos > Accesorios", + brand: "Logitech", + price: 599.00, + stock: 120, + minStock: 25, + status: "active", + lastUpdated: "2024-01-14" + }, + { + id: 3, + code: "PROD-003", + name: "Monitor LG 24 pulgadas", + description: "Monitor LED Full HD con conexión HDMI", + category: "Electrónicos > Monitores", + brand: "LG", + price: 3299.00, + stock: 8, + minStock: 15, + status: "low-stock", + lastUpdated: "2024-01-13" + }, + { + id: 4, + code: "PROD-004", + name: "Teclado Mecánico RGB", + description: "Teclado mecánico para gaming con iluminación RGB", + category: "Electrónicos > Accesorios", + brand: "Corsair", + price: 2199.00, + stock: 0, + minStock: 5, + status: "out-of-stock", + lastUpdated: "2024-01-12" + }, + { + id: 5, + code: "PROD-005", + name: "Webcam HD Logitech", + description: "Cámara web HD para videoconferencias", + category: "Electrónicos > Accesorios", + brand: "Logitech", + price: 899.00, + stock: 32, + minStock: 10, + status: "active", + lastUpdated: "2024-01-11" + } +] + +const getStatusBadge = (status: string, stock: number, minStock: number) => { + if (stock === 0) { + return Sin Stock + } + if (stock <= minStock) { + return Stock Bajo + } + return Activo +} + +export default function Products() { + const [searchTerm, setSearchTerm] = useState("") + const [filteredProducts, setFilteredProducts] = useState(products) + + const handleSearch = (term: string) => { + setSearchTerm(term) + const filtered = products.filter(product => + product.name.toLowerCase().includes(term.toLowerCase()) || + product.code.toLowerCase().includes(term.toLowerCase()) || + product.brand.toLowerCase().includes(term.toLowerCase()) + ) + setFilteredProducts(filtered) + } + + return ( +
+ {/* Header */} +
+
+

Productos

+

+ Gestión del catálogo de productos +

+
+ +
+ + {/* Stats Cards */} +
+ + +
+ +
+

{products.length}

+

Total Productos

+
+
+
+
+ + +
+
+ +
+
+

+ {products.filter(p => p.status === "active").length} +

+

Activos

+
+
+
+
+ + +
+
+ ! +
+
+

+ {products.filter(p => p.status === "low-stock").length} +

+

Stock Bajo

+
+
+
+
+ + +
+
+ × +
+
+

+ {products.filter(p => p.status === "out-of-stock").length} +

+

Sin Stock

+
+
+
+
+
+ + {/* Filters and Search */} + + + Catálogo de Productos + + +
+
+ + handleSearch(e.target.value)} + className="pl-10" + /> +
+ +
+ + {/* Products Table */} +
+ + + + Código + Producto + Categoría + Marca + Precio + Stock + Estado + + + + + {filteredProducts.map((product) => ( + + + {product.code} + + +
+

{product.name}

+

+ {product.description} +

+
+
+ + {product.category} + + {product.brand} + + ${product.price.toLocaleString('es-MX')} + + +
+

{product.stock}

+

+ Min: {product.minStock} +

+
+
+ + {getStatusBadge(product.status, product.stock, product.minStock)} + + + + + + + + + + Editar + + + + Ver Stock + + + + Eliminar + + + + +
+ ))} +
+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/router/Index.js b/src/router/Index.js index 5802ee6..cc5f7f2 100644 --- a/src/router/Index.js +++ b/src/router/Index.js @@ -528,6 +528,40 @@ const router = createRouter({ } ] }, + { + path: 'products', + name: 'admin.products', + meta: { + title: 'Productos', + icon: 'inventory', + }, + redirect: '/admin/products', + children: [ + { + path: '', + name: 'admin.products.index', + component: () => import('@Pages/Products/Index.vue'), + }, + /* { + path: 'create', + name: 'admin.products.create', + component: () => import('@Pages/Products/Create.vue'), + meta: { + title: 'Crear', + icon: 'add', + }, + }, + { + path: ':id/edit', + name: 'admin.products.edit', + component: () => import('@Pages/Products/Edit.vue'), + meta: { + title: 'Editar', + icon: 'edit', + }, + } */ + ] + }, { path: 'roles', name: 'admin.roles',