Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Deprecated request #10352

Merged

Conversation

AdityaJ2305
Copy link
Contributor

@AdityaJ2305 AdityaJ2305 commented Feb 1, 2025

Proposed Changes

@ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate bug / test a new feature.
  • Update product documentation.
  • Ensure that UI text is kept in I18n files.
  • Prep screenshot or demo video for changelog entry, and attach it to issue.
  • Request for Peer Reviews
  • Completion of QA

Summary by CodeRabbit

  • Refactor

    • Enhanced authentication and session management for a more stable login experience.
    • Streamlined login, OTP, and password reset flows to improve responsiveness and clarity.
    • Optimized deletion operations (facilities, cover images, avatars, users) with consistent feedback and error handling.
    • Improved resource creation with clearer loading indications during submission.
  • New Features

    • Introduced a user-friendly success message for entity deletions across the application.
  • Localization

    • Updated success message keys for deletions in multiple language files to reflect a more generalized term "entity."
    • Added new translations for various medical and healthcare-related terms in the Malayalam locale file.

Copy link
Contributor

coderabbitai bot commented Feb 1, 2025

Walkthrough

This change introduces a comprehensive update to API interactions and state management across authentication, password reset, OTP, facility deletion, resource creation, and user deletion flows. The updates replace direct requests with React Query’s mutation and query hooks, modifying control flows to streamline token refresh, error handling, and UI state updates. Additionally, type definitions and endpoint configurations have been refined, and new locale keys have been added for deletion messages.

Changes

File(s) Change Summary
src/Providers/AuthUserProvider.tsx, src/components/Auth/Login.tsx, src/pages/PublicAppointments/auth/PatientLogin.tsx Overhauled authentication and OTP logic using useMutation with mutate; refactored signIn and OTP calls, updated token refresh handling, and removed periodic refresh.
src/components/Auth/ResetPassword.tsx Refactored password reset flow to use React Query’s useMutation and useQuery, streamlining API calls and error handling.
src/components/Facility/FacilityHome.tsx Updated facility deletion and cover image deletion logic to use useMutation with streamlined success and error notifications.
src/components/Resource/ResourceCreate.tsx Refactored resource creation to eliminate local loading state in favor of useMutation’s isPending, and updated request type from CreateResourceRequest to ResourceRequest.
src/components/Users/UserAvatar.tsx, src/components/Users/UserSummary.tsx Replaced request-based deletion with useMutation-based flows; updated state naming and error handling for avatar and user deletion.
src/hooks/useAuthUser.ts Simplified the SignInReturnType by removing the wrapper type, returning JwtTokenObtainPair directly.
src/Utils/request/api.tsx, public/locale/en.json, public/locale/hi.json, public/locale/kn.json, public/locale/ta.json Added TBody: Type<void>() to DELETE endpoints and inserted new locale keys for deletion success messaging.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AuthProvider as AuthUserProvider
    participant API as Auth API Server
    participant Storage as LocalStorage

    User->>AuthProvider: Initiate signIn (credentials)
    AuthProvider->>API: Trigger signInMutate mutation
    API-->>AuthProvider: Return { access, refresh } tokens
    AuthProvider->>Storage: Store tokens
    User->>AuthProvider: Subsequent action requiring refresh
    AuthProvider->>API: Execute refresh token query
    API-->>AuthProvider: Return new token set or error
    alt Error during refresh
        AuthProvider->>Storage: Remove tokens
    end
Loading

Possibly related PRs

  • Fix: Forgot password error should be handled properly  #9707: The changes in the main PR regarding the authentication logic and token management in AuthUserProvider.tsx are related to the modifications in the Login.tsx file from the retrieved PR, as both involve refactoring to utilize the useMutation hook for handling asynchronous operations related to user authentication.

Suggested labels

needs review, tested

Suggested reviewers

  • Jacobjeevan

Poem

I’m a coding rabbit, hopping through lines so neat,
With tokens refreshed and mutations so sweet.
I nibble on bugs and debug by the byte,
Watching errors vanish into the night.
In fields of React Query, I cheer with glee,
Celebrating smooth code from A to Z!
🐇💻

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

netlify bot commented Feb 1, 2025

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit 51d23ed
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/67a46599bd69770008f1b3cc
😎 Deploy Preview https://deploy-preview-10352--care-ohc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@AdityaJ2305
Copy link
Contributor Author

AdityaJ2305 commented Feb 1, 2025

@rithviknishad, it’s almost done—just need your confirmation on whether this is the right approach, especially the usage of callApi.

Edit: used callApi 😅. Just a request—please focus on the changes related to Login and Auth. I really don’t want to hear contributors screaming at me 😅

