diff --git a/src/components/layout/Sidebar.vue b/src/components/layout/Sidebar.vue
index dc22bfd..9a34fb0 100644
--- a/src/components/layout/Sidebar.vue
+++ b/src/components/layout/Sidebar.vue
@@ -1,15 +1,18 @@
diff --git a/src/modules/catalog/components/units/Units.vue b/src/modules/catalog/components/units/Units.vue
index e6e4568..ae09f1a 100644
--- a/src/modules/catalog/components/units/Units.vue
+++ b/src/modules/catalog/components/units/Units.vue
@@ -12,6 +12,8 @@ import Tag from 'primevue/tag';
import Toast from 'primevue/toast';
import ConfirmDialog from 'primevue/confirmdialog';
import ProgressSpinner from 'primevue/progressspinner';
+import InputText from 'primevue/inputtext';
+import Select from 'primevue/select';
import { useUnitOfMeasureStore } from '../../stores/unitOfMeasureStore';
import UnitsForm from './UnitsForm.vue';
import type { UnitOfMeasure, CreateUnitOfMeasureData } from '../../types/unit-measure.interfaces';
@@ -36,18 +38,40 @@ const home = ref({
const showDialog = ref(false);
const isEditing = ref(false);
const selectedUnit = ref(null);
+const unitsFormRef = ref | null>(null);
+const search = ref('');
+const statusFilter = ref<'all' | 'active' | 'inactive'>('all');
// Computed
const units = computed(() => unitStore.units);
const loading = computed(() => unitStore.loading);
+const statusFilterOptions = [
+ { label: 'Todas', value: 'all' },
+ { label: 'Activas', value: 'active' },
+ { label: 'Inactivas', value: 'inactive' },
+];
-const getStatusConfig = (isActive: number) => {
- return isActive === 1
+const getStatusConfig = (isActive: boolean) => {
+ return isActive
? { label: 'Activa', severity: 'success' }
: { label: 'Inactiva', severity: 'secondary' };
};
// Methods
+const buildFilters = () => ({
+ paginate: true,
+ per_page: 25,
+ search: search.value.trim(),
+ is_active: statusFilter.value === 'all' ? undefined : statusFilter.value === 'active',
+});
+
+const loadUnits = async (force = false) => {
+ await unitStore.fetchUnits({
+ force,
+ ...buildFilters(),
+ });
+};
+
const openCreateDialog = () => {
isEditing.value = false;
selectedUnit.value = null;
@@ -60,33 +84,67 @@ const openEditDialog = (unit: UnitOfMeasure) => {
showDialog.value = true;
};
+const handleCreateUnit = async (data: CreateUnitOfMeasureData) => {
+ await unitStore.createUnit(data);
+ toast.add({
+ severity: 'success',
+ summary: 'Creación Exitosa',
+ detail: 'La unidad de medida ha sido creada correctamente.',
+ life: 3000,
+ });
+};
+
+const handleUpdateUnit = async (id: number, data: CreateUnitOfMeasureData) => {
+ await unitStore.updateUnit(id, data);
+ toast.add({
+ severity: 'success',
+ summary: 'Actualización Exitosa',
+ detail: 'La unidad de medida ha sido actualizada correctamente.',
+ life: 3000,
+ });
+};
+
const handleSaveUnit = async (data: CreateUnitOfMeasureData) => {
try {
if (isEditing.value && selectedUnit.value) {
- await unitStore.updateUnit(selectedUnit.value.id, data);
- toast.add({
- severity: 'success',
- summary: 'Actualización Exitosa',
- detail: 'La unidad de medida ha sido actualizada correctamente.',
- life: 3000
- });
+ await handleUpdateUnit(selectedUnit.value.id, data);
} else {
- await unitStore.createUnit(data);
- toast.add({
- severity: 'success',
- summary: 'Creación Exitosa',
- detail: 'La unidad de medida ha sido creada correctamente.',
- life: 3000
- });
+ await handleCreateUnit(data);
}
+
showDialog.value = false;
+ selectedUnit.value = null;
+ unitsFormRef.value?.resetSubmitting();
} catch (error) {
console.error('Error saving unit:', error);
+
+ const requestError = error as {
+ response?: {
+ status?: number;
+ data?: {
+ errors?: Record;
+ message?: string;
+ };
+ };
+ };
+
+ if (requestError.response?.status === 422 && requestError.response.data?.errors) {
+ unitsFormRef.value?.setValidationErrors(requestError.response.data.errors);
+ toast.add({
+ severity: 'warn',
+ summary: 'Errores de validación',
+ detail: 'Corrige los campos marcados para continuar.',
+ life: 4000,
+ });
+ return;
+ }
+
+ unitsFormRef.value?.resetSubmitting();
toast.add({
severity: 'error',
summary: 'Error',
- detail: 'No se pudo guardar la unidad de medida. Por favor, intenta nuevamente.',
- life: 3000
+ detail: requestError.response?.data?.message || 'No se pudo guardar la unidad de medida. Por favor, intenta nuevamente.',
+ life: 3000,
});
}
};
@@ -106,11 +164,12 @@ const confirmDelete = (unit: UnitOfMeasure) => {
const deleteUnit = async (id: number) => {
try {
await unitStore.deleteUnit(id);
+ await loadUnits(true);
toast.add({
severity: 'success',
summary: 'Eliminación Exitosa',
detail: 'La unidad de medida ha sido eliminada correctamente.',
- life: 3000
+ life: 3000,
});
} catch (error) {
console.error('Error deleting unit:', error);
@@ -118,14 +177,24 @@ const deleteUnit = async (id: number) => {
severity: 'error',
summary: 'Error',
detail: 'No se pudo eliminar la unidad de medida. Puede estar en uso.',
- life: 3000
+ life: 3000,
});
}
};
+const applyFilters = async () => {
+ await loadUnits(true);
+};
+
+const clearFilters = async () => {
+ search.value = '';
+ statusFilter.value = 'all';
+ await loadUnits(true);
+};
+
// Lifecycle
onMounted(async () => {
- await unitStore.fetchUnits();
+ await loadUnits();
});
@@ -169,6 +238,42 @@ onMounted(async () => {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{
();
const formData = ref({
name: '',
abbreviation: '',
- code_sat: 1,
- is_active: 1
+ code_sat: null,
+ is_active: true
});
// Estado interno del switch (boolean para el UI)
const isActiveSwitch = ref(true);
+const loading = ref(false);
+const errors = ref>({});
// SAT Units
const satUnits = ref([]);
@@ -58,7 +60,7 @@ const dialogTitle = computed(() =>
);
const isFormValid = computed(() => {
- return !!(formData.value.name && formData.value.abbreviation);
+ return !!formData.value.name?.trim();
});
const emptyMessage = computed(() => {
@@ -99,7 +101,7 @@ const loadSatUnits = async (search: string) => {
};
// Debounced search
-const handleSearchChange = (event: any) => {
+const handleSearchChange = (event: { value?: string }) => {
const query = event.value || '';
searchQuery.value = query;
@@ -120,9 +122,11 @@ const resetForm = () => {
name: '',
abbreviation: '',
code_sat: null,
- is_active: 1
+ is_active: true
};
isActiveSwitch.value = true;
+ errors.value = {};
+ loading.value = false;
};
// Watch para actualizar el formulario cuando cambie la unidad
@@ -134,7 +138,7 @@ watch(() => props.unit, (newUnit) => {
code_sat: newUnit.code_sat,
is_active: newUnit.is_active
};
- isActiveSwitch.value = newUnit.is_active === 1;
+ isActiveSwitch.value = newUnit.is_active;
// Precargar la unidad SAT actual en el dropdown
if (newUnit.sat_unit) {
@@ -152,13 +156,57 @@ const handleClose = () => {
resetForm();
};
-const handleSave = () => {
- // Convertir el switch boolean a number para el backend
- formData.value.is_active = isActiveSwitch.value ? 1 : 0;
-
- emit('save', { ...formData.value });
- handleClose();
+const validateForm = (): boolean => {
+ errors.value = {};
+
+ if (!formData.value.name?.trim()) {
+ errors.value.name = 'El nombre es obligatorio';
+ } else if (formData.value.name.trim().length > 50) {
+ errors.value.name = 'El nombre no puede exceder 50 caracteres';
+ }
+
+ if (formData.value.abbreviation && formData.value.abbreviation.trim().length > 10) {
+ errors.value.abbreviation = 'La abreviatura no puede exceder 10 caracteres';
+ }
+
+ return Object.keys(errors.value).length === 0;
};
+
+const handleSave = () => {
+ if (!validateForm()) {
+ return;
+ }
+
+ loading.value = true;
+ formData.value.is_active = isActiveSwitch.value;
+
+ emit('save', {
+ ...formData.value,
+ name: formData.value.name.trim(),
+ abbreviation: formData.value.abbreviation?.trim() || undefined,
+ });
+};
+
+const setValidationErrors = (backendErrors: Record) => {
+ loading.value = false;
+ errors.value = {};
+
+ Object.keys(backendErrors).forEach((key) => {
+ const firstError = backendErrors[key]?.[0];
+ if (firstError) {
+ errors.value[key] = firstError;
+ }
+ });
+};
+
+const resetSubmitting = () => {
+ loading.value = false;
+};
+
+defineExpose({
+ setValidationErrors,
+ resetSubmitting,
+});
@@ -183,7 +231,9 @@ const handleSave = () => {
class="w-full"
placeholder="Ej: PIEZA, KILOGRAMO, METRO"
:required="true"
+ :class="{ 'p-invalid': errors.name }"
/>
+ {{ errors.name }}
@@ -196,8 +246,9 @@ const handleSave = () => {
v-model="formData.abbreviation"
class="w-full"
placeholder="Ej: PZA, kg, m"
- :required="true"
+ :class="{ 'p-invalid': errors.abbreviation }"
/>
+ {{ errors.abbreviation }}
@@ -216,10 +267,12 @@ const handleSave = () => {
class="w-full"
:filter="true"
filterPlaceholder="Buscar unidad SAT"
- :showClear="false"
+ :showClear="true"
@filter="handleSearchChange"
:emptyFilterMessage="emptyMessage"
+ :class="{ 'p-invalid': errors.code_sat }"
/>
+ {{ errors.code_sat }}
Unidad del catálogo SAT
@@ -253,6 +306,7 @@ const handleSave = () => {
diff --git a/src/modules/catalog/services/sat-units.services.ts b/src/modules/catalog/services/sat-units.services.ts
index 8e278e3..351d5d2 100644
--- a/src/modules/catalog/services/sat-units.services.ts
+++ b/src/modules/catalog/services/sat-units.services.ts
@@ -11,7 +11,14 @@ export const satUnitsService = {
* Get all SAT units with search filter
*/
async getSatUnits(search: string = ''): Promise {
- const response = await api.get(`/api/sat/units?search=${search}`);
- return response.data;
+ try {
+ const response = await api.get('/api/sat/units', {
+ params: { search },
+ });
+ return response.data;
+ } catch (error) {
+ console.error('Error al obtener unidades SAT:', error);
+ throw error;
+ }
}
};
diff --git a/src/modules/catalog/services/unit-measure.mapper.ts b/src/modules/catalog/services/unit-measure.mapper.ts
new file mode 100644
index 0000000..97b0a32
--- /dev/null
+++ b/src/modules/catalog/services/unit-measure.mapper.ts
@@ -0,0 +1,40 @@
+import type {
+ CreateUnitOfMeasureData,
+ UnitOfMeasure,
+ UnitOfMeasureApi,
+ UpdateUnitOfMeasureData,
+} from '../types/unit-measure.interfaces';
+
+const toBoolean = (value: boolean | number | undefined): boolean => {
+ if (typeof value === 'boolean') {
+ return value;
+ }
+
+ return value === 1;
+};
+
+export const mapUnitFromApi = (apiUnit: UnitOfMeasureApi): UnitOfMeasure => ({
+ id: apiUnit.id,
+ name: apiUnit.name,
+ abbreviation: apiUnit.abbreviation,
+ is_active: toBoolean(apiUnit.is_active),
+ created_at: apiUnit.created_at,
+ updated_at: apiUnit.updated_at,
+ deleted_at: apiUnit.deleted_at,
+ code_sat: apiUnit.code_sat,
+ sat_unit: apiUnit.sat_unit,
+});
+
+export const mapCreatePayload = (data: CreateUnitOfMeasureData): CreateUnitOfMeasureData => ({
+ name: data.name.trim(),
+ abbreviation: data.abbreviation?.trim() || undefined,
+ code_sat: data.code_sat ?? null,
+ is_active: data.is_active ?? true,
+});
+
+export const mapUpdatePayload = (data: UpdateUnitOfMeasureData): UpdateUnitOfMeasureData => ({
+ name: data.name?.trim(),
+ abbreviation: data.abbreviation?.trim() || undefined,
+ code_sat: data.code_sat ?? null,
+ is_active: data.is_active,
+});
diff --git a/src/modules/catalog/services/unit-measure.services.ts b/src/modules/catalog/services/unit-measure.services.ts
index 67c5cea..27ee36a 100644
--- a/src/modules/catalog/services/unit-measure.services.ts
+++ b/src/modules/catalog/services/unit-measure.services.ts
@@ -1,52 +1,124 @@
import api from '../../../services/api';
import type {
+ UnitOfMeasureApi,
+ UnitOfMeasurePaginatedApiResponse,
+ UnitOfMeasureUnpaginatedApiResponse,
UnitOfMeasurePaginatedResponse,
UnitOfMeasureUnpaginatedResponse,
CreateUnitOfMeasureData,
UpdateUnitOfMeasureData,
SingleUnitOfMeasureResponse,
- UnitOfMeasureResponseById
+ UnitOfMeasureResponseById,
+ UnitOfMeasureQueryParams
} from '../types/unit-measure.interfaces';
+import { mapCreatePayload, mapUnitFromApi, mapUpdatePayload } from './unit-measure.mapper';
+
+const mapPaginatedResponse = (
+ response: UnitOfMeasurePaginatedApiResponse
+): UnitOfMeasurePaginatedResponse => ({
+ ...response,
+ data: response.data.map(mapUnitFromApi),
+});
+
+const mapUnpaginatedResponse = (
+ response: UnitOfMeasureUnpaginatedApiResponse
+): UnitOfMeasureUnpaginatedResponse => ({
+ data: response.data.map(mapUnitFromApi),
+});
+
+const mapSingleResponse = (response: { message: string; data: UnitOfMeasureApi }): SingleUnitOfMeasureResponse => ({
+ message: response.message,
+ data: mapUnitFromApi(response.data),
+});
export const unitOfMeasureService = {
/**
* Get all units of measure with optional pagination and search
*/
- async getUnits(paginate: boolean = true, search: string = ''): Promise {
- const response = await api.get(`/api/catalogs/units-of-measure?paginate=${paginate}&search=${search}`);
- return response.data;
+ async getUnits(params: UnitOfMeasureQueryParams = {}): Promise {
+ try {
+ const {
+ search = '',
+ is_active,
+ paginate = true,
+ per_page,
+ page,
+ } = params;
+
+ const response = await api.get('/api/catalogs/units-of-measure', {
+ params: {
+ search,
+ is_active,
+ paginate,
+ per_page,
+ page,
+ },
+ });
+
+ if ('current_page' in response.data) {
+ return mapPaginatedResponse(response.data as UnitOfMeasurePaginatedApiResponse);
+ }
+
+ return mapUnpaginatedResponse(response.data as UnitOfMeasureUnpaginatedApiResponse);
+ } catch (error) {
+ console.error('Error al obtener unidades de medida:', error);
+ throw error;
+ }
},
/**
* Get a single unit of measure by ID
*/
async getUnitById(id: number): Promise {
- const response = await api.get(`/api/catalogs/units-of-measure/${id}`);
- return response.data;
+ try {
+ const response = await api.get(`/api/catalogs/units-of-measure/${id}`);
+ return {
+ data: mapUnitFromApi((response.data as { data: UnitOfMeasureApi }).data),
+ };
+ } catch (error) {
+ console.error(`Error al obtener unidad de medida con id ${id}:`, error);
+ throw error;
+ }
},
/**
* Create a new unit of measure
*/
async createUnit(data: CreateUnitOfMeasureData): Promise {
- const response = await api.post(`/api/catalogs/units-of-measure`, data);
- console.log('Create Unit response:', response);
- return response.data;
+ try {
+ const payload = mapCreatePayload(data);
+ const response = await api.post('/api/catalogs/units-of-measure', payload);
+ return mapSingleResponse(response.data as { message: string; data: UnitOfMeasureApi });
+ } catch (error) {
+ console.error('Error al crear unidad de medida:', error);
+ throw error;
+ }
},
/**
* Update an existing unit of measure
*/
async updateUnit(id: number, data: UpdateUnitOfMeasureData): Promise {
- const response = await api.put(`/api/catalogs/units-of-measure/${id}`, data);
- return response.data;
+ try {
+ const payload = mapUpdatePayload(data);
+ const response = await api.put(`/api/catalogs/units-of-measure/${id}`, payload);
+ return mapSingleResponse(response.data as { message: string; data: UnitOfMeasureApi });
+ } catch (error) {
+ console.error(`Error al actualizar unidad de medida con id ${id}:`, error);
+ throw error;
+ }
},
/**
* Delete a unit of measure
*/
async deleteUnit(id: number): Promise {
- await api.delete(`/api/catalogs/units-of-measure/${id}`);
+ try {
+ await api.delete(`/api/catalogs/units-of-measure/${id}`);
+ } catch (error) {
+ console.error(`Error al eliminar unidad de medida con id ${id}:`, error);
+ throw error;
+ }
}
};
diff --git a/src/modules/catalog/stores/unitOfMeasureStore.ts b/src/modules/catalog/stores/unitOfMeasureStore.ts
index 0ff506c..58eb910 100644
--- a/src/modules/catalog/stores/unitOfMeasureStore.ts
+++ b/src/modules/catalog/stores/unitOfMeasureStore.ts
@@ -4,23 +4,40 @@ import { unitOfMeasureService } from '../services/unit-measure.services';
import type {
UnitOfMeasure,
CreateUnitOfMeasureData,
- UpdateUnitOfMeasureData
+ UpdateUnitOfMeasureData,
+ UnitOfMeasureQueryParams,
+ UnitOfMeasurePaginatedResponse,
+ UnitOfMeasureUnpaginatedResponse,
} from '../types/unit-measure.interfaces';
+interface FetchUnitsOptions extends UnitOfMeasureQueryParams {
+ force?: boolean;
+}
+
+const isPaginatedResponse = (
+ response: UnitOfMeasurePaginatedResponse | UnitOfMeasureUnpaginatedResponse
+): response is UnitOfMeasurePaginatedResponse => 'current_page' in response;
+
export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
// State
const units = ref([]);
const loading = ref(false);
const loaded = ref(false);
const error = ref(null);
+ const lastFetchOptions = ref({
+ paginate: true,
+ search: '',
+ page: 1,
+ per_page: 10,
+ });
// Getters
const activeUnits = computed(() =>
- units.value.filter(unit => unit.is_active === 1)
+ units.value.filter((unit) => unit.is_active)
);
const inactiveUnits = computed(() =>
- units.value.filter(unit => unit.is_active === 0)
+ units.value.filter((unit) => !unit.is_active)
);
const unitCount = computed(() => units.value.length);
@@ -35,31 +52,35 @@ export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
});
// Actions
- const fetchUnits = async (force = false, paginate = true, search = '') => {
- // Si ya están cargados y no se fuerza la recarga, no hacer nada
- if (loaded.value && !force) {
- console.log('Units of measure already loaded from store');
+ const fetchUnits = async (options: FetchUnitsOptions = {}) => {
+ const {
+ force = false,
+ ...queryOptions
+ } = options;
+
+ if (loaded.value && !force && units.value.length > 0) {
return;
}
+ const normalizedOptions: UnitOfMeasureQueryParams = {
+ ...lastFetchOptions.value,
+ ...queryOptions,
+ };
+
try {
loading.value = true;
error.value = null;
- const response = await unitOfMeasureService.getUnits(paginate, search);
+ const response = await unitOfMeasureService.getUnits(normalizedOptions);
- // Manejar respuesta paginada o no paginada
- if ('current_page' in response) {
- // Respuesta paginada
+ if (isPaginatedResponse(response)) {
units.value = response.data;
} else {
- // Respuesta no paginada
units.value = response.data;
}
loaded.value = true;
-
- console.log('Units of measure loaded into store:', units.value.length);
+ lastFetchOptions.value = normalizedOptions;
} catch (err) {
error.value = err instanceof Error ? err.message : 'Error loading units of measure';
console.error('Error in unit of measure store:', err);
@@ -69,8 +90,12 @@ export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
}
};
- const refreshUnits = () => {
- return fetchUnits(true);
+ const refreshUnits = (overrides: UnitOfMeasureQueryParams = {}) => {
+ return fetchUnits({
+ force: true,
+ ...lastFetchOptions.value,
+ ...overrides,
+ });
};
const createUnit = async (data: CreateUnitOfMeasureData) => {
@@ -82,8 +107,6 @@ export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
// Refrescar la lista después de crear
await refreshUnits();
-
- console.log('Unit of measure created successfully');
} catch (err) {
error.value = err instanceof Error ? err.message : 'Error creating unit of measure';
console.error('Error creating unit of measure:', err);
@@ -102,8 +125,6 @@ export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
// Refrescar la lista después de actualizar
await refreshUnits();
-
- console.log('Unit of measure updated successfully');
} catch (err) {
error.value = err instanceof Error ? err.message : 'Error updating unit of measure';
console.error('Error updating unit of measure:', err);
@@ -122,8 +143,6 @@ export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
// Refrescar la lista después de eliminar
await refreshUnits();
-
- console.log('Unit of measure deleted successfully');
} catch (err) {
error.value = err instanceof Error ? err.message : 'Error deleting unit of measure';
console.error('Error deleting unit of measure:', err);
@@ -145,6 +164,7 @@ export const useUnitOfMeasureStore = defineStore('unitOfMeasure', () => {
loading,
loaded,
error,
+ lastFetchOptions,
// Getters
activeUnits,
inactiveUnits,
diff --git a/src/modules/catalog/types/unit-measure.interfaces.ts b/src/modules/catalog/types/unit-measure.interfaces.ts
index 0ab0ff9..673934c 100644
--- a/src/modules/catalog/types/unit-measure.interfaces.ts
+++ b/src/modules/catalog/types/unit-measure.interfaces.ts
@@ -8,32 +8,50 @@ export interface SatUnit {
updated_at: string;
}
-// Interface para la Unidad de Medida
+export interface UnitOfMeasureApi {
+ id: number;
+ name: string;
+ abbreviation: string;
+ is_active: boolean | number;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+ code_sat: number | null;
+ sat_unit: SatUnit | null;
+}
+
export interface UnitOfMeasure {
id: number;
name: string;
abbreviation: string;
- is_active: number;
+ is_active: boolean;
created_at: string;
updated_at: string;
deleted_at: string | null;
- code_sat: number;
- sat_unit: SatUnit;
+ code_sat: number | null;
+ sat_unit: SatUnit | null;
}
-// Interfaces para crear y actualizar unidades de medida
export interface CreateUnitOfMeasureData {
name: string;
- abbreviation: string;
- code_sat: number | null;
- is_active: number;
+ abbreviation?: string;
+ code_sat?: number | null;
+ is_active?: boolean;
}
export interface UpdateUnitOfMeasureData {
name?: string;
abbreviation?: string;
code_sat?: number | null;
- is_active?: number;
+ is_active?: boolean;
+}
+
+export interface UnitOfMeasureQueryParams {
+ search?: string;
+ is_active?: boolean;
+ paginate?: boolean;
+ per_page?: number;
+ page?: number;
}
// Interface para los links de paginación
@@ -65,10 +83,12 @@ export interface UnpaginatedResponse {
data: T[];
}
-// Tipo específico para la respuesta paginada de Unidades de Medida
+export type UnitOfMeasurePaginatedApiResponse = PaginatedResponse;
+
+export type UnitOfMeasureUnpaginatedApiResponse = UnpaginatedResponse;
+
export type UnitOfMeasurePaginatedResponse = PaginatedResponse;
-// Tipo específico para la respuesta no paginada de Unidades de Medida
export type UnitOfMeasureUnpaginatedResponse = UnpaginatedResponse;
export type UnitOfMeasureResponseById = {
@@ -78,4 +98,4 @@ export type UnitOfMeasureResponseById = {
export interface SingleUnitOfMeasureResponse {
message: string;
data: UnitOfMeasure;
-}
\ No newline at end of file
+}
diff --git a/src/services/api.ts b/src/services/api.ts
index 97fe9d6..40cfcc6 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -1,5 +1,6 @@
import axios from 'axios';
import type { InternalAxiosRequestConfig } from 'axios';
+import { AUTH_TOKEN_KEY, clearStoredAuthSession } from '../modules/auth/utils/authStorage';
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000',
@@ -12,7 +13,7 @@ const api = axios.create({
// Interceptor para agregar el Bearer Token a cada petición
api.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
- const token = localStorage.getItem('auth_token'); // Ajusta según dónde guardes el token
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (token && config.headers) {
config.headers['Authorization'] = `Bearer ${token}`;
}
@@ -28,18 +29,16 @@ api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response) {
- // El servidor respondió con un código de estado fuera del rango 2xx
- console.error(error.response.data);
-
- // Manejar error 401 (no autorizado) - redirigir al login
if (error.response.status === 401) {
- localStorage.removeItem('auth_token');
- localStorage.removeItem('auth_user');
- window.location.href = '/login';
+ clearStoredAuthSession();
+
+ if (typeof window !== 'undefined') {
+ window.dispatchEvent(new CustomEvent('auth:unauthorized'));
+ }
}
}
return Promise.reject(error);
}
);
-export default api;
\ No newline at end of file
+export default api;