fix: resolve profile page data persistence and password change issues
Fixed critical issues with the profile page (/dashboard/profile):
1. **Form data not persisting on page refresh**:
- Added useEffect to update form values when user data loads
- Forms now properly populate after auth context loads user data
2. **Blank page on refresh**:
- Added loading and error states for better UX
- Handle case where user is not loaded yet (loading spinner)
- Handle case where user fails to load (retry button)
3. **Password change API endpoint correction**:
- Fixed: POST /api/v1/users/change-password (incorrect)
- Corrected to: PATCH /api/v1/users/me/password (matches backend)
- Updated return type to include { message: string }
The root cause was that useForm defaultValues were set once at
component mount when user was still null. The form never updated
when user data was subsequently loaded by the auth context.
Now the form properly resets with user data via useEffect, and
proper loading/error states prevent showing a blank page.
Refs: apps/frontend/app/dashboard/profile/page.tsx:68-78
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
905a56888a
commit
2054e73e78
@ -6,7 +6,7 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useAuth } from '@/lib/context/auth-context';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@ -44,7 +44,7 @@ const profileSchema = z.object({
|
||||
type ProfileFormData = z.infer<typeof profileSchema>;
|
||||
|
||||
export default function ProfilePage() {
|
||||
const { user, refreshUser } = useAuth();
|
||||
const { user, refreshUser, loading } = useAuth();
|
||||
const queryClient = useQueryClient();
|
||||
const [activeTab, setActiveTab] = useState<'profile' | 'password'>('profile');
|
||||
const [successMessage, setSuccessMessage] = useState('');
|
||||
@ -65,6 +65,18 @@ export default function ProfilePage() {
|
||||
resolver: zodResolver(passwordSchema),
|
||||
});
|
||||
|
||||
// Update form values when user data loads
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
profileForm.reset({
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
email: user.email,
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [user]);
|
||||
|
||||
// Update profile mutation
|
||||
const updateProfileMutation = useMutation({
|
||||
mutationFn: (data: ProfileFormData) => {
|
||||
@ -112,6 +124,35 @@ export default function ProfilePage() {
|
||||
updatePasswordMutation.mutate(data);
|
||||
};
|
||||
|
||||
// Show loading state while user data is being fetched
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-600">Loading profile...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Show error if user is not found after loading
|
||||
if (!loading && !user) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-center">
|
||||
<p className="text-red-600 mb-4">Unable to load user profile</p>
|
||||
<button
|
||||
onClick={() => window.location.reload()}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
|
||||
>
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto space-y-6">
|
||||
{/* Header */}
|
||||
|
||||
@ -103,7 +103,7 @@ export const usersApi = {
|
||||
/**
|
||||
* Change password
|
||||
*/
|
||||
async changePassword(data: ChangePasswordRequest): Promise<void> {
|
||||
return apiClient.post<void>('/api/v1/users/change-password', data);
|
||||
async changePassword(data: ChangePasswordRequest): Promise<{ message: string }> {
|
||||
return apiClient.patch<{ message: string }>('/api/v1/users/me/password', data);
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user