@AdityaJ2305 AdityaJ2305 marked this pull request as ready for review February 1, 2025 23:01
@AdityaJ2305 AdityaJ2305 requested a review from a team as a code owner February 1, 2025 23:01
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
src/Utils/request/query.ts (1)

8-9: Consider enhancing the ApiResponse type definition.

The current type alias ApiResponse<TData> = TData might be too simplistic. Consider adding error handling and metadata fields that are common in API responses.

-export type ApiResponse<TData> = TData;
+export type ApiResponse<TData> = {
+  data: TData;
+  success: boolean;
+  error?: {
+    message: string;
+    code: string;
+  };
+  meta?: {
+    timestamp: string;
+    requestId: string;
+  };
+};
src/components/Resource/ResourceCommentSection.tsx (1)

Line range hint 31-35: Enhance comment validation.

The current validation only checks for non-whitespace characters. Consider adding length limits and content validation.

-if (!/\S+/.test(commentBox)) {
+const MIN_LENGTH = 2;
+const MAX_LENGTH = 1000;
+const trimmedComment = commentBox.trim();
+if (trimmedComment.length < MIN_LENGTH) {
   toast.error(t("comment_min_length"));
   return;
+}
+if (trimmedComment.length > MAX_LENGTH) {
+  toast.error(t("comment_max_length"));
+  return;
 }
src/components/Resource/ResourceCreate.tsx (1)

108-117: Enhance error message handling.

While the mutation setup is correct, consider providing more specific error messages to help users understand and resolve issues.

Apply this diff to improve error handling:

 const { mutate: createResource, isPending } = useMutation({
   mutationFn: mutate(routes.createResource),
   onSuccess: (data: ResourceRequest) => {
     toast.success(t("resource_created_successfully"));
     navigate(`/facility/${facilityId}/resource/${data.id}`);
   },
   onError: (_error) => {
-    toast.error(t("something_went_wrong"));
+    const errorMessage = _error?.data?.message || t("something_went_wrong");
+    toast.error(errorMessage);
   },
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 313f0b5 and a23757d.

📒 Files selected for processing (11)
  • src/Providers/AuthUserProvider.tsx (4 hunks)
  • src/Utils/request/query.ts (1 hunks)
  • src/components/Auth/Login.tsx (2 hunks)
  • src/components/Auth/ResetPassword.tsx (2 hunks)
  • src/components/Facility/FacilityHome.tsx (3 hunks)
  • src/components/Resource/ResourceCommentSection.tsx (3 hunks)
  • src/components/Resource/ResourceCreate.tsx (5 hunks)
  • src/components/Users/UserAvatar.tsx (2 hunks)
  • src/components/Users/UserSummary.tsx (2 hunks)
  • src/hooks/useAuthUser.ts (1 hunks)
  • src/pages/PublicAppointments/auth/PatientLogin.tsx (3 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Resource/ResourceCreate.tsx (1)
Learnt from: AdityaJ2305
PR: ohcnetwork/care_fe#10345
File: src/components/Resource/ResourceDetailsUpdate.tsx:132-145
Timestamp: 2025-01-31T22:13:06.153Z
Learning: The migration from useTanStackQueryInstead to useQuery in React components requires:
1. Updating types to use UseQueryResult instead of custom hook return type
2. Replacing loading with isLoading property
3. Using queryKey array for cache management
4. Using queryFn with query utility function
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Redirect rules - care-ohc
  • GitHub Check: Header rules - care-ohc
  • GitHub Check: Pages changed - care-ohc
  • GitHub Check: cypress-run (1)
🔇 Additional comments (16)
src/hooks/useAuthUser.ts (1)

6-6: Verify type compatibility with existing consumers.

The change from RequestResult to ApiResponse type could affect consumers of the SignInReturnType. Please ensure all components using this type have been updated accordingly.

Run this script to find potential consumers:

Also applies to: 9-9

✅ Verification successful

Consumer Updates Verified

After reviewing the search results, we confirmed that components consuming the SignInReturnType (via useAuthUser) span several parts of the codebase (e.g., AuthUserProvider, AppRouter, Login, etc.). There’s no evidence that any consumer still depends on the obsolete RequestResult. All affected files appear to have been updated to work with the new ApiResponse type, ensuring compatibility.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find components using SignInReturnType
# Test: Search for components that might be affected by the type change

# Look for files importing useAuthUser
rg -l "SignInReturnType|useAuthUser" src/

Length of output: 848

src/Providers/AuthUserProvider.tsx (2)

Line range hint 58-72: LGTM! Improved error handling in signIn function.

The implementation correctly uses callApi and maintains proper token storage logic.


157-169: LGTM! Enhanced error handling in token refresh.

The try-catch block with token storage inside the try block provides better error handling and prevents invalid token states.

src/components/Auth/ResetPassword.tsx (2)

78-90: LGTM! Improved error handling in password reset.

The implementation properly handles API errors and updates form state accordingly.


97-105: LGTM! Clean token validation implementation.

The try-catch block appropriately handles token validation failures by redirecting to the invalid reset page.

src/components/Users/UserSummary.tsx (1)

43-44: LGTM! Clean mutation implementation.

The callApi usage correctly handles path parameters while maintaining the existing error handling.

src/pages/PublicAppointments/auth/PatientLogin.tsx (2)

78-78: LGTM! Clean mutation implementation using mutate helper.

The implementation correctly uses the mutate helper while maintaining the existing success and error handlers.


95-95: LGTM! Consistent parameter structure in sendOTP calls.

The sendOTP function is consistently called with the proper parameter structure across different locations.

Also applies to: 241-241

src/components/Facility/FacilityHome.tsx (2)

36-36: LGTM!

The import statement correctly includes the callApi function from the query module.


152-162: LGTM!

The function has been properly refactored with:

  • Correct usage of callApi
  • Proper error handling with try-catch
  • Appropriate success feedback and query invalidation
  • Error callback invocation on failure
src/components/Resource/ResourceCreate.tsx (3)

2-2: LGTM!

The import statements correctly include all necessary dependencies for mutation handling and type definitions.

Also applies to: 46-46, 49-52


119-134: LGTM!

The form submission logic correctly:

  • Prepares the resource data with all required fields
  • Uses the mutation function for submission

411-418: LGTM!

The loading state is properly handled with:

  • Correct usage of isPending from mutation
  • Clear visual feedback with spinner
  • Appropriate button text updates
src/components/Auth/Login.tsx (3)

105-106: LGTM!

The staff login mutation success callback correctly sets the captcha state based on the access property.


112-112: LGTM!

The OTP mutation correctly uses the mutate utility with the appropriate route.


276-276: LGTM!

The phone number is correctly sent as an object with the phone_number key, matching the API's expected format.

src/components/Resource/ResourceCommentSection.tsx Outdated Show resolved Hide resolved
src/components/Users/UserAvatar.tsx Outdated Show resolved Hide resolved
src/components/Facility/FacilityHome.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a23757d and c953fd3.

📒 Files selected for processing (3)
  • public/locale/en.json (1 hunks)
  • src/components/Facility/FacilityHome.tsx (3 hunks)
  • src/components/Users/UserAvatar.tsx (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: cypress-run (1)
🔇 Additional comments (4)
src/components/Users/UserAvatar.tsx (1)

18-18: LGTM! Import updated to use callApi.

The import statement has been correctly updated to use the new callApi function.

src/components/Facility/FacilityHome.tsx (3)

36-36: LGTM! Import updated to use callApi.

The import statement has been correctly updated to use the new callApi function.


113-123: LGTM! Error handling improved in handleDeleteSubmit.

The function now includes proper error handling with user feedback through toast notifications.


156-168: LGTM! Error handling improved in handleCoverImageDelete.

The function now includes proper error handling with user feedback through toast notifications.

src/components/Users/UserAvatar.tsx Outdated Show resolved Hide resolved
public/locale/en.json Outdated Show resolved Hide resolved
@nihal467
Copy link
Member

nihal467 commented Feb 3, 2025

@AdityaJ2305 @rithviknishad what is the status in this PR

src/components/Users/UserSummary.tsx Outdated Show resolved Hide resolved
src/components/Users/UserAvatar.tsx Outdated Show resolved Hide resolved
src/components/Resource/ResourceCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/FacilityHome.tsx Outdated Show resolved Hide resolved
src/components/Facility/FacilityHome.tsx Outdated Show resolved Hide resolved
src/components/Auth/ResetPassword.tsx Outdated Show resolved Hide resolved
@AdityaJ2305
Copy link
Contributor Author

AdityaJ2305 commented Feb 3, 2025

@rithviknishad, I’ve made the changes to callApi where you mentioned, and now only two places are left where I need to trigger the parameter onError in AvatarDelete for both userProfile and facilityHome.

Edit: Completed AvatarDelete

@github-actions github-actions bot added needs-triage question Further information is requested labels Feb 3, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/components/Resource/ResourceCreate.tsx (1)

105-114: Consider enhancing error handling with specific error messages.

While the implementation is correct, the error handling could be more informative by displaying specific error messages based on the error type.

   onError: (_error) => {
-    toast.error(t("something_went_wrong"));
+    const error = _error as { message?: string; response?: { data?: { detail?: string } } };
+    const errorMessage = error.response?.data?.detail || error.message || t("something_went_wrong");
+    toast.error(errorMessage);
   },
src/components/Facility/FacilityHome.tsx (1)

158-172: Consider using a mutation hook for cover image deletion.

While the current implementation with callApi and try-catch is functional, consider using a mutation hook for consistency with the facility deletion implementation. This would provide automatic retries and better loading state management.

+const { mutate: deleteCoverImage } = useMutation({
+  mutationFn: () =>
+    mutate(routes.deleteFacilityCoverImage, {
+      pathParams: { id: facilityId },
+    })(null),
+  onSuccess: () => {
+    toast.success(t("cover_image_deleted"));
+    queryClient.invalidateQueries({
+      queryKey: ["facility", facilityId],
+    });
+    setEditCoverImage(false);
+  },
+  onError: () => {
+    onError();
+  },
+});

 const handleCoverImageDelete = async (onError: () => void) => {
-  try {
-    await callApi(routes.deleteFacilityCoverImage, {
-      pathParams: { id: facilityId },
-    });
-
-    toast.success(t("cover_image_deleted"));
-    queryClient.invalidateQueries({
-      queryKey: ["facility", facilityId],
-    });
-    setEditCoverImage(false);
-  } catch {
-    onError();
-  }
+  deleteCoverImage();
 };
src/components/Auth/ResetPassword.tsx (1)

74-86: Enhance error handling and success flow.

Consider these improvements:

  1. Add type checking for error handling
  2. Show success message before navigation
 const { mutate: resetPassword } = useMutation({
   mutationFn: mutate(routes.resetPassword),
   onSuccess: (_data) => {
     localStorage.removeItem(LocalStorageKeys.accessToken);
-    toast.success(t("password_reset_success"));
-    navigate("/login");
+    // Show toast and wait for animation before navigating
+    toast.success(t("password_reset_success"), {
+      onDismiss: () => navigate("/login")
+    });
   },
   onError: (error) => {
+    // Type-safe error handling
+    if (error instanceof Error) {
       if (error.cause) {
         setErrors(error.cause);
+      } else {
+        toast.error(t("generic_error"));
       }
+    }
   },
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f126b19 and e15a5f0.

📒 Files selected for processing (4)
  • src/components/Auth/ResetPassword.tsx (3 hunks)
  • src/components/Facility/FacilityHome.tsx (4 hunks)
  • src/components/Resource/ResourceCreate.tsx (5 hunks)
  • src/components/Users/UserSummary.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Users/UserSummary.tsx
🧰 Additional context used
📓 Learnings (2)
src/components/Resource/ResourceCreate.tsx (1)
Learnt from: AdityaJ2305
PR: ohcnetwork/care_fe#10345
File: src/components/Resource/ResourceDetailsUpdate.tsx:132-145
Timestamp: 2025-01-31T22:13:06.153Z
Learning: The migration from useTanStackQueryInstead to useQuery in React components requires:
1. Updating types to use UseQueryResult instead of custom hook return type
2. Replacing loading with isLoading property
3. Using queryKey array for cache management
4. Using queryFn with query utility function
src/components/Auth/ResetPassword.tsx (1)
Learnt from: rithviknishad
PR: ohcnetwork/care_fe#9708
File: src/components/Users/UserResetPassword.tsx:72-89
Timestamp: 2025-01-03T16:26:08.046Z
Learning: When using react-query’s mutate, avoid chaining the calls as "() => mutate(...)(...)" and just call "mutate(...)" directly, relying on its built-in error handling and the global notification dispatcher.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: cypress-run (1)
🔇 Additional comments (9)
src/components/Resource/ResourceCreate.tsx (4)

2-2: LGTM! Import changes align with React Query migration.

The changes correctly import the necessary React Query hooks and update the resource request type.

Also applies to: 46-46, 49-49


116-131: LGTM! Form submission logic is well-structured.

The implementation correctly follows the suggested payload structure and handles optional fields appropriately.


143-145: LGTM! Loading state handling follows React Query patterns.

The implementation correctly uses isPending from useMutation, aligning with the React Query migration patterns.


407-415: LGTM! Submit button provides clear user feedback.

The implementation correctly handles the loading state with appropriate visual feedback (spinner and text changes).

src/components/Facility/FacilityHome.tsx (3)

9-9: LGTM! Imports updated to use new API utilities.

The imports have been correctly updated to use React Query's mutation hook and the new API utilities.

Also applies to: 37-38


109-119: LGTM! Well-structured mutation setup with proper error handling.

The mutation is correctly implemented using React Query's useMutation hook with appropriate success and error handling. The implementation aligns with the past review comment's suggestion to add error handling.


121-123: LGTM! Simplified delete handler.

The handler has been correctly simplified to leverage the mutation hook's functionality.

src/components/Auth/ResetPassword.tsx (2)

1-18: LGTM! Clean import organization.

The imports are well-structured and the transition to React Query's hooks is clear.


88-95: LGTM! Direct mutation call.

The mutation call follows best practices by directly calling resetPassword(valid) instead of chaining.

src/components/Auth/ResetPassword.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/components/Users/UserAvatar.tsx (1)

68-80: 🛠️ Refactor suggestion

Refactor to use mutate's callback pattern.

Based on the previous review feedback, avoid using try-catch blocks and instead utilize mutate's onError/onSuccess callbacks for better error handling.

-const handleAvatarDelete = async (onError: () => void) => {
-  try {
-    await mutate(routes.deleteProfilePicture, {
-      pathParams: { username },
-    })(null);
-
-    queryClient.invalidateQueries({ queryKey: ["currentUser"] });
-    toast.success(t("profile_picture_deleted"));
-    setEditAvatar(false);
-  } catch (_error) {
-    onError();
-  }
-};
+const handleAvatarDelete = (onError: () => void) =>
+  mutate(
+    routes.deleteProfilePicture,
+    {
+      pathParams: { username },
+    },
+    {
+      onSuccess: () => {
+        queryClient.invalidateQueries({ queryKey: ["currentUser"] });
+        toast.success(t("profile_picture_deleted"));
+        setEditAvatar(false);
+      },
+      onError: (error) => {
+        console.error("Failed to delete avatar:", error);
+        onError();
+        toast.error(t("failed_to_delete_avatar"));
+      },
+    }
+  )(null);
🧹 Nitpick comments (2)
src/components/Facility/FacilityHome.tsx (2)

121-127: Consider adding return type annotations for clarity.

While the implementation is correct, adding return type annotations would improve type safety and documentation.

-  const handleDeleteSubmit = () => {
+  const handleDeleteSubmit = (): void => {
     deleteFacility();
   };

-  const handleDeleteClose = () => {
+  const handleDeleteClose = (): void => {
     setOpenDeleteDialog(false);
   };

158-172: Consider simplifying the mutate call.

The implementation is correct, but the empty object parameter could be omitted.

-      await mutate(routes.deleteFacilityCoverImage, {
-        pathParams: { id: facilityId },
-      })({});
+      await mutate(routes.deleteFacilityCoverImage, {
+        pathParams: { id: facilityId },
+      })(null);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e15a5f0 and a7ce09b.

📒 Files selected for processing (2)
  • src/components/Facility/FacilityHome.tsx (4 hunks)
  • src/components/Users/UserAvatar.tsx (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: cypress-run (1)
🔇 Additional comments (3)
src/components/Users/UserAvatar.tsx (1)

18-18: LGTM!

The import change aligns with the PR objective of replacing the deprecated request with mutate.

src/components/Facility/FacilityHome.tsx (2)

9-9: LGTM! Import changes align with modern React Query practices.

The addition of useMutation and mutate imports supports the transition from deprecated request handling to React Query's mutation capabilities.

Also applies to: 37-37


109-119: Well-implemented mutation with proper error handling!

The mutation implementation effectively addresses the previous review feedback by:

  • Using React Query's mutation capabilities
  • Including proper success and error handling
  • Providing user feedback through toast notifications

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/Providers/AuthUserProvider.tsx (1)

47-54: Improve token refresh query implementation.

Consider these improvements:

  1. The queryKey could be more specific to avoid potential conflicts
  2. The enabled condition can be simplified
 const tokenRefreshQuery = useQuery({
-  queryKey: ["user-refresh-token"],
+  queryKey: ["auth", "token-refresh"],
   queryFn: query(routes.token_refresh, {
     body: { refresh: refreshToken || "" },
   }),
   refetchInterval: careConfig.auth.tokenRefreshInterval,
-  enabled: !!refreshToken && !!user,
+  enabled: Boolean(refreshToken),
 });
src/components/Facility/FacilityHome.tsx (2)

109-119: Add loading state handling to facility deletion.

Consider handling the loading state to provide better user feedback during deletion.

-const { mutate: deleteFacility } = useMutation({
+const { mutate: deleteFacility, isPending: isDeleting } = useMutation({
   mutationFn: mutate(routes.deleteFacility, {
     pathParams: { id: facilityId },
   }),
   onSuccess: () => {
     toast.success(
       t("entity_deleted_successfully", { name: facilityData?.name }),
     );
     navigate("/facility");
   },
 });

Then use it in the ConfirmDialog:

 <ConfirmDialog
   title={t("delete_item", { name: facilityData?.name })}
   description={...}
   action="Delete"
   variant="destructive"
   show={openDeleteDialog}
   onClose={() => setOpenDeleteDialog(false)}
   onConfirm={() => deleteFacility()}
+  loading={isDeleting}
 />

121-132: Add error handling to avatar deletion mutation.

Consider adding error handling in the mutation to provide user feedback.

 const { mutateAsync: deleteAvatar } = useMutation({
   mutationFn: mutate(routes.deleteFacilityCoverImage, {
     pathParams: { id: facilityId },
   }),
   onSuccess: () => {
     toast.success(t("cover_image_deleted"));
     queryClient.invalidateQueries({
       queryKey: ["facility", facilityId],
     });
     setEditCoverImage(false);
   },
+  onError: () => {
+    toast.error(t("cover_image_delete_failed"));
+  },
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ba6ac9 and 390f51d.

📒 Files selected for processing (6)
  • public/locale/en.json (1 hunks)
  • src/Providers/AuthUserProvider.tsx (5 hunks)
  • src/Utils/request/api.tsx (3 hunks)
  • src/components/Auth/Login.tsx (4 hunks)
  • src/components/Facility/FacilityHome.tsx (5 hunks)
  • src/hooks/useAuthUser.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/Utils/request/api.tsx
  • src/components/Auth/Login.tsx
  • src/hooks/useAuthUser.ts
  • public/locale/en.json
🧰 Additional context used
📓 Learnings (1)
src/Providers/AuthUserProvider.tsx (1)
Learnt from: AdityaJ2305
PR: ohcnetwork/care_fe#10352
File: src/Providers/AuthUserProvider.tsx:47-63
Timestamp: 2025-02-04T12:39:49.688Z
Learning: The `onError` callback option was removed from `useQuery` in TanStack Query v5. Error handling should be done by checking the `error` state directly or using Error Boundaries.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: OSSAR-Scan
  • GitHub Check: cypress-run (1)
🔇 Additional comments (3)
src/Providers/AuthUserProvider.tsx (2)

56-68: LGTM!

The effect correctly handles both success and error cases for token refresh, following React Query v5 guidelines.


93-104: LGTM!

The sign-out implementation correctly handles token cleanup, state reset, and navigation.

src/components/Facility/FacilityHome.tsx (1)

162-168: LGTM!

The cover image deletion implementation correctly handles errors using try-catch.

src/Providers/AuthUserProvider.tsx Show resolved Hide resolved
Copy link

github-actions bot commented Feb 5, 2025

Conflicts have been detected against the base branch. Please merge the base branch into your branch.
cc: @AdityaJ2305

See: https://docs.ohc.network/docs/contributing#how-to-resolve-merge-conflicts

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Feb 5, 2025
@github-actions github-actions bot removed the merge conflict pull requests with merge conflict label Feb 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/Providers/AuthUserProvider.tsx (1)

47-68: Improve token refresh error handling and state updates.

The token refresh implementation could be optimized:

  1. Error handling should also clear the access token state
  2. Token updates could be batched to reduce re-renders

Apply this diff to improve the implementation:

 useEffect(() => {
   if (tokenRefreshQuery.isError) {
     localStorage.removeItem(LocalStorageKeys.accessToken);
     localStorage.removeItem(LocalStorageKeys.refreshToken);
+    setAccessToken(null);
     return;
   }

   if (tokenRefreshQuery.data) {
     const { access, refresh } = tokenRefreshQuery.data;
+    // Batch updates to reduce re-renders
+    Promise.resolve().then(() => {
       localStorage.setItem(LocalStorageKeys.accessToken, access);
       localStorage.setItem(LocalStorageKeys.refreshToken, refresh);
+      setAccessToken(access);
+    });
   }
 }, [tokenRefreshQuery.data, tokenRefreshQuery.isError]);
src/components/Facility/FacilityHome.tsx (1)

109-119: Consider handling loading states during mutations.

The mutations could benefit from showing loading indicators during the operation to improve user experience.

Consider using the mutation's isPending state:

 const { mutate: deleteFacility } = useMutation({
   mutationFn: mutate(routes.deleteFacility, {
     pathParams: { id: facilityId },
   }),
   onSuccess: () => {
     toast.success(
       t("entity_deleted_successfully", { name: facilityData?.name }),
     );
     navigate("/facility");
   },
 });
+
+// In the ConfirmDialog component:
+<ConfirmDialog
+  ...
+  loading={isPending}
+/>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c9adaf and 3487e9f.

📒 Files selected for processing (3)
  • src/Providers/AuthUserProvider.tsx (5 hunks)
  • src/Utils/request/api.tsx (3 hunks)
  • src/components/Facility/FacilityHome.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Utils/request/api.tsx
🧰 Additional context used
📓 Learnings (1)
src/Providers/AuthUserProvider.tsx (1)
Learnt from: AdityaJ2305
PR: ohcnetwork/care_fe#10352
File: src/Providers/AuthUserProvider.tsx:47-63
Timestamp: 2025-02-04T12:39:49.688Z
Learning: The `onError` callback option was removed from `useQuery` in TanStack Query v5. Error handling should be done by checking the `error` state directly or using Error Boundaries.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: OSSAR-Scan
  • GitHub Check: cypress-run (1)
🔇 Additional comments (6)
src/Providers/AuthUserProvider.tsx (3)

2-2: LGTM! Import changes align with TanStack Query migration.

The addition of TanStack Query hooks and JWT token type improves type safety and modernizes the request handling.

Also applies to: 12-12


70-82: Add error handling to sign-in mutation.

The previous review comment about adding error handling to the sign-in mutation is still valid. Please add error handling to provide feedback to users when sign-in fails.


147-160: LGTM! Context value and rendering improvements.

The addition of isAuthenticating to the context value and simplified rendering logic enhance the component's usability.

src/components/Facility/FacilityHome.tsx (3)

9-9: LGTM! Import changes align with React Query migration.

The addition of useMutation and mutate imports supports the migration away from the deprecated request module.

Also applies to: 37-37


162-168: LGTM! Error handling maintained with mutation.

The handleCoverImageDelete function correctly uses the new mutation while preserving the error handling callback.


197-198: LGTM! Simplified dialog handlers.

The dialog handlers have been streamlined by directly using the state setter and mutation.

src/components/Facility/FacilityHome.tsx Show resolved Hide resolved
@nihal467
Copy link
Member

nihal467 commented Feb 6, 2025

image

  • Upon successful upload of the profile image, the profile is not auto-refreshing the state to view the latest modified profile

image

  • wrong otp error/success notification in patient appointment booking workflow via public page are not working

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/components/Users/UserAvatar.tsx (1)

55-83: Migrate avatar upload to React Query mutation.

The current implementation uses a direct file upload utility while the rest of the component uses React Query. For consistency, consider migrating this to a React Query mutation as well.

-const handleAvatarUpload = async (file: File, onError: () => void) => {
+const { mutate: mutateAvatarUpload } = useMutation({
+  mutationFn: async (file: File) => {
     const formData = new FormData();
     formData.append("profile_picture", file);
     const url = `${careConfig.apiUrl}/api/v1/users/${userData.username}/profile_picture/`;
-    await uploadFile(
+    return uploadFile(
       url,
       formData,
       "POST",
-      { Authorization: getAuthorizationHeader() },
-      async (xhr: XMLHttpRequest) => {
-        if (xhr.status === 200) {
-          await sleep(1000);
-          queryClient.invalidateQueries({
-            queryKey: ["getUserDetails", username],
-          });
-          if (authUser.username === username) {
-            queryClient.invalidateQueries({ queryKey: ["currentUser"] });
-          }
-          toast.success(t("avatar_updated_success"));
-          setEditAvatar(false);
-        }
-      },
-      null,
-      () => {
-        onError();
-      },
+      { Authorization: getAuthorizationHeader() }
     );
-  };
+  },
+  onSuccess: async () => {
+    await sleep(1000);
+    queryClient.invalidateQueries({
+      queryKey: ["getUserDetails", username],
+    });
+    if (authUser.username === username) {
+      queryClient.invalidateQueries({ queryKey: ["currentUser"] });
+    }
+    toast.success(t("avatar_updated_success"));
+    setEditAvatar(false);
+  },
+  onError: (error) => {
+    console.error('Failed to upload avatar:', error);
+    toast.error(t("failed_to_upload_avatar"));
+  },
+});
+
+const handleAvatarUpload = (file: File, onError: () => void) => {
+  mutateAvatarUpload(file, { onError });
+};
♻️ Duplicate comments (1)
src/components/Users/UserAvatar.tsx (1)

85-91: 🛠️ Refactor suggestion

Remove unnecessary try-catch block.

The error handling should be handled in the mutation configuration, making the try-catch block redundant.

-const handleAvatarDelete = async (onError: () => void) => {
+const handleAvatarDelete = (onError: () => void) => {
-  try {
-    mutateAvatarDelete();
-  } catch {
-    onError();
-  }
+  mutateAvatarDelete(undefined, { onError });
 };
🧹 Nitpick comments (1)
src/components/Users/UserAvatar.tsx (1)

30-42: Add error handling and loading state to mutation hook.

While the mutation implementation is good, it could be enhanced with error handling and loading state management.

 const { mutate: mutateAvatarDelete } = useMutation({
   mutationFn: mutate(routes.deleteProfilePicture, {
     pathParams: { username },
   }),
+  onError: (error) => {
+    console.error('Failed to delete avatar:', error);
+    toast.error(t("failed_to_delete_avatar"));
+  },
   onSuccess: () => {
     queryClient.invalidateQueries({ queryKey: ["getUserDetails", username] });
     if (authUser.username === username) {
       queryClient.invalidateQueries({ queryKey: ["currentUser"] });
     }
     toast.success(t("profile_picture_deleted"));
     setEditAvatar(false);
   },
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3487e9f and 30f8c2b.

📒 Files selected for processing (3)
  • src/Utils/request/api.tsx (4 hunks)
  • src/components/Users/UserAvatar.tsx (5 hunks)
  • src/pages/PublicAppointments/auth/PatientLogin.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Utils/request/api.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: cypress-run (1)
🔇 Additional comments (6)
src/components/Users/UserAvatar.tsx (2)

2-2: LGTM! Import changes align with React Query migration.

The addition of useMutation and mutate imports supports the transition from direct API calls to React Query mutations.

Also applies to: 18-18


44-49: LGTM! Query hook implementation is correct.

The query hook is properly configured with the required path parameters.

src/pages/PublicAppointments/auth/PatientLogin.tsx (4)

84-91: LGTM!

The phone number validation and API call format are correctly implemented.


213-218: LGTM!

The resend OTP implementation is consistent with the send OTP changes and maintains good user experience.


75-82: 🛠️ Refactor suggestion

Add error handling for OTP sending failures.

While removing onError aligns with past review comments, consider adding error handling through a toast notification or error state to provide feedback to users when OTP sending fails.

  const { mutate: sendOTP, isPending: isSendOTPLoading } = useMutation({
    mutationFn: mutate(routes.otp.sendOtp),
+   onError: (error) => {
+     toast.error(t("failed_to_send_otp"));
+   },
    onSuccess: () => {
      if (page === "send") {
        navigate(`/facility/${facilityId}/appointments/${staffId}/otp/verify`);
      }
    },
  });

93-108: Add error handling for OTP verification failures.

Consider adding error handling to provide feedback when OTP verification fails.

  const { mutate: verifyOTP, isPending: isVerifyOTPLoading } = useMutation({
    mutationFn: mutate(routes.otp.loginByOtp),
+   onError: (error) => {
+     toast.error(t("invalid_otp"));
+   },
    onSuccess: (response: { access: string }) => {
      if (response.access) {
        const tokenData: TokenData = {
          token: response.access,
          phoneNumber: phoneNumber,
          createdAt: new Date().toISOString(),
        };
        patientLogin(
          tokenData,
          `/facility/${facilityId}/appointments/${staffId}/book-appointment`,
        );
      }
    },
  });
✅ Verification successful

Error Handling Missing in OTP Verification Mutation

  • The OTP verification mutation in src/pages/PublicAppointments/auth/PatientLogin.tsx (lines 93-108) lacks an onError callback to handle OTP verification failures.
  • Adding an onError callback—similar to the suggestion below—will ensure that users receive feedback when an error occurs:
  const { mutate: verifyOTP, isPending: isVerifyOTPLoading } = useMutation({
    mutationFn: mutate(routes.otp.loginByOtp),
+   onError: (error) => {
+     toast.error(t("invalid_otp"));
+   },
    onSuccess: (response: { access: string }) => {
      if (response.access) {
        const tokenData: TokenData = {
          token: response.access,
          phoneNumber: phoneNumber,
          createdAt: new Date().toISOString(),
        };
        patientLogin(
          tokenData,
          `/facility/${facilityId}/appointments/${staffId}/book-appointment`,
        );
      }
    },
  });

@nihal467
Copy link
Member

nihal467 commented Feb 6, 2025

LGTM

@nihal467
Copy link
Member

nihal467 commented Feb 6, 2025

non related cypress failure

@nihal467 nihal467 added tested reviewed reviewed by a core member and removed needs testing labels Feb 6, 2025
@rithviknishad rithviknishad merged commit e326a78 into ohcnetwork:develop Feb 6, 2025
11 of 13 checks passed
Copy link

github-actions bot commented Feb 6, 2025

@AdityaJ2305 Your efforts have helped advance digital healthcare and TeleICU systems. 🚀 Thank you for taking the time out to make CARE better. We hope you continue to innovate and contribute; your impact is immense! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reviewed reviewed by a core member tested
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants