Skip to content

Latest commit

 

History

History
197 lines (161 loc) · 6.91 KB

File metadata and controls

197 lines (161 loc) · 6.91 KB

Profile Completion Form and Onboarding Flow Analysis

Summary

This analysis examines the frontend code for the profile completion form and onboarding flow in the LSDN application. The files reviewed include:

  • /frontend/src/pages/ProfileCompletion.tsx - Profile completion page
  • /frontend/src/hooks/useOnboarding.ts - Onboarding state management
  • /frontend/src/hooks/useAuth.tsx - Authentication and profile management
  • /frontend/src/App.tsx - Main app routing
  • /backend/src/routes/users.ts - Backend profile routes
  • /backend/src/services/userService.ts - User service layer
  • /backend/src/middleware/validation.ts - Request validation

Key Functionality

ProfileCompletion.tsx

The profile completion page is the first step after login/registration. It collects:

  • Profile picture
  • First name, last name, age
  • Bio (max 500 characters)
  • Interests (multi-select)
  • Relationship goals (multi-select)

Form validation ensures all fields are filled, age is between 18-100, and bio doesn't exceed 500 characters.

useOnboarding Hook

Manages onboarding state with local storage persistence:

  • Tracks completed steps: auth, profile, preferences, payment, welcome
  • Methods to complete/uncomplete steps, check accessibility, and calculate progress
  • Redirects users to appropriate step based on completion status

useAuth Hook

Handles authentication and profile management:

  • updateProfile() makes a PUT request to /api/users/profile with token authentication
  • Returns { success: boolean, error?: string } format for error handling
  • Updates user state on successful profile update

Backend API

  • /api/users/profile endpoint accepts PUT requests with profile data
  • Validates input using Joi schema
  • Handles age to dateOfBirth conversion
  • Updates profilePhotoUrl field with provided value (including null)

Testing Results

Tested profile update with null profile picture - API responds correctly and updates the field to null.

Potential Issues Identified

1. Error Handling in ProfileCompletion.tsx

Problem: Uses alert() for error notifications instead of consistent error display component.

Code Location: ProfileCompletion.tsx

Impact: Inconsistent user experience compared to Login/Register pages which use proper error components.

2. No Loading State in useAuth.updateProfile

Problem: The updateProfile method in useAuth doesn't set a loading state.

Code Location: useAuth.tsx

Impact: Users don't see any feedback while waiting for the profile update to complete.

3. Unused Error State in useAuth

Problem: The error state in useAuth is not utilized in ProfileCompletion.tsx.

Code Location: useAuth.tsx

Impact: Errors may not be properly displayed to users.

4. Inconsistent Error Handling Patterns

Problem: Different error handling approaches across pages:

  • Login/Register use error state and display components
  • ProfileCompletion uses alert()

Code Location: ProfileCompletion.tsx

Impact: Confusing user experience.

5. No Error Boundary for API Errors

Problem: API errors (e.g., network failures) may not be properly caught and displayed.

Code Location: useAuth.tsx

Suggested Improvements

1. Replace Alert with Error Component

// In ProfileCompletion.tsx
const [error, setError] = useState<string | null>(null);

// In handleSubmit
if (result.success) {
  // ... existing success logic
} else {
  setError(result.error || 'Failed to update profile');
}
// ...
catch (error) {
  console.error('Error updating profile:', error);
  setError('Failed to update profile');
}

// In render
{error && (
  <div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
    <div className="flex items-center">
      <svg className="h-5 w-5 text-red-400 mr-2" viewBox="0 0 20 20" fill="currentColor">
        <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
      </svg>
      <span className="text-sm font-medium text-red-800">{error}</span>
    </div>
  </div>
)}

2. Add Loading State to useAuth

// In useAuth.tsx
const updateProfile = async (userData: any): Promise<{ success: boolean; error?: string }> => {
  try {
    setError(null);
    setLoading(true); // Add this
    const token = localStorage.getItem('token');
    const response = await fetch('/api/users/profile', {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify(userData),
    });

    if (response.ok) {
      const { data } = await response.json();
      setUser(data.user);
      return { success: true };
    } else {
      const errorData = await response.json().catch(() => ({ message: 'Profile update failed' }));
      return { success: false, error: errorData.message || 'Profile update failed' };
    }
  } catch (error) {
    console.error('Error updating profile:', error);
    return { success: false, error: 'Network error. Please try again.' };
  } finally {
    setLoading(false); // Add this
  }
};

3. Ensure Consistent Error Handling

Update all pages to use the same error display component for consistency.

4. Improve API Error Handling

// In useAuth.tsx
const updateProfile = async (userData: any): Promise<{ success: boolean; error?: string }> => {
  try {
    setError(null);
    setLoading(true);
    const token = localStorage.getItem('token');
    
    // Check if token exists
    if (!token) {
      setLoading(false);
      return { success: false, error: 'Authentication required' };
    }

    const response = await fetch('/api/users/profile', {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify(userData),
    });

    const result = await response.json();

    if (response.ok) {
      setUser(result.data.user);
      return { success: true };
    } else {
      return { success: false, error: result.message || 'Profile update failed' };
    }
  } catch (error: any) {
    console.error('Error updating profile:', error);
    return { 
      success: false, 
      error: error.message || 'Network error. Please check your connection and try again.' 
    };
  } finally {
    setLoading(false);
  }
};

Conclusion

The profile completion form and onboarding flow are generally functional but have several usability and consistency issues with error handling and feedback. Implementing the suggested improvements will enhance the user experience and make the application more robust.