Start integrating the onboarding flow with backend 6

This commit is contained in:
Urtzi Alfaro
2025-09-05 17:49:48 +02:00
parent 236c3a32ae
commit 069954981a
131 changed files with 5217 additions and 22838 deletions

View File

@@ -0,0 +1,316 @@
/**
* 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<UseQueryOptions<TenantResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantResponse, ApiError>({
queryKey: tenantKeys.detail(tenantId),
queryFn: () => tenantService.getTenant(tenantId),
enabled: !!tenantId,
staleTime: 5 * 60 * 1000, // 5 minutes
...options,
});
};
export const useTenantBySubdomain = (
subdomain: string,
options?: Omit<UseQueryOptions<TenantResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantResponse, ApiError>({
queryKey: tenantKeys.subdomain(subdomain),
queryFn: () => tenantService.getTenantBySubdomain(subdomain),
enabled: !!subdomain,
staleTime: 5 * 60 * 1000, // 5 minutes
...options,
});
};
export const useUserTenants = (
userId: string,
options?: Omit<UseQueryOptions<TenantResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantResponse[], ApiError>({
queryKey: tenantKeys.userTenants(userId),
queryFn: () => tenantService.getUserTenants(userId),
enabled: !!userId,
staleTime: 2 * 60 * 1000, // 2 minutes
...options,
});
};
export const useUserOwnedTenants = (
userId: string,
options?: Omit<UseQueryOptions<TenantResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantResponse[], ApiError>({
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<UseQueryOptions<TenantAccessResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantAccessResponse, ApiError>({
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<UseQueryOptions<TenantResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantResponse[], ApiError>({
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<UseQueryOptions<TenantResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantResponse[], ApiError>({
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<UseQueryOptions<TenantMemberResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantMemberResponse[], ApiError>({
queryKey: tenantKeys.members(tenantId),
queryFn: () => tenantService.getTeamMembers(tenantId, activeOnly),
enabled: !!tenantId,
staleTime: 2 * 60 * 1000, // 2 minutes
...options,
});
};
export const useTenantStatistics = (
options?: Omit<UseQueryOptions<TenantStatistics, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<TenantStatistics, ApiError>({
queryKey: tenantKeys.statistics(),
queryFn: () => tenantService.getTenantStatistics(),
staleTime: 10 * 60 * 1000, // 10 minutes
...options,
});
};
// Mutations
export const useRegisterBakery = (
options?: UseMutationOptions<TenantResponse, ApiError, BakeryRegistration>
) => {
const queryClient = useQueryClient();
return useMutation<TenantResponse, ApiError, BakeryRegistration>({
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<TenantResponse, ApiError, { tenantId: string; updateData: TenantUpdate }>
) => {
const queryClient = useQueryClient();
return useMutation<TenantResponse, ApiError, { tenantId: string; updateData: TenantUpdate }>({
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,
});
};