/** * Tenant React Query hooks */ import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query'; import { tenantService } from '../services/tenant'; import { BakeryRegistration, TenantResponse, TenantAccessResponse, TenantUpdate, TenantMemberResponse, TenantStatistics, TenantSearchParams, TenantNearbyParams, } from '../types/tenant'; import { ApiError } from '../client'; // Query Keys export const tenantKeys = { all: ['tenant'] as const, lists: () => [...tenantKeys.all, 'list'] as const, list: (filters: string) => [...tenantKeys.lists(), { filters }] as const, details: () => [...tenantKeys.all, 'detail'] as const, detail: (id: string) => [...tenantKeys.details(), id] as const, subdomain: (subdomain: string) => [...tenantKeys.all, 'subdomain', subdomain] as const, userTenants: (userId: string) => [...tenantKeys.all, 'user', userId] as const, userOwnedTenants: (userId: string) => [...tenantKeys.all, 'user-owned', userId] as const, access: (tenantId: string, userId: string) => [...tenantKeys.all, 'access', tenantId, userId] as const, search: (params: TenantSearchParams) => [...tenantKeys.lists(), 'search', params] as const, nearby: (params: TenantNearbyParams) => [...tenantKeys.lists(), 'nearby', params] as const, members: (tenantId: string) => [...tenantKeys.all, 'members', tenantId] as const, statistics: () => [...tenantKeys.all, 'statistics'] as const, } as const; // Queries export const useTenant = ( tenantId: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.detail(tenantId), queryFn: () => tenantService.getTenant(tenantId), enabled: !!tenantId, staleTime: 5 * 60 * 1000, // 5 minutes ...options, }); }; export const useTenantBySubdomain = ( subdomain: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.subdomain(subdomain), queryFn: () => tenantService.getTenantBySubdomain(subdomain), enabled: !!subdomain, staleTime: 5 * 60 * 1000, // 5 minutes ...options, }); }; export const useUserTenants = ( userId: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.userTenants(userId), queryFn: () => tenantService.getUserTenants(userId), enabled: !!userId, staleTime: 2 * 60 * 1000, // 2 minutes ...options, }); }; export const useUserOwnedTenants = ( userId: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.userOwnedTenants(userId), queryFn: () => tenantService.getUserOwnedTenants(userId), enabled: !!userId, staleTime: 2 * 60 * 1000, // 2 minutes ...options, }); }; export const useTenantAccess = ( tenantId: string, userId: string, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.access(tenantId, userId), queryFn: () => tenantService.verifyTenantAccess(tenantId, userId), enabled: !!tenantId && !!userId, staleTime: 5 * 60 * 1000, // 5 minutes ...options, }); }; export const useSearchTenants = ( params: TenantSearchParams, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.search(params), queryFn: () => tenantService.searchTenants(params), enabled: !!params.search_term, staleTime: 30 * 1000, // 30 seconds for search results ...options, }); }; export const useNearbyTenants = ( params: TenantNearbyParams, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.nearby(params), queryFn: () => tenantService.getNearbyTenants(params), enabled: !!(params.latitude && params.longitude), staleTime: 5 * 60 * 1000, // 5 minutes ...options, }); }; export const useTeamMembers = ( tenantId: string, activeOnly: boolean = true, options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.members(tenantId), queryFn: () => tenantService.getTeamMembers(tenantId, activeOnly), enabled: !!tenantId, staleTime: 2 * 60 * 1000, // 2 minutes ...options, }); }; export const useTenantStatistics = ( options?: Omit, 'queryKey' | 'queryFn'> ) => { return useQuery({ queryKey: tenantKeys.statistics(), queryFn: () => tenantService.getTenantStatistics(), staleTime: 10 * 60 * 1000, // 10 minutes ...options, }); }; // Mutations export const useRegisterBakery = ( options?: UseMutationOptions ) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (bakeryData: BakeryRegistration) => tenantService.registerBakery(bakeryData), onSuccess: (data, variables) => { // Invalidate user tenants to include the new one queryClient.invalidateQueries({ queryKey: tenantKeys.userTenants('') }); queryClient.invalidateQueries({ queryKey: tenantKeys.userOwnedTenants('') }); // Set the tenant data in cache queryClient.setQueryData(tenantKeys.detail(data.id), data); }, ...options, }); }; export const useUpdateTenant = ( options?: UseMutationOptions ) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ tenantId, updateData }) => tenantService.updateTenant(tenantId, updateData), onSuccess: (data, { tenantId }) => { // Update the tenant cache queryClient.setQueryData(tenantKeys.detail(tenantId), data); // Invalidate related queries queryClient.invalidateQueries({ queryKey: tenantKeys.userTenants('') }); queryClient.invalidateQueries({ queryKey: tenantKeys.userOwnedTenants('') }); }, ...options, }); }; export const useDeactivateTenant = ( options?: UseMutationOptions<{ success: boolean; message: string }, ApiError, string> ) => { const queryClient = useQueryClient(); return useMutation<{ success: boolean; message: string }, ApiError, string>({ mutationFn: (tenantId: string) => tenantService.deactivateTenant(tenantId), onSuccess: (data, tenantId) => { // Invalidate tenant-related queries queryClient.invalidateQueries({ queryKey: tenantKeys.detail(tenantId) }); queryClient.invalidateQueries({ queryKey: tenantKeys.userTenants('') }); queryClient.invalidateQueries({ queryKey: tenantKeys.userOwnedTenants('') }); }, ...options, }); }; export const useActivateTenant = ( options?: UseMutationOptions<{ success: boolean; message: string }, ApiError, string> ) => { const queryClient = useQueryClient(); return useMutation<{ success: boolean; message: string }, ApiError, string>({ mutationFn: (tenantId: string) => tenantService.activateTenant(tenantId), onSuccess: (data, tenantId) => { // Invalidate tenant-related queries queryClient.invalidateQueries({ queryKey: tenantKeys.detail(tenantId) }); queryClient.invalidateQueries({ queryKey: tenantKeys.userTenants('') }); queryClient.invalidateQueries({ queryKey: tenantKeys.userOwnedTenants('') }); }, ...options, }); }; export const useUpdateModelStatus = ( options?: UseMutationOptions< TenantResponse, ApiError, { tenantId: string; modelTrained: boolean; lastTrainingDate?: string } > ) => { const queryClient = useQueryClient(); return useMutation< TenantResponse, ApiError, { tenantId: string; modelTrained: boolean; lastTrainingDate?: string } >({ mutationFn: ({ tenantId, modelTrained, lastTrainingDate }) => tenantService.updateModelStatus(tenantId, modelTrained, lastTrainingDate), onSuccess: (data, { tenantId }) => { // Update the tenant cache queryClient.setQueryData(tenantKeys.detail(tenantId), data); }, ...options, }); }; export const useAddTeamMember = ( options?: UseMutationOptions< TenantMemberResponse, ApiError, { tenantId: string; userId: string; role: string } > ) => { const queryClient = useQueryClient(); return useMutation< TenantMemberResponse, ApiError, { tenantId: string; userId: string; role: string } >({ mutationFn: ({ tenantId, userId, role }) => tenantService.addTeamMember(tenantId, userId, role), onSuccess: (data, { tenantId }) => { // Invalidate team members query queryClient.invalidateQueries({ queryKey: tenantKeys.members(tenantId) }); }, ...options, }); }; export const useUpdateMemberRole = ( options?: UseMutationOptions< TenantMemberResponse, ApiError, { tenantId: string; memberUserId: string; newRole: string } > ) => { const queryClient = useQueryClient(); return useMutation< TenantMemberResponse, ApiError, { tenantId: string; memberUserId: string; newRole: string } >({ mutationFn: ({ tenantId, memberUserId, newRole }) => tenantService.updateMemberRole(tenantId, memberUserId, newRole), onSuccess: (data, { tenantId }) => { // Invalidate team members query queryClient.invalidateQueries({ queryKey: tenantKeys.members(tenantId) }); }, ...options, }); }; export const useRemoveTeamMember = ( options?: UseMutationOptions< { success: boolean; message: string }, ApiError, { tenantId: string; memberUserId: string } > ) => { const queryClient = useQueryClient(); return useMutation< { success: boolean; message: string }, ApiError, { tenantId: string; memberUserId: string } >({ mutationFn: ({ tenantId, memberUserId }) => tenantService.removeTeamMember(tenantId, memberUserId), onSuccess: (data, { tenantId }) => { // Invalidate team members query queryClient.invalidateQueries({ queryKey: tenantKeys.members(tenantId) }); }, ...options, }); };