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>
324 lines
9.4 KiB
TypeScript
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);
|
|
}
|