From e84a030aec93932b9a68657a4d79b37d8d18d59c Mon Sep 17 00:00:00 2001 From: Kevin_Ramirez Date: Fri, 2 Jan 2026 16:18:51 -0600 Subject: [PATCH] Se integro el modulo parcial de clases en mercancias --- frontend/messages/en.json | 5 + frontend/messages/es.json | 5 + .../components/dashboard/classes/columns.ts | 1 + .../classes/data-table-actions.svelte | 3 +- .../src/lib/components/sidebar/modules.ts | 16 + .../dashboard/goods/classes/+page.server.ts | 63 ++++ .../dashboard/goods/classes/+page.svelte | 239 +++++++++++++ .../goods/classes/edit/[[id]]/+page.svelte | 335 ++++++++++++++++++ .../routes/dashboard/goods/parts/+page.svelte | 1 + 9 files changed, 667 insertions(+), 1 deletion(-) create mode 100644 frontend/src/routes/dashboard/goods/classes/+page.server.ts create mode 100644 frontend/src/routes/dashboard/goods/classes/+page.svelte create mode 100644 frontend/src/routes/dashboard/goods/classes/edit/[[id]]/+page.svelte create mode 100644 frontend/src/routes/dashboard/goods/parts/+page.svelte diff --git a/frontend/messages/en.json b/frontend/messages/en.json index d4274cd5..541dac72 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -63,6 +63,11 @@ "back_flush": "Back Flush", "crossing_notice": "Crossing Notice" }, + "goods": { + "title": "Goods", + "classes": "Classes", + "parts": "Parts" + }, "pedimentos": { "title": "Pedimentos", "pedimento_management": "Pedimento Management", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 083691bc..9e2a85c5 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -63,6 +63,11 @@ "back_flush": "Back Flush", "crossing_notice": "Aviso de cruce" }, + "goods": { + "title": "Mercancías", + "classes": "Clases", + "parts": "Partes" + }, "pedimentos": { "title": "Pedimentos", "pedimento_management": "Gestión de Pedimentos", diff --git a/frontend/src/lib/components/dashboard/classes/columns.ts b/frontend/src/lib/components/dashboard/classes/columns.ts index f5535b3c..69f88da4 100644 --- a/frontend/src/lib/components/dashboard/classes/columns.ts +++ b/frontend/src/lib/components/dashboard/classes/columns.ts @@ -166,6 +166,7 @@ export function createColumns(onSuccess?: () => void): ColumnDef[] { }, { id: "actions", + header: "Acciones", cell: ({ row }) => { return renderComponent(DataTableActions, { item: row.original, onSuccess }); } diff --git a/frontend/src/lib/components/dashboard/classes/data-table-actions.svelte b/frontend/src/lib/components/dashboard/classes/data-table-actions.svelte index 51f21088..ad2ad6b6 100644 --- a/frontend/src/lib/components/dashboard/classes/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/classes/data-table-actions.svelte @@ -5,6 +5,7 @@ import { companyStore } from "$lib/stores/company.svelte"; import { EllipsisVertical, Pencil, LoaderCircle, Trash2 } from 'lucide-svelte'; import CreateEditDialog from "./create-edit-dialog.svelte"; + import { goto } from "$app/navigation"; let { item, @@ -88,7 +89,7 @@ Acciones - + { goto(`/dashboard/goods/classes/edit/${item.id}`); }} > Editar diff --git a/frontend/src/lib/components/sidebar/modules.ts b/frontend/src/lib/components/sidebar/modules.ts index a8d965bd..4adf7499 100644 --- a/frontend/src/lib/components/sidebar/modules.ts +++ b/frontend/src/lib/components/sidebar/modules.ts @@ -13,6 +13,7 @@ import { Users, } from 'lucide-svelte'; import * as m from "$lib/paraglide/messages.js"; +import { Title } from '../ui/alert'; export interface NavItem { title: string; @@ -285,6 +286,21 @@ export function getSidebarData(): SidebarData { }, ], }, + { + title: m["sidebar.goods.title"](), + url: "#", + icon: Package, + items: [ + { + title: m["sidebar.goods.classes"](), + url: "/dashboard/goods/classes", + }, + { + title: m["sidebar.goods.parts"](), + url: "/dashboard/goods/parts", + } + ], + }, { title: m["sidebar.pedimentos.title"](), url: "#", diff --git a/frontend/src/routes/dashboard/goods/classes/+page.server.ts b/frontend/src/routes/dashboard/goods/classes/+page.server.ts new file mode 100644 index 00000000..f3302213 --- /dev/null +++ b/frontend/src/routes/dashboard/goods/classes/+page.server.ts @@ -0,0 +1,63 @@ +import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; + +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); + + if (!accessToken) { + // Cambiamos el objeto de retorno vacío a "classes" + return { error: 'No authenticated', classes: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } + + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + + // --- ZONA DE CAMBIOS DE FILTROS --- + const filters: Record = {}; + + // En tu modelo el campo se llama "class_code", así que buscamos eso o 'code' + const classCode = url.searchParams.get('class_code') || url.searchParams.get('code'); + const description = url.searchParams.get('description'); // Este sirve para description_es o description_en + + if (classCode) filters.class_code = classCode; // Ajustado al modelo + if (description) filters.description = description; + // ---------------------------------- + + const parentData = await parent(); + const cookieCompanyId = cookies.get('active_company_id'); + const companyId = cookieCompanyId + ? parseInt(cookieCompanyId) + : parentData.companies?.[0]?.id; + + if (!companyId) { + return { + error: 'No se encontró una compañía seleccionada', + classes: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } + }; + } + + const queryParams = new URLSearchParams({ + company_id: companyId.toString(), + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + + // --- ZONA DE CAMBIO DE ENDPOINT --- + // Asumiendo que tu endpoint sigue el estándar REST y se llama 'classes' + const response = await authenticatedFetch(`v1/a76/classes?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', classes: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + // Retornamos "classes" para que coincida con lo que espera tu frontend + return { classes: await response.json() }; + + } catch (error) { + console.error('Error loading classes:', error); + return { error: 'Error loading', classes: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } +}; \ No newline at end of file diff --git a/frontend/src/routes/dashboard/goods/classes/+page.svelte b/frontend/src/routes/dashboard/goods/classes/+page.svelte new file mode 100644 index 00000000..7669e858 --- /dev/null +++ b/frontend/src/routes/dashboard/goods/classes/+page.svelte @@ -0,0 +1,239 @@ + + +
+
+
+

Catálogo de Clases

+

+ Gestiona las clases de material (SCAII / SCAF) +

+
+ +
+ + + + Buscar Clase + + +
{ e.preventDefault(); handleSearch(); }} class="space-y-4"> +
+
+ + +
+
+ + {#if searchedClass} + + {/if} +
+
+ + {#if searchError} +
+ {searchError} +
+ {/if} +
+
+
+ + + +
+
+ + {#if searchedClass} + Resultado de la Búsqueda + {:else} + Listado de Clases + {/if} + + + {#if searchedClass} + Se encontró 1 Clase + {:else if listLoading} + Cargando Clases... + {:else} + Total: {classesList.length} registro{classesList.length !== 1 ? 's' : ''} + {/if} + +
+
+
+ + {#if listError} +
+ {listError} +
+ {:else if listLoading} +
+
+
+ Cargando Clases... +
+
+ {:else} + + {/if} +
+
+
\ No newline at end of file diff --git a/frontend/src/routes/dashboard/goods/classes/edit/[[id]]/+page.svelte b/frontend/src/routes/dashboard/goods/classes/edit/[[id]]/+page.svelte new file mode 100644 index 00000000..be859091 --- /dev/null +++ b/frontend/src/routes/dashboard/goods/classes/edit/[[id]]/+page.svelte @@ -0,0 +1,335 @@ + + +
+
+ +
+

{title}

+
+
+ + {#if error} +
+ ⚠️ {error} +
+ {/if} + + {#key id} +
{ e.preventDefault(); handleSubmit(); }} class="space-y-6"> + + + +
+ + +
+
+ + +

Máximo 8 caracteres.

+
+ +
+ + +
+
+ +
+ +