2025-09-05 17:49:48 +02:00
|
|
|
/**
|
|
|
|
|
* Auth React Query hooks
|
|
|
|
|
*/
|
|
|
|
|
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
|
|
|
|
|
import { authService } from '../services/auth';
|
2025-10-06 15:27:01 +02:00
|
|
|
import {
|
|
|
|
|
UserRegistration,
|
|
|
|
|
UserLogin,
|
|
|
|
|
TokenResponse,
|
|
|
|
|
PasswordChange,
|
|
|
|
|
PasswordReset,
|
|
|
|
|
UserResponse,
|
|
|
|
|
UserUpdate,
|
|
|
|
|
TokenVerification
|
2025-09-05 17:49:48 +02:00
|
|
|
} from '../types/auth';
|
|
|
|
|
import { ApiError } from '../client';
|
2025-09-24 21:54:49 +02:00
|
|
|
import { useAuthStore } from '../../stores/auth.store';
|
2025-09-05 17:49:48 +02:00
|
|
|
|
|
|
|
|
// Query Keys
|
|
|
|
|
export const authKeys = {
|
|
|
|
|
all: ['auth'] as const,
|
|
|
|
|
profile: () => [...authKeys.all, 'profile'] as const,
|
|
|
|
|
health: () => [...authKeys.all, 'health'] as const,
|
|
|
|
|
verify: (token?: string) => [...authKeys.all, 'verify', token] as const,
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
// Queries
|
|
|
|
|
export const useAuthProfile = (
|
|
|
|
|
options?: Omit<UseQueryOptions<UserResponse, ApiError>, 'queryKey' | 'queryFn'>
|
|
|
|
|
) => {
|
|
|
|
|
return useQuery<UserResponse, ApiError>({
|
|
|
|
|
queryKey: authKeys.profile(),
|
|
|
|
|
queryFn: () => authService.getProfile(),
|
|
|
|
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useAuthHealth = (
|
2025-10-06 15:27:01 +02:00
|
|
|
options?: Omit<UseQueryOptions<{ status: string; service: string }, ApiError>, 'queryKey' | 'queryFn'>
|
2025-09-05 17:49:48 +02:00
|
|
|
) => {
|
2025-10-06 15:27:01 +02:00
|
|
|
return useQuery<{ status: string; service: string }, ApiError>({
|
2025-09-05 17:49:48 +02:00
|
|
|
queryKey: authKeys.health(),
|
|
|
|
|
queryFn: () => authService.healthCheck(),
|
|
|
|
|
staleTime: 30 * 1000, // 30 seconds
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useVerifyToken = (
|
|
|
|
|
token?: string,
|
2025-10-06 15:27:01 +02:00
|
|
|
options?: Omit<UseQueryOptions<TokenVerification, ApiError>, 'queryKey' | 'queryFn'>
|
2025-09-05 17:49:48 +02:00
|
|
|
) => {
|
2025-10-06 15:27:01 +02:00
|
|
|
return useQuery<TokenVerification, ApiError>({
|
2025-09-05 17:49:48 +02:00
|
|
|
queryKey: authKeys.verify(token),
|
|
|
|
|
queryFn: () => authService.verifyToken(token),
|
|
|
|
|
enabled: !!token,
|
|
|
|
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Mutations
|
|
|
|
|
export const useRegister = (
|
|
|
|
|
options?: UseMutationOptions<TokenResponse, ApiError, UserRegistration>
|
|
|
|
|
) => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
|
|
|
|
return useMutation<TokenResponse, ApiError, UserRegistration>({
|
|
|
|
|
mutationFn: (userData: UserRegistration) => authService.register(userData),
|
|
|
|
|
onSuccess: (data) => {
|
|
|
|
|
// Update profile query with new user data
|
|
|
|
|
if (data.user) {
|
|
|
|
|
queryClient.setQueryData(authKeys.profile(), data.user);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useLogin = (
|
|
|
|
|
options?: UseMutationOptions<TokenResponse, ApiError, UserLogin>
|
|
|
|
|
) => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
|
|
|
|
return useMutation<TokenResponse, ApiError, UserLogin>({
|
|
|
|
|
mutationFn: (loginData: UserLogin) => authService.login(loginData),
|
|
|
|
|
onSuccess: (data) => {
|
|
|
|
|
// Update profile query with new user data
|
|
|
|
|
if (data.user) {
|
|
|
|
|
queryClient.setQueryData(authKeys.profile(), data.user);
|
|
|
|
|
}
|
|
|
|
|
// Invalidate all queries to refresh data
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: ['auth'] });
|
|
|
|
|
},
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useRefreshToken = (
|
|
|
|
|
options?: UseMutationOptions<TokenResponse, ApiError, string>
|
|
|
|
|
) => {
|
|
|
|
|
return useMutation<TokenResponse, ApiError, string>({
|
|
|
|
|
mutationFn: (refreshToken: string) => authService.refreshToken(refreshToken),
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useLogout = (
|
|
|
|
|
options?: UseMutationOptions<{ message: string }, ApiError, string>
|
|
|
|
|
) => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
|
|
|
|
return useMutation<{ message: string }, ApiError, string>({
|
|
|
|
|
mutationFn: (refreshToken: string) => authService.logout(refreshToken),
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
// Clear all queries on logout
|
|
|
|
|
queryClient.clear();
|
|
|
|
|
},
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useChangePassword = (
|
|
|
|
|
options?: UseMutationOptions<{ message: string }, ApiError, PasswordChange>
|
|
|
|
|
) => {
|
|
|
|
|
return useMutation<{ message: string }, ApiError, PasswordChange>({
|
|
|
|
|
mutationFn: (passwordData: PasswordChange) => authService.changePassword(passwordData),
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useResetPassword = (
|
|
|
|
|
options?: UseMutationOptions<{ message: string }, ApiError, PasswordReset>
|
|
|
|
|
) => {
|
|
|
|
|
return useMutation<{ message: string }, ApiError, PasswordReset>({
|
|
|
|
|
mutationFn: (resetData: PasswordReset) => authService.resetPassword(resetData),
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useUpdateProfile = (
|
|
|
|
|
options?: UseMutationOptions<UserResponse, ApiError, UserUpdate>
|
|
|
|
|
) => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
|
|
|
|
return useMutation<UserResponse, ApiError, UserUpdate>({
|
|
|
|
|
mutationFn: (updateData: UserUpdate) => authService.updateProfile(updateData),
|
|
|
|
|
onSuccess: (data) => {
|
|
|
|
|
// Update the profile cache
|
|
|
|
|
queryClient.setQueryData(authKeys.profile(), data);
|
2025-09-24 21:54:49 +02:00
|
|
|
// Update the auth store user to maintain consistency
|
|
|
|
|
const authStore = useAuthStore.getState();
|
|
|
|
|
if (authStore.user) {
|
2025-10-06 15:27:01 +02:00
|
|
|
authStore.updateUser(data as any);
|
2025-09-24 21:54:49 +02:00
|
|
|
}
|
2025-09-05 17:49:48 +02:00
|
|
|
},
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useVerifyEmail = (
|
|
|
|
|
options?: UseMutationOptions<{ message: string }, ApiError, { userId: string; verificationToken: string }>
|
|
|
|
|
) => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
|
|
|
|
return useMutation<{ message: string }, ApiError, { userId: string; verificationToken: string }>({
|
|
|
|
|
mutationFn: ({ userId, verificationToken }) =>
|
|
|
|
|
authService.verifyEmail(userId, verificationToken),
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
// Invalidate profile to get updated verification status
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: authKeys.profile() });
|
|
|
|
|
},
|
|
|
|
|
...options,
|
|
|
|
|
});
|
|
|
|
|
};
|