erp-core-frontend-v2/src/features/geolocation/hooks/useGeolocation.ts
Adrian Flores Cortes da2e391b7c [TASK-2026-02-03] fix: Convert remaining hooks from @tanstack/react-query to useState/useEffect
Converts 5 modules to use the project's standard hook pattern:
- dashboard: useDashboard hooks
- geolocation: useGeolocation, useCountries, useRegions, useCities, etc.
- mcp: useMcpServers, useMcpTools, useMcpResources, etc.
- payment-terminals: usePaymentTerminals, usePaymentTerminalTransactions, etc.
- scanning: useScanningSessions, useScanningDevices, etc.

All hooks now use useState/useEffect instead of @tanstack/react-query.
Build passes with 0 TypeScript errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:09:04 -06:00

324 lines
9.4 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react';
import { geolocationApi } from '../api/geolocation.api';
import type {
Geolocation,
GeolocationFilters,
GeolocationsResponse,
CreateGeolocationDto,
UpdateGeolocationDto,
GeolocationQuery,
} from '../../shared/types/api.types';
// Hook para obtener lista de geolocalizaciones con filtros
export function useGeolocations(filters?: GeolocationFilters) {
const [data, setData] = useState<GeolocationsResponse | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetch = useCallback(async () => {
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.getAll(filters);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al obtener geolocalizaciones');
} finally {
setIsLoading(false);
}
}, [
filters?.search,
filters?.page,
filters?.limit,
filters?.sortBy,
filters?.sortOrder,
filters?.countryId,
filters?.regionId,
filters?.cityId,
filters?.postalCode,
]);
useEffect(() => {
fetch();
}, [fetch]);
const create = useCallback(async (createData: CreateGeolocationDto): Promise<Geolocation> => {
const created = await geolocationApi.create(createData);
await fetch();
return created;
}, [fetch]);
const update = useCallback(async (id: string, updateData: UpdateGeolocationDto): Promise<Geolocation> => {
const updated = await geolocationApi.update(id, updateData);
await fetch();
return updated;
}, [fetch]);
const remove = useCallback(async (id: string): Promise<void> => {
await geolocationApi.delete(id);
await fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch, create, update, remove };
}
// Hook para obtener una geolocalización por ID
export function useGeolocation(id: string) {
const [data, setData] = useState<Geolocation | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetch = useCallback(async () => {
if (!id) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.getById(id);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al obtener geolocalización');
} finally {
setIsLoading(false);
}
}, [id]);
useEffect(() => {
fetch();
}, [fetch]);
const update = useCallback(async (updateData: UpdateGeolocationDto): Promise<Geolocation> => {
const updated = await geolocationApi.update(id, updateData);
setData(updated);
return updated;
}, [id]);
const remove = useCallback(async (): Promise<void> => {
await geolocationApi.delete(id);
setData(null);
}, [id]);
return { data, isLoading, error, refresh: fetch, update, remove };
}
// Hook para obtener países
export function useCountries() {
const [data, setData] = useState<Geolocation[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetch = useCallback(async () => {
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.getCountries();
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al obtener países');
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Hook para obtener regiones de un país
export function useRegions(countryId: string) {
const [data, setData] = useState<Geolocation[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetch = useCallback(async () => {
if (!countryId) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.getRegions(countryId);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al obtener regiones');
} finally {
setIsLoading(false);
}
}, [countryId]);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Hook para obtener ciudades de una región
export function useCities(regionId: string) {
const [data, setData] = useState<Geolocation[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetch = useCallback(async () => {
if (!regionId) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.getCities(regionId);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al obtener ciudades');
} finally {
setIsLoading(false);
}
}, [regionId]);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Hook para geocodificación (dirección a coordenadas)
export function useGeocode(query: GeolocationQuery) {
const [data, setData] = useState<Geolocation[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const isEnabled = !!(query.address || query.postalCode || query.city || query.country);
const fetch = useCallback(async () => {
if (!isEnabled) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.geocode(query);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error en geocodificación');
} finally {
setIsLoading(false);
}
}, [query.address, query.postalCode, query.city, query.country, query.limit, isEnabled]);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Hook para geocodificación inversa (coordenadas a dirección)
export function useReverseGeocode(latitude: number, longitude: number) {
const [data, setData] = useState<Geolocation | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const isEnabled = !!(latitude && longitude);
const fetch = useCallback(async () => {
if (!isEnabled) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.reverseGeocode(latitude, longitude);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error en geocodificación inversa');
} finally {
setIsLoading(false);
}
}, [latitude, longitude, isEnabled]);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Hook para obtener zona horaria
export function useTimezone(latitude: number, longitude: number) {
const [data, setData] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const isEnabled = !!(latitude && longitude);
const fetch = useCallback(async () => {
if (!isEnabled) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.getTimezone(latitude, longitude);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al obtener zona horaria');
} finally {
setIsLoading(false);
}
}, [latitude, longitude, isEnabled]);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Hook para calcular distancia entre dos puntos
export function useDistance(
fromLat: number,
fromLng: number,
toLat: number,
toLng: number,
unit: 'km' | 'miles' = 'km'
) {
const [data, setData] = useState<number | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const isEnabled = !!(fromLat && fromLng && toLat && toLng);
const fetch = useCallback(async () => {
if (!isEnabled) return;
setIsLoading(true);
setError(null);
try {
const response = await geolocationApi.calculateDistance(fromLat, fromLng, toLat, toLng, unit);
setData(response);
} catch (err) {
setError(err instanceof Error ? err.message : 'Error al calcular distancia');
} finally {
setIsLoading(false);
}
}, [fromLat, fromLng, toLat, toLng, unit, isEnabled]);
useEffect(() => {
fetch();
}, [fetch]);
return { data, isLoading, error, refresh: fetch };
}
// Función para crear geolocalización (sin hook)
export async function createGeolocation(data: CreateGeolocationDto): Promise<Geolocation> {
return geolocationApi.create(data);
}
// Función para actualizar geolocalización (sin hook)
export async function updateGeolocation(id: string, data: UpdateGeolocationDto): Promise<Geolocation> {
return geolocationApi.update(id, data);
}
// Función para eliminar geolocalización (sin hook)
export async function deleteGeolocation(id: string): Promise<void> {
return geolocationApi.delete(id);
}
// Función para validar código postal (sin hook)
export async function validatePostalCode(postalCode: string, countryId?: string): Promise<boolean> {
return geolocationApi.validatePostalCode(postalCode, countryId);
}