forked from cardosofelipe/fast-next-template
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.
This commit is contained in:
83
frontend/src/lib/api/hooks/useUser.ts
Normal file
83
frontend/src/lib/api/hooks/useUser.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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');
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user