mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- Remove nested git repository from bugulma/frontend/.git - Add all frontend files to main repository tracking - Convert from separate frontend/backend repos to unified monorepo - Preserve all frontend code and development history as tracked files - Eliminate nested repository complexity for simpler development workflow This creates a proper monorepo structure with frontend and backend coexisting in the same repository for easier development and deployment.
136 lines
3.9 KiB
TypeScript
136 lines
3.9 KiB
TypeScript
/**
|
|
* Reusable React Query hook utilities
|
|
* Reduces duplication across API hooks while maintaining type safety
|
|
*
|
|
* Note: These are helper functions, not full factories, to work better with React Query's type system
|
|
*/
|
|
|
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
|
|
/**
|
|
* Creates a mutation hook with automatic cache invalidation
|
|
* Provides consistent invalidation behavior across all mutation hooks
|
|
*/
|
|
export function useInvalidatingMutation<TData, TVariables, TError = Error>(options: {
|
|
mutationFn: (variables: TVariables) => Promise<TData>;
|
|
invalidateKeys: readonly (readonly unknown[])[];
|
|
onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;
|
|
onError?: (error: TError, variables: TVariables) => void | Promise<void>;
|
|
}) {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation<TData, TError, TVariables>({
|
|
mutationFn: options.mutationFn,
|
|
onSuccess: (data, variables) => {
|
|
// Invalidate specified query keys
|
|
options.invalidateKeys.forEach((key) => {
|
|
queryClient.invalidateQueries({ queryKey: key });
|
|
});
|
|
// Call custom onSuccess if provided
|
|
options.onSuccess?.(data, variables);
|
|
},
|
|
onError: options.onError,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Common query options for consistent behavior across hooks
|
|
*/
|
|
export const commonQueryOptions = {
|
|
/**
|
|
* Standard stale time for data that doesn't change often (30 seconds)
|
|
*/
|
|
standardStaleTime: 30 * 1000,
|
|
|
|
/**
|
|
* Standard placeholder data for lists (empty array)
|
|
*/
|
|
emptyListPlaceholder: <T>(): T[] => [] as T[],
|
|
} as const;
|
|
|
|
/**
|
|
* Generic query hook factory for consistent API hook patterns
|
|
* Reduces boilerplate code across API hooks
|
|
*/
|
|
export function createStandardQueryHook<TData>(
|
|
queryKey: readonly unknown[],
|
|
queryFn: () => Promise<TData>,
|
|
options?: {
|
|
enabled?: boolean;
|
|
staleTime?: number;
|
|
placeholderData?: TData;
|
|
}
|
|
) {
|
|
return () =>
|
|
useQuery({
|
|
queryKey,
|
|
queryFn,
|
|
enabled: options?.enabled ?? true,
|
|
staleTime: options?.staleTime ?? commonQueryOptions.standardStaleTime,
|
|
placeholderData: options?.placeholderData,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generic detail query hook factory
|
|
* For fetching individual entities by ID
|
|
*/
|
|
export function createDetailQueryHook<TData>(
|
|
queryKeyFactory: (id: string | null | undefined) => readonly unknown[],
|
|
queryFnFactory: (id: string) => Promise<TData>,
|
|
options?: {
|
|
staleTime?: number;
|
|
placeholderData?: TData;
|
|
}
|
|
) {
|
|
return (id: string | null | undefined) =>
|
|
useQuery({
|
|
queryKey: queryKeyFactory(id),
|
|
queryFn: () => queryFnFactory(id!),
|
|
enabled: !!id,
|
|
staleTime: options?.staleTime ?? commonQueryOptions.standardStaleTime,
|
|
placeholderData: options?.placeholderData,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generic list query hook factory
|
|
* For fetching collections of entities
|
|
*/
|
|
export function createListQueryHook<TData extends unknown[]>(
|
|
queryKey: readonly unknown[],
|
|
queryFn: () => Promise<TData>,
|
|
options?: {
|
|
staleTime?: number;
|
|
}
|
|
) {
|
|
return () =>
|
|
useQuery({
|
|
queryKey,
|
|
queryFn,
|
|
staleTime: options?.staleTime ?? commonQueryOptions.standardStaleTime,
|
|
placeholderData: commonQueryOptions.emptyListPlaceholder<TData[0]>(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generic conditional list query hook factory
|
|
* For fetching collections with conditional enabling
|
|
*/
|
|
export function createConditionalListQueryHook<TData extends unknown[], TParam>(
|
|
queryKeyFactory: (param: TParam | null | undefined) => readonly unknown[],
|
|
queryFnFactory: (param: TParam) => Promise<TData>,
|
|
options?: {
|
|
staleTime?: number;
|
|
}
|
|
) {
|
|
return (param: TParam | null | undefined) =>
|
|
useQuery({
|
|
queryKey: queryKeyFactory(param),
|
|
queryFn: () => queryFnFactory(param!),
|
|
enabled: !!param,
|
|
staleTime: options?.staleTime ?? commonQueryOptions.standardStaleTime,
|
|
placeholderData: commonQueryOptions.emptyListPlaceholder<TData[0]>(),
|
|
});
|
|
}
|