Files
fast-next-template/frontend/src/lib/api/hooks/useUser.ts
Felipe Cardoso 65f209c679 Add forms for profile and password settings; improve tests for settings pages
- Implement `ProfileSettingsForm` and `PasswordChangeForm` components to manage user profile and password updates.
- Add `SessionCard` for session management and related API hooks (`useSession`).
- Update settings page tests to include user state mock and React Query provider for better test reliability.
- Enhance `PasswordSettingsPage` and `ProfileSettingsPage` tests to verify component rendering and user interaction.
- Improve API hook structure with dedicated hooks for session and user profile management.
2025-11-02 23:24:29 +01:00

84 lines
2.4 KiB
TypeScript

/**
* User Management React Query Hooks
*
* Integrates with auto-generated API client and authStore for user profile management.
* All hooks use generated SDK functions for type safety and OpenAPI compliance.
*
* @module lib/api/hooks/useUser
*/
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { updateCurrentUser } from '../client';
import { useAuthStore } from '@/lib/stores/authStore';
import type { User } from '@/lib/stores/authStore';
import { parseAPIError, getGeneralError } from '../errors';
import { authKeys } from './useAuth';
// ============================================================================
// Mutations
// ============================================================================
/**
* Update current user profile mutation
* PATCH /api/v1/users/me
*
* On success:
* - Updates user in auth store
* - Invalidates auth queries
*
* @param onSuccess Optional callback after successful update
* @returns React Query mutation
*/
export function useUpdateProfile(onSuccess?: (message: string) => void) {
const queryClient = useQueryClient();
const setUser = useAuthStore((state) => state.setUser);
return useMutation({
mutationFn: async (data: {
first_name?: string;
last_name?: string;
email?: string;
}) => {
const response = await updateCurrentUser({
body: data,
throwOnError: false,
});
if ('error' in response) {
throw response.error;
}
// Type assertion: if no error, response has data
const responseData = (response as { data: unknown }).data;
// Validate response is a user object
if (
typeof responseData !== 'object' ||
responseData === null ||
!('id' in responseData)
) {
throw new Error('Invalid profile update response: missing user data');
}
return responseData as User;
},
onSuccess: (data) => {
// Update auth store with new user data
setUser(data);
// Invalidate auth queries to refetch user data
queryClient.invalidateQueries({ queryKey: authKeys.me });
// Call custom success callback if provided
if (onSuccess) {
onSuccess('Profile updated successfully');
}
},
onError: (error: unknown) => {
const errors = parseAPIError(error);
const generalError = getGeneralError(errors);
console.error('Profile update failed:', generalError || 'Unknown error');
},
});
}