diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/index.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/index.ts new file mode 100644 index 00000000..257406a5 --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/index.ts @@ -0,0 +1,21 @@ +/** + * Índice de exportación para catálogos generales A76 + */ + +// Unit Measures - Main +export * from './unit-measures'; + +// Unit Measures - Customs (Mexican) +export * from './um-customs-mex'; + +// Unit Measures - American +export * from './um-customs-ame'; + +// Unit Measures - ACE +export * from './um-ace'; + +// Unit Measures - OMA +export * from './um-oma'; + +// Locations (from ports) +export * from './locations'; diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts new file mode 100644 index 00000000..888e6f98 --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts @@ -0,0 +1,52 @@ +/** + * API Client para Locations - Ubicaciones relacionadas con puertos + * Basado en los campos location_code y location_description del módulo de puertos + */ +import { api } from '$lib/api'; +import type { ApiResponse } from '$lib/api'; + +export interface Location { + location_code: string; + location_description: string | null; +} + +/** + * Nota: Las ubicaciones están integradas en el módulo de puertos. + * Este archivo proporciona tipos para trabajar con ubicaciones, + * pero las operaciones se realizan a través del módulo de puertos. + * + * Ver: /a76/ports para operaciones relacionadas con ubicaciones + */ + +/** + * Obtiene ubicaciones únicas de los puertos + * Esta función extrae las ubicaciones únicas de la lista de puertos + */ +export async function getLocationsFromPorts(): Promise> { + const portsResponse = await api.get('/a76/ports?page_size=1000'); + + if (portsResponse.error || !portsResponse.data) { + return { + error: portsResponse.error || 'Error al obtener puertos', + status: portsResponse.status + }; + } + + // Extraer ubicaciones únicas + const locationMap = new Map(); + const ports = portsResponse.data.items || []; + + ports.forEach((port: any) => { + if (port.location_code && !locationMap.has(port.location_code)) { + locationMap.set(port.location_code, { + location_code: port.location_code, + location_description: port.location_description + }); + } + }); + + return { + data: Array.from(locationMap.values()), + status: 200 + }; +} diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/um-ace.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-ace.ts new file mode 100644 index 00000000..779996ac --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-ace.ts @@ -0,0 +1,75 @@ +/** + * API Client para UM ACE - Unidades de medida ACE + */ +import { api } from '$lib/api'; +import type { ApiResponse } from '$lib/api'; + +export interface UMACE { + id: number; + code: string; + description: string | null; + created_at: string | null; + updated_at: string | null; +} + +export interface UMACECreate { + code: string; + description?: string | null; +} + +export interface UMACEUpdate { + code?: string; + description?: string | null; +} + +export interface UMACEListResponse { + items: UMACE[]; + total: number; + page: number; + page_size: number; + pages: number; +} + +/** + * Lista todas las unidades de medida ACE + */ +export async function getUMACE( + page = 1, + pageSize = 50, + filters: Record = {} +): Promise> { + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + return await api.get(`/a76/units-of-measure/ace?${queryParams.toString()}`); +} + +/** + * Obtiene una unidad de medida por ID + */ +export async function getUMACEById(id: number): Promise> { + return await api.get(`/a76/units-of-measure/ace/${id}`); +} + +/** + * Crea una nueva unidad de medida + */ +export async function createUMACE(data: UMACECreate): Promise> { + return await api.post('/a76/units-of-measure/ace', data); +} + +/** + * Actualiza una unidad de medida + */ +export async function updateUMACE(id: number, data: UMACEUpdate): Promise> { + return await api.put(`/a76/units-of-measure/ace/${id}`, data); +} + +/** + * Elimina una unidad de medida + */ +export async function deleteUMACE(id: number): Promise> { + return await api.delete(`/a76/units-of-measure/ace/${id}`); +} diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/um-customs-ame.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-customs-ame.ts new file mode 100644 index 00000000..cc1e2569 --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-customs-ame.ts @@ -0,0 +1,75 @@ +/** + * API Client para UM American - Unidades de medida americanas + */ +import { api } from '$lib/api'; +import type { ApiResponse } from '$lib/api'; + +export interface UMCustomsAme { + id: number; + code: string; + description: string | null; + created_at: string | null; + updated_at: string | null; +} + +export interface UMCustomsAmeCreate { + code: string; + description?: string | null; +} + +export interface UMCustomsAmeUpdate { + code?: string; + description?: string | null; +} + +export interface UMCustomsAmeListResponse { + items: UMCustomsAme[]; + total: number; + page: number; + page_size: number; + pages: number; +} + +/** + * Lista todas las unidades de medida americanas + */ +export async function getUMCustomsAme( + page = 1, + pageSize = 50, + filters: Record = {} +): Promise> { + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + return await api.get(`/a76/units-of-measure/american?${queryParams.toString()}`); +} + +/** + * Obtiene una unidad de medida por ID + */ +export async function getUMCustomsAmeById(id: number): Promise> { + return await api.get(`/a76/units-of-measure/american/${id}`); +} + +/** + * Crea una nueva unidad de medida + */ +export async function createUMCustomsAme(data: UMCustomsAmeCreate): Promise> { + return await api.post('/a76/units-of-measure/american', data); +} + +/** + * Actualiza una unidad de medida + */ +export async function updateUMCustomsAme(id: number, data: UMCustomsAmeUpdate): Promise> { + return await api.put(`/a76/units-of-measure/american/${id}`, data); +} + +/** + * Elimina una unidad de medida + */ +export async function deleteUMCustomsAme(id: number): Promise> { + return await api.delete(`/a76/units-of-measure/american/${id}`); +} diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/um-customs-mex.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-customs-mex.ts new file mode 100644 index 00000000..857a77f2 --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-customs-mex.ts @@ -0,0 +1,75 @@ +/** + * API Client para UM Customs (Mexican) - Unidades de medida para aduanas mexicanas + */ +import { api } from '$lib/api'; +import type { ApiResponse } from '$lib/api'; + +export interface UMCustomsMex { + id: number; + code: string; + description: string | null; + created_at: string | null; + updated_at: string | null; +} + +export interface UMCustomsMexCreate { + code: string; + description?: string | null; +} + +export interface UMCustomsMexUpdate { + code?: string; + description?: string | null; +} + +export interface UMCustomsMexListResponse { + items: UMCustomsMex[]; + total: number; + page: number; + page_size: number; + pages: number; +} + +/** + * Lista todas las unidades de medida para aduanas mexicanas + */ +export async function getUMCustomsMex( + page = 1, + pageSize = 50, + filters: Record = {} +): Promise> { + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + return await api.get(`/a76/units-of-measure/customs?${queryParams.toString()}`); +} + +/** + * Obtiene una unidad de medida por ID + */ +export async function getUMCustomsMexById(id: number): Promise> { + return await api.get(`/a76/units-of-measure/customs/${id}`); +} + +/** + * Crea una nueva unidad de medida + */ +export async function createUMCustomsMex(data: UMCustomsMexCreate): Promise> { + return await api.post('/a76/units-of-measure/customs', data); +} + +/** + * Actualiza una unidad de medida + */ +export async function updateUMCustomsMex(id: number, data: UMCustomsMexUpdate): Promise> { + return await api.put(`/a76/units-of-measure/customs/${id}`, data); +} + +/** + * Elimina una unidad de medida + */ +export async function deleteUMCustomsMex(id: number): Promise> { + return await api.delete(`/a76/units-of-measure/customs/${id}`); +} diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/um-oma.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-oma.ts new file mode 100644 index 00000000..40708461 --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/um-oma.ts @@ -0,0 +1,75 @@ +/** + * API Client para UM OMA - Unidades de medida OMA + */ +import { api } from '$lib/api'; +import type { ApiResponse } from '$lib/api'; + +export interface UMOMA { + id: number; + code: string; + description: string | null; + created_at: string | null; + updated_at: string | null; +} + +export interface UMOMACreate { + code: string; + description?: string | null; +} + +export interface UMOMAUpdate { + code?: string; + description?: string | null; +} + +export interface UMOMAListResponse { + items: UMOMA[]; + total: number; + page: number; + page_size: number; + pages: number; +} + +/** + * Lista todas las unidades de medida OMA + */ +export async function getUMOMA( + page = 1, + pageSize = 50, + filters: Record = {} +): Promise> { + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + return await api.get(`/a76/units-of-measure/oma?${queryParams.toString()}`); +} + +/** + * Obtiene una unidad de medida por ID + */ +export async function getUMOMAById(id: number): Promise> { + return await api.get(`/a76/units-of-measure/oma/${id}`); +} + +/** + * Crea una nueva unidad de medida + */ +export async function createUMOMA(data: UMOMACreate): Promise> { + return await api.post('/a76/units-of-measure/oma', data); +} + +/** + * Actualiza una unidad de medida + */ +export async function updateUMOMA(id: number, data: UMOMAUpdate): Promise> { + return await api.put(`/a76/units-of-measure/oma/${id}`, data); +} + +/** + * Elimina una unidad de medida + */ +export async function deleteUMOMA(id: number): Promise> { + return await api.delete(`/a76/units-of-measure/oma/${id}`); +} diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-measures.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-measures.ts new file mode 100644 index 00000000..6497bcda --- /dev/null +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-measures.ts @@ -0,0 +1,75 @@ +/** + * API Client para Unit Measures - Catálogo principal de unidades de medida + */ +import { api } from '$lib/api'; +import type { ApiResponse } from '$lib/api'; + +export interface UnitMeasure { + id: number; + code: string; + description: string | null; + created_at: string | null; + updated_at: string | null; +} + +export interface UnitMeasureCreate { + code: string; + description?: string | null; +} + +export interface UnitMeasureUpdate { + code?: string; + description?: string | null; +} + +export interface UnitMeasureListResponse { + items: UnitMeasure[]; + total: number; + page: number; + page_size: number; + pages: number; +} + +/** + * Lista todas las unidades de medida + */ +export async function getUnitMeasures( + page = 1, + pageSize = 50, + filters: Record = {} +): Promise> { + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + return await api.get(`/a76/units-of-measure?${queryParams.toString()}`); +} + +/** + * Obtiene una unidad de medida por ID + */ +export async function getUnitMeasure(id: number): Promise> { + return await api.get(`/a76/units-of-measure/${id}`); +} + +/** + * Crea una nueva unidad de medida + */ +export async function createUnitMeasure(data: UnitMeasureCreate): Promise> { + return await api.post('/a76/units-of-measure', data); +} + +/** + * Actualiza una unidad de medida + */ +export async function updateUnitMeasure(id: number, data: UnitMeasureUpdate): Promise> { + return await api.put(`/a76/units-of-measure/${id}`, data); +} + +/** + * Elimina una unidad de medida + */ +export async function deleteUnitMeasure(id: number): Promise> { + return await api.delete(`/a76/units-of-measure/${id}`); +} diff --git a/frontend/src/lib/components/dashboard/locations/columns.ts b/frontend/src/lib/components/dashboard/locations/columns.ts new file mode 100644 index 00000000..f639fec8 --- /dev/null +++ b/frontend/src/lib/components/dashboard/locations/columns.ts @@ -0,0 +1,20 @@ +import type { ColumnDef } from '@tanstack/table-core'; + +export interface Location { + location_code: string; + location_description: string | null; +} + +export function createColumns(): ColumnDef[] { + return [ + { + accessorKey: 'location_code', + header: 'Código', + }, + { + accessorKey: 'location_description', + header: 'Descripción', + cell: ({ row }) => row.original.location_description || '-' + } + ]; +} diff --git a/frontend/src/lib/components/dashboard/locations/data-table.svelte b/frontend/src/lib/components/dashboard/locations/data-table.svelte new file mode 100644 index 00000000..eecc0a26 --- /dev/null +++ b/frontend/src/lib/components/dashboard/locations/data-table.svelte @@ -0,0 +1,76 @@ + + +
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {#if !header.isPlaceholder} + + {/if} + + {/each} + + {/each} + + + {#each table.getRowModel().rows as row (row.id)} + + {#each row.getVisibleCells() as cell (cell.id)} + + + + {/each} + + {:else} + + + No hay resultados. + + + {/each} + + +
+ +
+
+ Total: {totalItems} ubicaciones únicas +
+
diff --git a/frontend/src/lib/components/dashboard/units_of_measure/customs/columns.ts b/frontend/src/lib/components/dashboard/units_of_measure/customs/columns.ts new file mode 100644 index 00000000..db580d6b --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/customs/columns.ts @@ -0,0 +1,32 @@ +import type { ColumnDef } from '@tanstack/table-core'; +import { renderComponent } from '$lib/components/ui/data-table'; +import DataTableActions from './data-table-actions.svelte'; + +export interface UMCustomsMex { + id: number; + code: string; + description: string | null; +} + +export function createColumns(onSuccess?: () => void): ColumnDef[] { + return [ + { + accessorKey: 'code', + header: 'Código', + }, + { + accessorKey: 'description', + header: 'Descripción', + cell: ({ row }) => row.original.description || '-' + }, + { + id: 'actions', + cell: ({ row }) => { + return renderComponent(DataTableActions, { + item: row.original, + onSuccess + }); + } + } + ]; +} diff --git a/frontend/src/lib/components/dashboard/units_of_measure/customs/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/units_of_measure/customs/create-edit-dialog.svelte new file mode 100644 index 00000000..46319d69 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/customs/create-edit-dialog.svelte @@ -0,0 +1,113 @@ + + + + + + {title} + + +
+ {#if error} +
{error}
+ {/if} + +
+ + +
+ +
+ + +
+
+ +
+ + +
+
+
diff --git a/frontend/src/lib/components/dashboard/units_of_measure/customs/data-table-actions.svelte b/frontend/src/lib/components/dashboard/units_of_measure/customs/data-table-actions.svelte new file mode 100644 index 00000000..0e845518 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/customs/data-table-actions.svelte @@ -0,0 +1,79 @@ + + + + + {#snippet child({ props })} + + {/snippet} + + + Acciones + dialogOpen = true}> + + Editar + + + {#if loading} + + {:else} + + {/if} + Eliminar + + + + + diff --git a/frontend/src/lib/components/dashboard/units_of_measure/customs/data-table.svelte b/frontend/src/lib/components/dashboard/units_of_measure/customs/data-table.svelte new file mode 100644 index 00000000..ea8886c5 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/customs/data-table.svelte @@ -0,0 +1,106 @@ + + +
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {#if !header.isPlaceholder} + + {/if} + + {/each} + + {/each} + + + {#each table.getRowModel().rows as row (row.id)} + + {#each row.getVisibleCells() as cell (cell.id)} + + + + {/each} + + {:else} + + + No hay resultados. + + + {/each} + + +
+ +
+
+ Total: {totalItems} +
+
+ + +
+
diff --git a/frontend/src/lib/components/dashboard/units_of_measure/general/columns.ts b/frontend/src/lib/components/dashboard/units_of_measure/general/columns.ts new file mode 100644 index 00000000..710cb488 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/general/columns.ts @@ -0,0 +1,32 @@ +import type { ColumnDef } from '@tanstack/table-core'; +import { renderComponent } from '$lib/components/ui/data-table'; +import DataTableActions from './data-table-actions.svelte'; + +export interface UnitMeasure { + id: number; + code: string; + description: string | null; +} + +export function createColumns(onSuccess?: () => void): ColumnDef[] { + return [ + { + accessorKey: 'code', + header: 'Código', + }, + { + accessorKey: 'description', + header: 'Descripción', + cell: ({ row }) => row.original.description || '-' + }, + { + id: 'actions', + cell: ({ row }) => { + return renderComponent(DataTableActions, { + item: row.original, + onSuccess + }); + } + } + ]; +} diff --git a/frontend/src/lib/components/dashboard/units_of_measure/general/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/units_of_measure/general/create-edit-dialog.svelte new file mode 100644 index 00000000..ffbb4054 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/general/create-edit-dialog.svelte @@ -0,0 +1,113 @@ + + + + + + {title} + + +
+ {#if error} +
{error}
+ {/if} + +
+ + +
+ +
+ + +
+
+ +
+ + +
+
+
diff --git a/frontend/src/lib/components/dashboard/units_of_measure/general/data-table-actions.svelte b/frontend/src/lib/components/dashboard/units_of_measure/general/data-table-actions.svelte new file mode 100644 index 00000000..66641d66 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/general/data-table-actions.svelte @@ -0,0 +1,79 @@ + + + + + {#snippet child({ props })} + + {/snippet} + + + Acciones + dialogOpen = true}> + + Editar + + + {#if loading} + + {:else} + + {/if} + Eliminar + + + + + diff --git a/frontend/src/lib/components/dashboard/units_of_measure/general/data-table.svelte b/frontend/src/lib/components/dashboard/units_of_measure/general/data-table.svelte new file mode 100644 index 00000000..ea8886c5 --- /dev/null +++ b/frontend/src/lib/components/dashboard/units_of_measure/general/data-table.svelte @@ -0,0 +1,106 @@ + + +
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {#if !header.isPlaceholder} + + {/if} + + {/each} + + {/each} + + + {#each table.getRowModel().rows as row (row.id)} + + {#each row.getVisibleCells() as cell (cell.id)} + + + + {/each} + + {:else} + + + No hay resultados. + + + {/each} + + +
+ +
+
+ Total: {totalItems} +
+
+ + +
+
diff --git a/frontend/src/lib/components/sidebar/modules.ts b/frontend/src/lib/components/sidebar/modules.ts index 1ebaea56..56c7e58d 100644 --- a/frontend/src/lib/components/sidebar/modules.ts +++ b/frontend/src/lib/components/sidebar/modules.ts @@ -179,7 +179,7 @@ export function getSidebarData(): SidebarData { }, { title: m["sidebar.general_catalogs.incoterms"](), - url: "#", + url: "/dashboard/reference_data/incoterms", }, { title: m["sidebar.general_catalogs.inpc"](), @@ -195,7 +195,7 @@ export function getSidebarData(): SidebarData { }, { title: m["sidebar.general_catalogs.valuation_methods"](), - url: "#", + url: "/dashboard/reference_data/valuation_methods", }, { title: m["sidebar.general_catalogs.countries"](), @@ -207,23 +207,23 @@ export function getSidebarData(): SidebarData { }, { title: m["sidebar.general_catalogs.unit_measures"](), - url: "/dashboard/general_catalogs/units_of_measures", + url: "/dashboard/general_catalogs/units_of_measure/general", }, { title: m["sidebar.general_catalogs.um_customs_mex"](), - url: "#", + url: "/dashboard/general_catalogs/units_of_measure/customs", }, { title: m["sidebar.general_catalogs.um_customs_ame"](), - url: "#", + url: "/dashboard/general_catalogs/units_of_measure/american", }, { title: m["sidebar.general_catalogs.um_ace"](), - url: "#", + url: "/dashboard/general_catalogs/units_of_measure/ace", }, { title: m["sidebar.general_catalogs.um_oma"](), - url: "#", + url: "/dashboard/general_catalogs/units_of_measure/oma", }, { title: m["sidebar.general_catalogs.conversions"](), @@ -239,7 +239,7 @@ export function getSidebarData(): SidebarData { }, { title: m["sidebar.general_catalogs.currency_types"](), - url: "#", + url: "/dashboard/reference_data/currency_types", }, { title: m["sidebar.general_catalogs.multi_currency"](), @@ -247,7 +247,7 @@ export function getSidebarData(): SidebarData { }, { title: m["sidebar.general_catalogs.invoice_types"](), - url: "#", + url: "/dashboard/reference_data/invoice_types", }, { title: m["sidebar.general_catalogs.electronic_signatures"](), @@ -259,20 +259,16 @@ export function getSidebarData(): SidebarData { }, { title: m["sidebar.general_catalogs.customs_warehouses"](), - url: "#", + url: "/dashboard/reference_data/customs_warehouses", }, { title: m["sidebar.general_catalogs.locations"](), - url: "#", + url: "/dashboard/general_catalogs/locations", }, { title: m["sidebar.general_catalogs.doda"](), url: "/dashboard/general_catalogs/doda", }, - { - title: m["sidebar.general_catalogs.packing_list"](), - url: "#", - }, { title: m["sidebar.general_catalogs.prevalidators"](), url: "/dashboard/general_catalogs/prevalidators", @@ -281,10 +277,6 @@ export function getSidebarData(): SidebarData { title: m["sidebar.general_catalogs.electronic_notices"](), url: "/dashboard/general_catalogs/electronic_notices", }, - { - title: m["sidebar.general_catalogs.back_flush"](), - url: "#", - }, { title: m["sidebar.general_catalogs.crossing_notice"](), url: "#", diff --git a/frontend/src/routes/dashboard/general_catalogs/classification_concepts/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/classification_concepts/+page.server.ts index 71112ed4..0348b6bc 100644 --- a/frontend/src/routes/dashboard/general_catalogs/classification_concepts/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/classification_concepts/+page.server.ts @@ -1,20 +1,34 @@ -import { getClassificationConcepts } from '$lib/api/dashboard/a76/classification-concepts'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const classification = url.searchParams.get('classification'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (classification) filters.classification = classification; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', classifications: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getClassificationConcepts(page, pageSize, filters); - - return { - classifications: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const classification = url.searchParams.get('classification'); + const description = url.searchParams.get('description'); + + if (classification) filters.classification = classification; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/classification-concepts?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', classifications: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { classifications: await response.json() }; + } catch (error) { + console.error('Error loading classification concepts:', error); + return { error: 'Error loading', classifications: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/concepts/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/concepts/+page.server.ts index 7821a462..3b00219a 100644 --- a/frontend/src/routes/dashboard/general_catalogs/concepts/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/concepts/+page.server.ts @@ -1,20 +1,79 @@ -import { getConcepts } from '$lib/api/dashboard/a76/concepts'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + // Esperar a que el layout padre valide/refresque el token + const parentData = await parent(); - if (code) filters.code = code; - if (description) filters.description = description; + const { accessToken } = getAuthTokens(cookies); - const response = await getConcepts(page, pageSize, filters); - - return { - concepts: response.data - }; + if (!accessToken) { + return { + error: 'No authenticated', + concepts: { + 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; + + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + // Construir URL con parámetros + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + + const response = await authenticatedFetch( + `v1/a76/concepts?${queryParams.toString()}`, + { method: 'GET' }, + cookies, + fetch + ); + + if (!response.ok) { + return { + error: 'Failed to load concepts', + concepts: { + items: [], + total: 0, + page: page, + page_size: pageSize, + pages: 0 + } + }; + } + + const data = await response.json(); + + return { + concepts: data + }; + } catch (error) { + console.error('Error loading concepts:', error); + return { + error: 'Error loading concepts', + concepts: { + items: [], + total: 0, + page: 1, + page_size: 50, + pages: 0 + } + }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.server.ts index bf477dc2..78f0e9a9 100644 --- a/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.server.ts @@ -1,20 +1,34 @@ -import { getCustomsBrokerConcepts } from '$lib/api/dashboard/a76/customs-broker-concepts'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (code) filters.code = code; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', concepts: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getCustomsBrokerConcepts(page, pageSize, filters); - - return { - concepts: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/customs-broker-concepts?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', concepts: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { concepts: await response.json() }; + } catch (error) { + console.error('Error loading customs broker concepts:', error); + return { error: 'Error loading', concepts: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/doda/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/doda/+page.server.ts index 62a4a297..8c8820e5 100644 --- a/frontend/src/routes/dashboard/general_catalogs/doda/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/doda/+page.server.ts @@ -1,20 +1,34 @@ -import { getDODAs } from '$lib/api/dashboard/a76/doda'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (code) filters.code = code; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', dodas: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getDODAs(page, pageSize, filters); - - return { - dodas: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/doda?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', dodas: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { dodas: await response.json() }; + } catch (error) { + console.error('Error loading DODAs:', error); + return { error: 'Error loading', dodas: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.server.ts index a063b335..c830acb3 100644 --- a/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.server.ts @@ -1,20 +1,34 @@ -import { getElectronicNotices } from '$lib/api/dashboard/a76/electronic-notices'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (code) filters.code = code; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', notices: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getElectronicNotices(page, pageSize, filters); - - return { - notices: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/electronic-notices?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', notices: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { notices: await response.json() }; + } catch (error) { + console.error('Error loading electronic notices:', error); + return { error: 'Error loading', notices: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.server.ts index 25265688..61f04441 100644 --- a/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.server.ts @@ -1,20 +1,34 @@ -import { getEquivalencies } from '$lib/api/dashboard/a76/equivalencies'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const fraccion_mex = url.searchParams.get('fraccion_mex'); - const fraccion_us = url.searchParams.get('fraccion_us'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (fraccion_mex) filters.fraccion_mex = fraccion_mex; - if (fraccion_us) filters.fraccion_us = fraccion_us; + if (!accessToken) { + return { error: 'No authenticated', equivalencies: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getEquivalencies(page, pageSize, filters); - - return { - equivalencies: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const fraccion_mex = url.searchParams.get('fraccion_mex'); + const fraccion_us = url.searchParams.get('fraccion_us'); + + if (fraccion_mex) filters.fraccion_mex = fraccion_mex; + if (fraccion_us) filters.fraccion_us = fraccion_us; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/equivalencies?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', equivalencies: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { equivalencies: await response.json() }; + } catch (error) { + console.error('Error loading equivalencies:', error); + return { error: 'Error loading', equivalencies: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/error_catalogs/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/error_catalogs/+page.server.ts index 308792ad..e951d645 100644 --- a/frontend/src/routes/dashboard/general_catalogs/error_catalogs/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/error_catalogs/+page.server.ts @@ -1,20 +1,34 @@ -import { getErrorCatalogs } from '$lib/api/dashboard/a76/error-catalogs'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (code) filters.code = code; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', errors: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getErrorCatalogs(page, pageSize, filters); - - return { - errors: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/error-catalogs?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', errors: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { errors: await response.json() }; + } catch (error) { + console.error('Error loading error catalogs:', error); + return { error: 'Error loading', errors: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/inpc/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/inpc/+page.server.ts index f8f78c79..ab37b160 100644 --- a/frontend/src/routes/dashboard/general_catalogs/inpc/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/inpc/+page.server.ts @@ -1,20 +1,34 @@ -import { getINPCs } from '$lib/api/dashboard/a76/inpc'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const year = url.searchParams.get('year'); - const month = url.searchParams.get('month'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (year) filters.year = year; - if (month) filters.month = month; + if (!accessToken) { + return { error: 'No authenticated', inpcs: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getINPCs(page, pageSize, filters); - - return { - inpcs: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const year = url.searchParams.get('year'); + const month = url.searchParams.get('month'); + + if (year) filters.year = year; + if (month) filters.month = month; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/inpc?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', inpcs: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { inpcs: await response.json() }; + } catch (error) { + console.error('Error loading INPCs:', error); + return { error: 'Error loading', inpcs: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/legends/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/legends/+page.server.ts index 724f084b..7879b99f 100644 --- a/frontend/src/routes/dashboard/general_catalogs/legends/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/legends/+page.server.ts @@ -1,20 +1,34 @@ -import { getLegends } from '$lib/api/dashboard/a76/legends'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (code) filters.code = code; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', legends: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getLegends(page, pageSize, filters); - - return { - legends: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/legends?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', legends: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { legends: await response.json() }; + } catch (error) { + console.error('Error loading legends:', error); + return { error: 'Error loading', legends: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/locations/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/locations/+page.server.ts new file mode 100644 index 00000000..773d73c8 --- /dev/null +++ b/frontend/src/routes/dashboard/general_catalogs/locations/+page.server.ts @@ -0,0 +1,71 @@ +import { getServerApiUrl, getAuthTokens } from '$lib/server/api'; +import type { PageServerLoad } from './$types'; +import { redirect } from '@sveltejs/kit'; + +export const load: PageServerLoad = async ({ cookies, fetch, url }) => { + const { accessToken } = getAuthTokens(cookies); + + if (!accessToken) { + throw redirect(302, '/login'); + } + + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('page_size')) || 1000; + + const apiUrl = getServerApiUrl(); + // Get locations from ports + const endpoint = `${apiUrl}api/v1/a76/ports?page=${page}&page_size=${pageSize}`; + + try { + const response = await fetch(endpoint, { + headers: { + 'Authorization': `Bearer ${accessToken}` + } + }); + + if (!response.ok) { + console.error(`Error fetching Ports for locations: ${response.status} ${response.statusText}`); + return { + items: [], + total: 0, + page: 1, + pageSize, + pages: 0, + error: `Error: ${response.statusText}` + }; + } + + const data = await response.json(); + + // Extract unique locations + const locationMap = new Map(); + data.items.forEach((port: any) => { + if (port.location_code && !locationMap.has(port.location_code)) { + locationMap.set(port.location_code, { + location_code: port.location_code, + location_description: port.location_description + }); + } + }); + + const locations = Array.from(locationMap.values()); + + return { + items: locations, + total: locations.length, + page: 1, + pageSize: locations.length, + pages: 1 + }; + } catch (error) { + console.error('Error fetching Locations:', error); + return { + items: [], + total: 0, + page: 1, + pageSize, + pages: 0, + error: 'Error al cargar datos' + }; + } +}; diff --git a/frontend/src/routes/dashboard/general_catalogs/locations/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/locations/+page.svelte new file mode 100644 index 00000000..d7e5ed3c --- /dev/null +++ b/frontend/src/routes/dashboard/general_catalogs/locations/+page.svelte @@ -0,0 +1,48 @@ + + +
+
+
+

Ubicaciones

+

+ Catálogo de ubicaciones extraídas de puertos +

+
+
+ +
+
+ + + + + + +
diff --git a/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.server.ts index 07325ba2..854d9ec5 100644 --- a/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.server.ts @@ -1,20 +1,34 @@ -import { getMultiCurrencyTypes } from '$lib/api/dashboard/a76/multi-currency-types'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const key = url.searchParams.get('key'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (key) filters.key = key; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', types: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getMultiCurrencyTypes(page, pageSize, filters); - - return { - types: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const key = url.searchParams.get('key'); + const description = url.searchParams.get('description'); + + if (key) filters.key = key; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/multi-currency-types?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', types: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { types: await response.json() }; + } catch (error) { + console.error('Error loading multi currency types:', error); + return { error: 'Error loading', types: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/packages/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/packages/+page.server.ts index 5f36bdae..a7fa76a8 100644 --- a/frontend/src/routes/dashboard/general_catalogs/packages/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/packages/+page.server.ts @@ -1,20 +1,79 @@ -import { getPackages } from '$lib/api/dashboard/a76/packages'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const key = url.searchParams.get('key'); - const description_es = url.searchParams.get('description_es'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + // Esperar a que el layout padre valide/refresque el token + const parentData = await parent(); - if (key) filters.key = key; - if (description_es) filters.description_es = description_es; + const { accessToken } = getAuthTokens(cookies); - const response = await getPackages(page, pageSize, filters); - - return { - packages: response.data - }; + if (!accessToken) { + return { + error: 'No authenticated', + packages: { + 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; + + const filters: Record = {}; + const key = url.searchParams.get('key'); + const description_es = url.searchParams.get('description_es'); + + if (key) filters.key = key; + if (description_es) filters.description_es = description_es; + + // Construir URL con parámetros + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + + const response = await authenticatedFetch( + `v1/a76/packages?${queryParams.toString()}`, + { method: 'GET' }, + cookies, + fetch + ); + + if (!response.ok) { + return { + error: 'Failed to load packages', + packages: { + items: [], + total: 0, + page: page, + page_size: pageSize, + pages: 0 + } + }; + } + + const data = await response.json(); + + return { + packages: data + }; + } catch (error) { + console.error('Error loading packages:', error); + return { + error: 'Error loading packages', + packages: { + items: [], + total: 0, + page: 1, + page_size: 50, + pages: 0 + } + }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.server.ts index 49ee3573..7954a98b 100644 --- a/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.server.ts @@ -1,20 +1,34 @@ -import { getPrevalidators } from '$lib/api/dashboard/a76/prevalidators'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const code = url.searchParams.get('code'); - const description = url.searchParams.get('description'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (code) filters.code = code; - if (description) filters.description = description; + if (!accessToken) { + return { error: 'No authenticated', prevalidators: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getPrevalidators(page, pageSize, filters); - - return { - prevalidators: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const code = url.searchParams.get('code'); + const description = url.searchParams.get('description'); + + if (code) filters.code = code; + if (description) filters.description = description; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/prevalidators?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', prevalidators: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { prevalidators: await response.json() }; + } catch (error) { + console.error('Error loading prevalidators:', error); + return { error: 'Error loading', prevalidators: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/signatures/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/signatures/+page.server.ts index c6ccdd88..ee89e76b 100644 --- a/frontend/src/routes/dashboard/general_catalogs/signatures/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/signatures/+page.server.ts @@ -1,20 +1,34 @@ -import { getSignatures } from '$lib/api/dashboard/a76/signatures'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; - const name = url.searchParams.get('name'); - const position = url.searchParams.get('position'); +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - if (name) filters.name = name; - if (position) filters.position = position; + if (!accessToken) { + return { error: 'No authenticated', signatures: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } - const response = await getSignatures(page, pageSize, filters); - - return { - signatures: response.data - }; + try { + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('pageSize')) || 50; + const filters: Record = {}; + const name = url.searchParams.get('name'); + const position = url.searchParams.get('position'); + + if (name) filters.name = name; + if (position) filters.position = position; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/signatures?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', signatures: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { signatures: await response.json() }; + } catch (error) { + console.error('Error loading signatures:', error); + return { error: 'Error loading', signatures: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.server.ts index 8df8bf46..71e39338 100644 --- a/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.server.ts +++ b/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.server.ts @@ -1,15 +1,29 @@ -import { getUnitConversions } from '$lib/api/dashboard/a76/unit-conversions'; import type { PageServerLoad } from './$types'; +import { getAuthTokens, authenticatedFetch } from '$lib/server/api'; -export const load: PageServerLoad = async ({ url }) => { - const page = Number(url.searchParams.get('page')) || 1; - const pageSize = Number(url.searchParams.get('pageSize')) || 50; - - const filters: Record = {}; +export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { + await parent(); + const { accessToken } = getAuthTokens(cookies); - const response = await getUnitConversions(page, pageSize, filters); - - return { - conversions: response.data - }; + if (!accessToken) { + return { error: 'No authenticated', conversions: { 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; + const filters: Record = {}; + + const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), ...filters }); + const response = await authenticatedFetch(`v1/a76/unit-conversions?${queryParams.toString()}`, { method: 'GET' }, cookies, fetch); + + if (!response.ok) { + return { error: 'Failed to load', conversions: { items: [], total: 0, page, page_size: pageSize, pages: 0 } }; + } + + return { conversions: await response.json() }; + } catch (error) { + console.error('Error loading unit conversions:', error); + return { error: 'Error loading', conversions: { items: [], total: 0, page: 1, page_size: 50, pages: 0 } }; + } }; diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.server.ts new file mode 100644 index 00000000..fd469a80 --- /dev/null +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.server.ts @@ -0,0 +1,56 @@ +import { getServerApiUrl, getAuthTokens } from '$lib/server/api'; +import type { PageServerLoad } from './$types'; +import { redirect } from '@sveltejs/kit'; + +export const load: PageServerLoad = async ({ cookies, fetch, url }) => { + const { accessToken } = getAuthTokens(cookies); + + if (!accessToken) { + throw redirect(302, '/login'); + } + + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('page_size')) || 50; + + const apiUrl = getServerApiUrl(); + const endpoint = `${apiUrl}api/v1/a76/units-of-measure/customs?page=${page}&page_size=${pageSize}`; + + try { + const response = await fetch(endpoint, { + headers: { + 'Authorization': `Bearer ${accessToken}` + } + }); + + if (!response.ok) { + console.error(`Error fetching Customs units: ${response.status} ${response.statusText}`); + return { + items: [], + total: 0, + page, + pageSize, + pages: 0, + error: `Error: ${response.statusText}` + }; + } + + const data = await response.json(); + return { + items: data.items, + total: data.total, + page: data.page, + pageSize: data.page_size, + pages: data.pages + }; + } catch (error) { + console.error('Error fetching Customs units:', error); + return { + items: [], + total: 0, + page, + pageSize, + pages: 0, + error: 'Error al cargar datos' + }; + } +}; diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte new file mode 100644 index 00000000..3b82e86f --- /dev/null +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte @@ -0,0 +1,61 @@ + + +
+
+
+

Unidades de Medida Aduanas MEX

+

+ Catálogo de unidades de medida para aduanas mexicanas +

+
+
+ + +
+
+ + + + + + + + +
diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.server.ts b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.server.ts new file mode 100644 index 00000000..b0490e54 --- /dev/null +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.server.ts @@ -0,0 +1,56 @@ +import { getServerApiUrl, getAuthTokens } from '$lib/server/api'; +import type { PageServerLoad } from './$types'; +import { redirect } from '@sveltejs/kit'; + +export const load: PageServerLoad = async ({ cookies, fetch, url }) => { + const { accessToken } = getAuthTokens(cookies); + + if (!accessToken) { + throw redirect(302, '/login'); + } + + const page = Number(url.searchParams.get('page')) || 1; + const pageSize = Number(url.searchParams.get('page_size')) || 50; + + const apiUrl = getServerApiUrl(); + const endpoint = `${apiUrl}api/v1/a76/units-of-measure?page=${page}&page_size=${pageSize}`; + + try { + const response = await fetch(endpoint, { + headers: { + 'Authorization': `Bearer ${accessToken}` + } + }); + + if (!response.ok) { + console.error(`Error fetching General units: ${response.status} ${response.statusText}`); + return { + items: [], + total: 0, + page, + pageSize, + pages: 0, + error: `Error: ${response.statusText}` + }; + } + + const data = await response.json(); + return { + items: data.items, + total: data.total, + page: data.page, + pageSize: data.page_size, + pages: data.pages + }; + } catch (error) { + console.error('Error fetching General units:', error); + return { + items: [], + total: 0, + page, + pageSize, + pages: 0, + error: 'Error al cargar datos' + }; + } +}; diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte new file mode 100644 index 00000000..1dbdf49b --- /dev/null +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte @@ -0,0 +1,61 @@ + + +
+
+
+

Unidades de Medida Generales

+

+ Catálogo general de unidades de medida +

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