import { useQuery, useMutation, useQueryClient, UseQueryOptions } from '@tanstack/react-query'; import { geolocationApi } from '../api/geolocation.api'; import type { Geolocation, GeolocationFilters, GeolocationsResponse, CreateGeolocationDto, UpdateGeolocationDto, GeolocationQuery, } from '../types/api.types'; // Query Keys export const geolocationKeys = { all: ['geolocation'] as const, lists: () => [...geolocationKeys.all, 'list'] as const, list: (filters: GeolocationFilters) => [...geolocationKeys.lists(), filters] as const, details: () => [...geolocationKeys.all, 'detail'] as const, detail: (id: string) => [...geolocationKeys.details(), id] as const, countries: () => [...geolocationKeys.all, 'countries'] as const, regions: (countryId: string) => [...geolocationKeys.all, 'regions', countryId] as const, cities: (regionId: string) => [...geolocationKeys.all, 'cities', regionId] as const, }; // Queries export const useGeolocations = ( filters?: GeolocationFilters, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: geolocationKeys.list(filters || {}), queryFn: () => geolocationApi.getAll(filters), ...options, }); }; export const useGeolocation = ( id: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: geolocationKeys.detail(id), queryFn: () => geolocationApi.getById(id), enabled: !!id, ...options, }); }; export const useCountries = ( options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: geolocationKeys.countries(), queryFn: () => geolocationApi.getCountries(), ...options, }); }; export const useRegions = ( countryId: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: geolocationKeys.regions(countryId), queryFn: () => geolocationApi.getRegions(countryId), enabled: !!countryId, ...options, }); }; export const useCities = ( regionId: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: geolocationKeys.cities(regionId), queryFn: () => geolocationApi.getCities(regionId), enabled: !!regionId, ...options, }); }; export const useGeocode = ( query: GeolocationQuery, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: [...geolocationKeys.all, 'geocode', query], queryFn: () => geolocationApi.geocode(query), enabled: !!(query.address || query.postalCode || query.city || query.country), ...options, }); }; export const useReverseGeocode = ( latitude: number, longitude: number, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: [...geolocationKeys.all, 'reverse', latitude, longitude], queryFn: () => geolocationApi.reverseGeocode(latitude, longitude), enabled: !!(latitude && longitude), ...options, }); }; export const useTimezone = ( latitude: number, longitude: number, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: [...geolocationKeys.all, 'timezone', latitude, longitude], queryFn: () => geolocationApi.getTimezone(latitude, longitude), enabled: !!(latitude && longitude), ...options, }); }; export const useDistance = ( fromLat: number, fromLng: number, toLat: number, toLng: number, unit: 'km' | 'miles' = 'km', options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: [...geolocationKeys.all, 'distance', fromLat, fromLng, toLat, toLng, unit], queryFn: () => geolocationApi.calculateDistance(fromLat, fromLng, toLat, toLng, unit), enabled: !!(fromLat && fromLng && toLat && toLng), ...options, }); }; // Mutations export const useCreateGeolocation = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (data: CreateGeolocationDto) => geolocationApi.create(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: geolocationKeys.lists() }); }, }); }; export const useUpdateGeolocation = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ id, data }: { id: string; data: UpdateGeolocationDto }) => geolocationApi.update(id, data), onSuccess: (_, { id }) => { queryClient.invalidateQueries({ queryKey: geolocationKeys.lists() }); queryClient.invalidateQueries({ queryKey: geolocationKeys.detail(id) }); }, }); }; export const useDeleteGeolocation = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (id: string) => geolocationApi.delete(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: geolocationKeys.lists() }); }, }); }; export const useValidatePostalCode = () => { return useMutation({ mutationFn: ({ postalCode, countryId }: { postalCode: string; countryId?: string }) => geolocationApi.validatePostalCode(postalCode, countryId), }); };