From 2054e73e78026bb1be4a050d97950a23d0f2bc8c Mon Sep 17 00:00:00 2001 From: David Date: Mon, 12 Jan 2026 18:18:04 +0100 Subject: [PATCH] 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 --- apps/frontend/app/dashboard/profile/page.tsx | 45 +++++++++++++++++++- apps/frontend/lib/api/users.ts | 4 +- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/apps/frontend/app/dashboard/profile/page.tsx b/apps/frontend/app/dashboard/profile/page.tsx index 96b3a25..13249e2 100644 --- a/apps/frontend/app/dashboard/profile/page.tsx +++ b/apps/frontend/app/dashboard/profile/page.tsx @@ -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; 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 ( +
+
+
+

Loading profile...

+
+
+ ); + } + + // Show error if user is not found after loading + if (!loading && !user) { + return ( +
+
+

Unable to load user profile

+ +
+
+ ); + } + return (
{/* Header */} diff --git a/apps/frontend/lib/api/users.ts b/apps/frontend/lib/api/users.ts index 87f6d80..0ab2ccb 100644 --- a/apps/frontend/lib/api/users.ts +++ b/apps/frontend/lib/api/users.ts @@ -103,7 +103,7 @@ export const usersApi = { /** * Change password */ - async changePassword(data: ChangePasswordRequest): Promise { - return apiClient.post('/api/v1/users/change-password', data); + async changePassword(data: ChangePasswordRequest): Promise<{ message: string }> { + return apiClient.patch<{ message: string }>('/api/v1/users/me/password', data); }, };