## Products Feature (24 files) - Convert hooks from @tanstack/react-query to useState/useEffect - Fix page components to use new hook structure - Add missing API files and components ## Warehouses Feature (20 files) - Complete feature using correct hook pattern ## Partners Hooks (3 files) - Convert usePartnerAddresses to useState/useEffect - Convert usePartnerContacts to useState/useEffect - Convert usePartnerBankAccounts to useState/useEffect ## Companies Hooks (2 files) - Convert useCompanyBranches to useState/useEffect - Convert useCompanySettings to useState/useEffect Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
170 lines
4.3 KiB
TypeScript
170 lines
4.3 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react';
|
|
import { zonesApi } from '../api';
|
|
import type {
|
|
WarehouseZone,
|
|
CreateZoneDto,
|
|
UpdateZoneDto,
|
|
} from '../types';
|
|
|
|
// ==================== Zones List Hook ====================
|
|
|
|
export interface UseZonesOptions {
|
|
autoFetch?: boolean;
|
|
}
|
|
|
|
export function useZones(warehouseId: string | null, options: UseZonesOptions = {}) {
|
|
const { autoFetch = true } = options;
|
|
const [zones, setZones] = useState<WarehouseZone[]>([]);
|
|
const [total, setTotal] = useState(0);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const fetchZones = useCallback(async () => {
|
|
if (!warehouseId) {
|
|
setZones([]);
|
|
setTotal(0);
|
|
return;
|
|
}
|
|
|
|
setIsLoading(true);
|
|
setError(null);
|
|
try {
|
|
const data = await zonesApi.getByWarehouse(warehouseId);
|
|
setZones(data);
|
|
setTotal(data.length);
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Error al cargar zonas');
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [warehouseId]);
|
|
|
|
useEffect(() => {
|
|
if (autoFetch) {
|
|
fetchZones();
|
|
}
|
|
}, [fetchZones, autoFetch]);
|
|
|
|
const createZone = useCallback(async (data: CreateZoneDto) => {
|
|
if (!warehouseId) {
|
|
throw new Error('Se requiere un almacen para crear una zona');
|
|
}
|
|
setIsLoading(true);
|
|
setError(null);
|
|
try {
|
|
const newZone = await zonesApi.create(warehouseId, data);
|
|
await fetchZones();
|
|
return newZone;
|
|
} catch (err) {
|
|
const errorMsg = err instanceof Error ? err.message : 'Error al crear zona';
|
|
setError(errorMsg);
|
|
throw err;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [warehouseId, fetchZones]);
|
|
|
|
const updateZone = useCallback(async (zoneId: string, data: UpdateZoneDto) => {
|
|
if (!warehouseId) {
|
|
throw new Error('Se requiere un almacen para actualizar una zona');
|
|
}
|
|
setIsLoading(true);
|
|
setError(null);
|
|
try {
|
|
const updated = await zonesApi.update(warehouseId, zoneId, data);
|
|
await fetchZones();
|
|
return updated;
|
|
} catch (err) {
|
|
const errorMsg = err instanceof Error ? err.message : 'Error al actualizar zona';
|
|
setError(errorMsg);
|
|
throw err;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [warehouseId, fetchZones]);
|
|
|
|
const deleteZone = useCallback(async (zoneId: string) => {
|
|
if (!warehouseId) {
|
|
throw new Error('Se requiere un almacen para eliminar una zona');
|
|
}
|
|
setIsLoading(true);
|
|
setError(null);
|
|
try {
|
|
await zonesApi.delete(warehouseId, zoneId);
|
|
await fetchZones();
|
|
} catch (err) {
|
|
const errorMsg = err instanceof Error ? err.message : 'Error al eliminar zona';
|
|
setError(errorMsg);
|
|
throw err;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [warehouseId, fetchZones]);
|
|
|
|
return {
|
|
zones,
|
|
total,
|
|
isLoading,
|
|
error,
|
|
refresh: fetchZones,
|
|
createZone,
|
|
updateZone,
|
|
deleteZone,
|
|
};
|
|
}
|
|
|
|
// ==================== Single Zone Hook ====================
|
|
|
|
export function useZone(warehouseId: string | null, zoneId: string | null) {
|
|
const [zone, setZone] = useState<WarehouseZone | null>(null);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const fetchZone = useCallback(async () => {
|
|
if (!warehouseId || !zoneId) {
|
|
setZone(null);
|
|
return;
|
|
}
|
|
|
|
setIsLoading(true);
|
|
setError(null);
|
|
try {
|
|
const data = await zonesApi.getById(warehouseId, zoneId);
|
|
setZone(data);
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Error al cargar zona');
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [warehouseId, zoneId]);
|
|
|
|
useEffect(() => {
|
|
fetchZone();
|
|
}, [fetchZone]);
|
|
|
|
const updateZone = useCallback(async (data: UpdateZoneDto) => {
|
|
if (!warehouseId || !zoneId) return;
|
|
setIsLoading(true);
|
|
setError(null);
|
|
try {
|
|
const updated = await zonesApi.update(warehouseId, zoneId, data);
|
|
setZone(updated);
|
|
return updated;
|
|
} catch (err) {
|
|
const errorMsg = err instanceof Error ? err.message : 'Error al actualizar zona';
|
|
setError(errorMsg);
|
|
throw err;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [warehouseId, zoneId]);
|
|
|
|
return {
|
|
zone,
|
|
isLoading,
|
|
error,
|
|
refresh: fetchZone,
|
|
updateZone,
|
|
};
|
|
}
|