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

Improvements in CreateUserForm #9887

Open
wants to merge 33 commits into
base: develop
Choose a base branch
from

Conversation

rajku-dev
Copy link
Contributor

@rajku-dev rajku-dev commented Jan 10, 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

Release Notes

  • New Features

    • Enhanced form validation with detailed error messages for user registration.
    • Added more gender options in user profile.
    • Improved date picker with advanced date selection controls.
    • New optional property for disabling specific dates in the date picker.
  • Localization

    • Added comprehensive validation messages for date of birth and phone number.
  • User Experience

    • More robust input validation for required fields.
    • Real-time form validation feedback.
    • Loading state indicators during form submission.
    • Enhanced error handling and success notifications in the user creation form.

@rajku-dev rajku-dev requested a review from a team as a code owner January 10, 2025 17:01
Copy link
Contributor

coderabbitai bot commented Jan 10, 2025

Walkthrough

This pull request introduces comprehensive improvements to user form validation and localization. The changes span multiple files, focusing on enhancing the user registration process by adding detailed validation rules for dates of birth and phone numbers. The modifications include updating the localization JSON file with new validation messages, refactoring the user creation form to utilize the useMutation hook for better error handling, and extending the date picker component to support date restrictions.

Changes

File Change Summary
public/locale/en.json Added validation message keys for date of birth and phone number
src/components/Users/CreateUserForm.tsx Updated form validation using Zod, added useMutation hook, enhanced error handling and user experience
src/components/ui/date-picker.tsx Added optional disabled prop to support date restrictions
src/types/user/user.ts Introduced new UserCreateRequest type with comprehensive user creation fields
src/types/user/userApi.ts Updated API request type to use new UserCreateRequest type

Assessment against linked issues

Objective Addressed Explanation
Date of Birth cannot be in future
Phone number limited to 10 digits after +91
Submit button disabled for unchanged forms Partial implementation, needs further review
Required fields marked with red asterisk Not implemented in this PR

Suggested labels

changes required

Suggested reviewers

  • Jacobjeevan
  • rithviknishad

Possibly related PRs

Poem

🐰 A rabbit's tale of form delight,
Validation dancing, errors take flight!
Usernames trimmed, dates checked with care,
No future birthdays shall slip through there.
Code hops along, clean and bright! 🌟


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 150f8aa and c6d5598.

📒 Files selected for processing (1)
  • public/locale/en.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • public/locale/en.json
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: OSSAR-Scan
  • GitHub Check: cypress-run (1)
  • GitHub Check: CodeQL-Build

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 Jan 10, 2025

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit c6d5598
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/67898394726f520008db216f
😎 Deploy Preview https://deploy-preview-9887--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.

@rajku-dev
Copy link
Contributor Author

@Jacobjeevan please review the changes , last pr was closed due to so many merge conflicts

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

🧹 Nitpick comments (7)
src/types/user/user.ts (1)

18-33: Consider using string type for dates in API requests.

While using Date type for date_of_birth works well in the frontend, it might be better to use string type since API requests typically serialize dates to strings. This would make the type definition more aligned with the actual API contract.

-  date_of_birth: Date;
+  date_of_birth: string;
src/components/ui/date-picker.tsx (1)

19-19: Add JSDoc comments for better documentation.

The disabled prop is a powerful feature but could benefit from documentation explaining its usage and providing examples.

 interface DatePickerProps {
   date?: Date;
   onChange?: (date?: Date) => void;
+  /**
+   * Function to determine if a date should be disabled
+   * @param date The date to check
+   * @returns true if the date should be disabled, false otherwise
+   * @example
+   * // Disable future dates
+   * disabled={(date) => date > new Date()}
+   */
   disabled?: (date: Date) => boolean;
 }

Also applies to: 22-22, 48-48

src/components/Users/CreateUserForm.tsx (3)

175-188: Consider adding retry logic for API calls.

The mutation setup looks good, but consider adding retry logic for transient failures:

 const { mutate: createUser, isPending } = useMutation({
   mutationFn: mutate(UserApi.create),
+  retry: (failureCount, error) => {
+    return failureCount < 3 && error.status >= 500;
+  },
   onSuccess: (user: UserBase) => {

342-347: Add input pattern for phone number validation.

Consider adding the pattern attribute to reinforce the phone number format on the client side.

 <Input
   type="tel"
   placeholder="+91XXXXXXXXXX"
   maxLength={13}
+  pattern="^\+91[0-9]{10}$"
   {...field}
 />

402-408: Consider extracting date constraints to constants.

The date validation logic is duplicated between the Zod schema and the DatePicker component. Consider extracting these constraints to constants.

+const DATE_CONSTRAINTS = {
+  MIN_DATE: new Date("1900-01-01"),
+  MAX_DATE: new Date(),
+} as const;
+
 <DatePicker
   date={field.value}
   onChange={(date) => field.onChange(date)}
   disabled={(date) =>
-    date > new Date() || date < new Date("1900-01-01")
+    date > DATE_CONSTRAINTS.MAX_DATE || date < DATE_CONSTRAINTS.MIN_DATE
   }
 />
public/locale/en.json (2)

1495-1495: Consider enhancing the phone number validation message.

While the message is clear, it could be more user-friendly by providing an example format.

-  "phone_number_must_start": "Phone number must start with +91 followed by 10 digits",
+  "phone_number_must_start": "Phone number must start with +91 followed by 10 digits (e.g., +911234567890)",

1999-2004: Consider consolidating username validation messages.

The current implementation has separate messages for each username validation rule. Consider combining them into a single, comprehensive message to improve user experience.

-  "username_consecutive_special_characters": "Username can't contain consecutive special characters",
-  "username_contain_lowercase_special": "Username can only contain lowercase letters, numbers, and . _ -",
-  "username_less_than": "Username must be less than 16 characters",
-  "username_more_than": "Username must be at least 4 characters",
-  "username_start_end_letter_number": "Username must start and end with a letter or number",
+  "username_requirements": "Username must: be 4-16 characters long, contain only lowercase letters, numbers, and . _ -, start and end with a letter or number, and not have consecutive special characters",

This consolidation would:

  1. Reduce cognitive load by presenting all rules at once
  2. Make it easier for users to create a valid username on their first try
  3. Reduce the number of validation cycles needed
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 86eba9b and 63b9679.

📒 Files selected for processing (5)
  • public/locale/en.json (4 hunks)
  • src/components/Users/CreateUserForm.tsx (14 hunks)
  • src/components/ui/date-picker.tsx (2 hunks)
  • src/types/user/user.ts (1 hunks)
  • src/types/user/userApi.ts (2 hunks)
🔇 Additional comments (5)
src/types/user/userApi.ts (1)

3-3: LGTM! Type safety improvement.

The change from UserBase to UserCreateRequest for the create method's request body type improves type safety by using a more specific type for user creation.

Also applies to: 15-15

src/components/Users/CreateUserForm.tsx (2)

51-111: Strong validation schema with i18n support.

The Zod schema implementation is thorough and well-structured, with proper internationalization of error messages.


517-525: LGTM! Good UX with loading state.

The submit button implementation is well done with:

  • Proper disable conditions
  • Loading indicator
  • Internationalized text
public/locale/en.json (2)

699-699: LGTM! Clear and concise validation message.

The validation message for date of birth is straightforward and effectively communicates the constraint to users.


1875-1875: LGTM! Standard required field message.

The message follows the common pattern for required field validation.

Copy link

👋 Hi, @rajku-dev,
Conflicts have been detected against the base branch. Please rebase your branch against the base branch.


This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there.

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Jan 11, 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 (4)
src/components/Users/CreateUserForm.tsx (4)

76-77: Consider making phone number validation more flexible.

The phone number validation is currently hardcoded to accept only Indian numbers (+91). Consider making this more flexible to support international phone numbers or configurable based on the deployment region.

-        .regex(/^\+91[0-9]{10}$/, t("phone_number_must_start")),
+        .regex(/^\+[1-9]\d{1,14}$/, t("invalid_phone_number")),

Also applies to: 80-84


186-199: Enhance error handling in mutation.

The error handling could be more robust:

  1. Consider adding a generic error message for unexpected error types
  2. Add type safety for error.cause
   onError: (error) => {
-      const errors = (error.cause?.errors as any[]) || [];
+      if (!error.cause?.errors || !Array.isArray(error.cause.errors)) {
+        toast.error(t("unexpected_error"));
+        return;
+      }
+      const errors = error.cause.errors as Array<{
+        loc: string[];
+        ctx: { error: string };
+      }>;
       errors.forEach((err) => {
         const field = err.loc[0];
         form.setError(field, { message: err.ctx.error });
       });
   },

408-414: Enhance DatePicker accessibility.

The DatePicker component should include aria-label and proper date format announcement.

   <DatePicker
     date={field.value}
     onChange={(date) => field.onChange(date)}
+    aria-label={t("date_of_birth")}
     disabled={(date) =>
       date > new Date() || date < new Date("1900-01-01")
     }
   />

523-531: Improve submit button feedback.

The button could provide more specific feedback about what's preventing submission.

   <Button
     type="submit"
     className="w-full"
     disabled={
       !form.formState.isDirty || !form.formState.isValid || isPending
     }
+    title={
+      !form.formState.isDirty
+        ? t("no_changes_made")
+        : !form.formState.isValid
+        ? t("please_fix_form_errors")
+        : ""
+    }
   >
     {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
-    {t("create")}
+    {t(isPending ? "creating" : "create")}
   </Button>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 63b9679 and ca7e588.

📒 Files selected for processing (2)
  • public/locale/en.json (3 hunks)
  • src/components/Users/CreateUserForm.tsx (16 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • public/locale/en.json
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: CodeQL-Build
  • GitHub Check: cypress-run (1)
  • GitHub Check: OSSAR-Scan
🔇 Additional comments (2)
src/components/Users/CreateUserForm.tsx (2)

Line range hint 1-534: Overall implementation looks solid! 👍

The form implementation is well-structured with proper validation, error handling, and user feedback. The use of react-query for mutations and zod for validation provides a robust foundation.


87-93: Review date validation range.

The date validation allows dates from 1900, which might need adjustment based on business requirements. Also, consider adding a minimum age requirement.

src/components/Users/CreateUserForm.tsx Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the merge conflict pull requests with merge conflict label Jan 11, 2025
Copy link
Member

@rithviknishad rithviknishad left a comment

Choose a reason for hiding this comment

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

do a self test; the button is disabled even after filling all the fields, nor are there any errors shown in the form.

image

src/types/user/user.ts Outdated Show resolved Hide resolved
src/components/Users/CreateUserForm.tsx Outdated Show resolved Hide resolved
@rithviknishad rithviknishad added the invalid This doesn't seem right label Jan 11, 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

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

Line range hint 117-125: Adjust phone number default value to match validation pattern.

The default value "+91" for phone numbers doesn't match the validation pattern /^\+91[0-9]{10}$/. This could cause initial validation errors. Consider either:

  1. Removing the default value, or
  2. Setting it to an empty string
🧹 Nitpick comments (1)
src/components/Users/CreateUserForm.tsx (1)

192-198: Improve type safety in error handling.

The error handling code makes assumptions about the error structure without proper type checking. Consider:

  1. Adding proper type definitions for the error response
  2. Adding null checks before accessing error properties
- const errors = (error.cause?.errors as any[]) || [];
+ type ApiError = { loc: string[]; ctx: { error: string } };
+ const errors = ((error.cause?.errors as ApiError[]) || [])
+   .filter((err): err is ApiError => 
+     Array.isArray(err?.loc) && typeof err?.ctx?.error === 'string'
+   );
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ca7e588 and c8d3420.

📒 Files selected for processing (2)
  • src/components/Users/CreateUserForm.tsx (16 hunks)
  • src/types/user/user.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/types/user/user.ts
🔇 Additional comments (2)
src/components/Users/CreateUserForm.tsx (2)

94-94: Use GENDER_TYPES constant for schema validation.

The gender validation is hardcoded in the schema while the UI uses the GENDER_TYPES constant, which could lead to inconsistencies if the gender types are updated.


523-531: LGTM! Well-implemented submit button.

The submit button implementation includes:

  • Proper loading state with spinner
  • Correct disable conditions based on form state
  • Clear visual feedback

src/components/Users/CreateUserForm.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: 1

♻️ Duplicate comments (2)
src/components/Users/CreateUserForm.tsx (2)

86-92: ⚠️ Potential issue

Fix date of birth validation issues.

The current date validation has several problems:

  1. Using string type instead of Date
  2. Incorrect date comparison
  3. Missing minimum date validation

As noted in previous feedback, also consider improving the date selection UX. Apply this fix:

  date_of_birth: z
-   .string({
+   .date({
      required_error: t("this_field_is_required"),
    })
+   .min(new Date("1900-01-01"), t("date_too_far_in_past"))
-   .refine((dob) => dob <= new Date().toISOString(), {
+   .max(new Date(), {
      message: t("date_of_birth_cannot_be_in_future"),
    }),

93-93: ⚠️ Potential issue

Use GENDER_TYPES constant for schema validation.

The gender enum is hardcoded in the schema while GENDER_TYPES constant is used in the UI. This could lead to inconsistencies.

- gender: z.enum(["male", "female", "transgender", "non_binary"]),
+ gender: z.enum(GENDER_TYPES.map(g => g.id)),
🧹 Nitpick comments (1)
src/components/Users/CreateUserForm.tsx (1)

74-84: Make phone number validation more flexible.

The current validation is hardcoded for Indian numbers (+91). Consider making it more flexible for international usage.

+ const PHONE_REGEX = {
+   IN: /^\+91[0-9]{10}$/,
+   // Add more country patterns
+ };

  phone_number: z
    .string()
-   .regex(/^\+91[0-9]{10}$/, t("phone_number_must_start")),
+   .regex(PHONE_REGEX.IN, t("invalid_phone_number_format")),

  alt_phone_number: z
    .string()
    .refine(
-     (val) => val === "" || /^\+91[0-9]{10}$/.test(val),
+     (val) => val === "" || PHONE_REGEX.IN.test(val),
-     t("phone_number_must_start"),
+     t("invalid_phone_number_format"),
    )
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c8d3420 and cf3a717.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (15 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Redirect rules - care-ohc
  • GitHub Check: Header rules - care-ohc
  • GitHub Check: Pages changed - care-ohc
  • GitHub Check: cypress-run (1)
  • GitHub Check: CodeQL-Build
  • GitHub Check: OSSAR-Scan
🔇 Additional comments (2)
src/components/Users/CreateUserForm.tsx (2)

200-217: Well implemented form submission!

Great job on:

  1. Type-safe form submission using z.infer
  2. Proper loading state with spinner
  3. Button disabled state based on form validity

Also applies to: 516-524


347-352: Well structured phone input implementation!

Good practices implemented:

  1. Correct input type="tel"
  2. Appropriate maxLength matching the format
  3. Clear placeholder showing expected format

src/components/Users/CreateUserForm.tsx 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

🧹 Nitpick comments (3)
src/components/Users/CreateUserForm.tsx (3)

75-76: Consider making phone number prefix configurable.

The phone number validation is hardcoded for Indian numbers (+91). Consider making this configurable to support international phone numbers.

+ const PHONE_NUMBER_REGEX = process.env.REACT_APP_PHONE_REGEX || /^\+91[0-9]{10}$/;
  phone_number: z
    .string()
-   .regex(/^\+91[0-9]{10}$/, t("phone_number_must_start")),
+   .regex(PHONE_NUMBER_REGEX, t("phone_number_must_start")),

141-147: Move password match validation to schema.

The password match validation in useEffect should be moved to the schema for consistency and to avoid maintaining validation logic in multiple places.

The schema already has this validation. Remove the duplicate validation from useEffect:

- if (password?.length && c_password?.length && password !== c_password) {
-   form.setError("c_password", { message: t("password_mismatch") });
-   form.setError("password", { message: t("password_mismatch") });
- } else {
-   form.clearErrors("c_password");
-   form.clearErrors("password");
- }

356-361: Enhance phone number input UX.

Consider using a phone number input component with formatting and validation:

  1. Use a phone input library like react-phone-number-input
  2. Add proper formatting as user types
  3. Show country selection dropdown

Example implementation:

- <Input
-   type="tel"
-   placeholder="+91XXXXXXXXXX"
-   maxLength={13}
-   {...field}
- />
+ <PhoneInput
+   international
+   defaultCountry="IN"
+   placeholder="Enter phone number"
+   value={field.value}
+   onChange={field.onChange}
+ />
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cf3a717 and 55c0457.

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

93-93: Use GENDER_TYPES constant for schema validation.

The gender enum is hardcoded in the schema while GENDER_TYPES constant is used in the UI. This could lead to inconsistencies.

- gender: z.enum(["male", "female", "transgender", "non_binary"]),
+ gender: z.enum(GENDER_TYPES.map(g => g.id)),

200-206: Improve error handling in mutation setup.

The error handling could be more robust:

  1. The type assertion as any[] in error handling is unsafe
  2. No fallback error message when errors array is empty
  onError: (error) => {
-   const errors = (error.cause?.errors as any[]) || [];
+   const errors = Array.isArray(error.cause?.errors) ? error.cause.errors : [];
    errors.forEach((err) => {
      const field = err.loc[0];
      form.setError(field, { message: err.ctx.error });
    });
+   if (errors.length === 0) {
+     toast.error(t("something_went_wrong"));
+   }
  },

525-533: LGTM! Good UX improvements.

The submit button implementation looks good:

  1. Proper disable conditions based on form state
  2. Loading indicator during submission
  3. Translated button text

@rajku-dev
Copy link
Contributor Author

rajku-dev commented Jan 12, 2025

do a self test; the button is disabled even after filling all the fields, nor are there any errors shown in the form.

it was due to .refine not running on password onChange,
moved the form setting logic inside existing useEffect
All edge cases have been handled, please review.

sol.mp4

@rithviknishad
Copy link
Member

rithviknishad commented Jan 12, 2025

let's not move it to useEffect. let's stick with refine itself. however, refine would get triggered when form is attempted to submit right? so what's the issue? why was the button disabled in the first place which prevented submitting it?

@rithviknishad rithviknishad added changes required and removed invalid This doesn't seem right labels Jan 12, 2025
@rajku-dev
Copy link
Contributor Author

rajku-dev commented Jan 12, 2025

let's not move it to useEffect. let's stick with refine itself. however, refine would get triggered when form is attempted to submit right? so what's the issue? why was the button disabled in the first place which prevented submitting it?
image

issue.mp4

.refine is not triggering on changing the password fields, so i had to apply the hack

@AdityaJ2305
Copy link
Contributor

refine would get triggered when form is attempted to submit right ?

@rajku-dev, I think you missed this line from rithvik's comment

@rajku-dev
Copy link
Contributor Author

rajku-dev commented Jan 13, 2025

refine would get triggered when form is attempted to submit right ?

@rajku-dev, I think you missed this line from rithvik's comment

The problem is, password has mismatch error that makes the submit button disable(since we are doing invalid check), but not showing under input field
I have demonstrated in video please look carefully, that explains everything

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 48550cf and e5c2521.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (17 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Users/CreateUserForm.tsx (3)
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:153-159
Timestamp: 2025-01-14T09:56:07.985Z
Learning: In react-hook-form, form.formState.isValid being false with an empty form.formState.errors object typically indicates that either not all required fields are filled, some fields haven't been "touched", or there's pending async validation. The errors object only contains validation errors for fields that have been validated.
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:93-93
Timestamp: 2025-01-14T09:22:13.878Z
Learning: The suggestion to use GENDER_TYPES.map(g => g.id) for gender enum validation in CreateUserForm.tsx was incorrect and caused an error.
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:93-93
Timestamp: 2025-01-14T09:22:13.878Z
Learning: In CreateUserForm.tsx, the gender validation schema uses string literals that match GENDER_TYPES.map(g => g.id). Using GENDER_TYPES directly with z.enum() fails because it's marked with 'as const' which makes it a readonly tuple type incompatible with Zod's enum.
🪛 eslint
src/components/Users/CreateUserForm.tsx

[error] 581-581: Replace <Loader2·className="mr-2·h-4·w-4·animate-spin"·data-cy="submit-user-form"·/> with (⏎············<Loader2⏎··············className="mr-2·h-4·w-4·animate-spin"⏎··············data-cy="submit-user-form"⏎············/>⏎··········)

(prettier/prettier)

🪛 GitHub Check: lint
src/components/Users/CreateUserForm.tsx

[failure] 581-581:
Replace <Loader2·className="mr-2·h-4·w-4·animate-spin"·data-cy="submit-user-form"·/> with (⏎············<Loader2⏎··············className="mr-2·h-4·w-4·animate-spin"⏎··············data-cy="submit-user-form"⏎············/>⏎··········)

🪛 GitHub Actions: Lint Code Base
src/components/Users/CreateUserForm.tsx

[error] 581-581: Formatting error: Loader2 component needs to be properly formatted across multiple lines according to prettier rules

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: cypress-run (1)
🔇 Additional comments (3)
src/components/Users/CreateUserForm.tsx (3)

221-238: Verify API contract for user creation.

The submission logic looks good, but let's verify that all required fields are being sent correctly to the backend.

Run this script to check the API contract:

✅ Verification successful

API contract verification successful

The form submission matches the UserCreateRequest type definition exactly, with all required fields being sent and optional fields properly handled.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the API contract for user creation
# Search for UserCreateRequest type definition and API usage

# Find UserCreateRequest type definition
echo "=== UserCreateRequest Type Definition ==="
ast-grep --pattern 'type UserCreateRequest = {
  $$$
}'

# Find API usage patterns
echo -e "\n=== API Usage Patterns ==="
rg -A 5 'UserApi.create'

Length of output: 1523


153-159: 🛠️ Refactor suggestion

Remove duplicate password validation from useEffect.

The password validation logic is duplicated between the schema and useEffect hook. The schema already handles this validation with .refine(), making this useEffect unnecessary and potentially causing race conditions.

Remove the password validation from useEffect as it's already handled by the schema:

-    if (password?.length && c_password?.length && password !== c_password) {
-      form.setError("c_password", { message: t("password_mismatch") });
-      form.setError("password", { message: t("password_mismatch") });
-    } else {
-      form.clearErrors("c_password");
-      form.clearErrors("password");
-    }

Likely invalid or redundant comment.


206-219: 🛠️ Refactor suggestion

Improve mutation error handling robustness.

The current error handling has two issues:

  1. Unsafe type assertion with as any[]
  2. No fallback error message when the errors array is empty

Apply these improvements:

   onError: (error) => {
-    const errors = (error.cause?.errors as any[]) || [];
+    const errors = Array.isArray(error.cause?.errors) ? error.cause.errors : [];
     errors.forEach((err) => {
       const field = err.loc[0];
-      form.setError(field, { message: err.ctx?.error || err.msg });
+      form.setError(field, { message: err.ctx?.error || err.msg || t("unknown_error") });
     });
+    if (errors.length === 0) {
+      toast.error(t("something_went_wrong"));
+    }
   },

Likely invalid or redundant comment.

src/components/Users/CreateUserForm.tsx Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the merge conflict pull requests with merge conflict label Jan 15, 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/components/Users/CreateUserForm.tsx (2)

86-100: Enhance date validation error message.

The error message doesn't accurately reflect both minimum and maximum date constraints.

         .refine(
           (dob) => {
             const date = new Date(dob);
+            if (isNaN(date.getTime())) return false;
             const minDate = new Date();
             minDate.setFullYear(minDate.getFullYear() - 120);
             return minDate <= date && date <= new Date();
           },
           {
-            message: t("date_of_birth_cannot_be_in_future"),
+            message: t("invalid_date_of_birth"),
           },
         ),

206-219: Improve error handling in mutation setup.

The error handling could be more robust:

  1. The type assertion as any[] is unsafe
  2. No fallback error message when errors array is empty
  onError: (error) => {
-   const errors = (error.cause?.errors as any[]) || [];
+   const errors = Array.isArray(error.cause?.errors) ? error.cause.errors : [];
    errors.forEach((err) => {
      const field = err.loc[0];
-     form.setError(field, { message: err.ctx?.error || err.msg });
+     form.setError(field, { message: err.ctx?.error || err.msg || t("unknown_error") });
    });
+   if (errors.length === 0) {
+     toast.error(t("something_went_wrong"));
+   }
  },
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e5c2521 and 068798f.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (17 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Users/CreateUserForm.tsx (3)
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:153-159
Timestamp: 2025-01-14T09:56:07.985Z
Learning: In react-hook-form, form.formState.isValid being false with an empty form.formState.errors object typically indicates that either not all required fields are filled, some fields haven't been "touched", or there's pending async validation. The errors object only contains validation errors for fields that have been validated.
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:93-93
Timestamp: 2025-01-14T09:22:13.878Z
Learning: The suggestion to use GENDER_TYPES.map(g => g.id) for gender enum validation in CreateUserForm.tsx was incorrect and caused an error.
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:93-93
Timestamp: 2025-01-14T09:22:13.878Z
Learning: In CreateUserForm.tsx, the gender validation schema uses string literals that match GENDER_TYPES.map(g => g.id). Using GENDER_TYPES directly with z.enum() fails because it's marked with 'as const' which makes it a readonly tuple type incompatible with Zod's enum.
🔇 Additional comments (5)
src/components/Users/CreateUserForm.tsx (5)

3-4: LGTM! Good choice of dependencies.

The addition of useMutation and Loader2 components improves API handling and user feedback.


73-76: LGTM! Improved validation messages.

The email and phone number validation messages are now more descriptive and user-friendly.


Line range hint 128-144: LGTM! Improved form configuration.

The "onChange" mode provides better real-time feedback, and default values improve UX.


221-238: LGTM! Clean and type-safe implementation.

The submission handler correctly maps form data to the API request structure.


574-583: 🛠️ Refactor suggestion

Fix button formatting according to prettier rules.

The Loader2 component needs to be properly formatted across multiple lines.

         <Button
           type="submit"
           className="w-full"
           disabled={
             !form.formState.isDirty || !form.formState.isValid || isPending
           }
         >
-          {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}{" "}
+          {isPending && (
+            <Loader2
+              className="mr-2 h-4 w-4 animate-spin"
+              data-cy="submit-user-form"
+            />
+          )}{" "}
           {t("create")}
         </Button>

Likely invalid or redundant comment.

src/components/Users/CreateUserForm.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: 1

🧹 Nitpick comments (2)
src/components/Users/CreateUserForm.tsx (2)

76-83: Improve phone number validation robustness.

The current validation:

  1. Only supports Indian numbers (+91)
  2. Doesn't validate the actual phone number format beyond length

Consider using a more comprehensive validation:

       phone_number: z
         .string()
-        .regex(/^\+91[0-9]{10}$/, t("phone_number_must_start")),
+        .regex(/^\+91[1-9][0-9]{9}$/, t("phone_number_must_start")),

101-105: Improve type safety of gender validation.

The current implementation uses a type assertion. Consider using a const assertion instead:

-      gender: z.enum(
-        GENDER_TYPES.map((gender) => gender.id) as [
-          (typeof GENDER_TYPES)[number]["id"],
-        ],
-      ),
+      gender: z.enum(
+        GENDER_TYPES.map((gender) => gender.id) as const,
+      ),
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ab23bb7 and c3f010d.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (14 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Users/CreateUserForm.tsx (3)
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:153-159
Timestamp: 2025-01-14T09:56:07.985Z
Learning: In react-hook-form, form.formState.isValid being false with an empty form.formState.errors object typically indicates that either not all required fields are filled, some fields haven't been "touched", or there's pending async validation. The errors object only contains validation errors for fields that have been validated.
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:93-93
Timestamp: 2025-01-14T09:22:13.878Z
Learning: The suggestion to use GENDER_TYPES.map(g => g.id) for gender enum validation in CreateUserForm.tsx was incorrect and caused an error.
Learnt from: rajku-dev
PR: ohcnetwork/care_fe#9887
File: src/components/Users/CreateUserForm.tsx:93-93
Timestamp: 2025-01-14T09:22:13.878Z
Learning: In CreateUserForm.tsx, the gender validation schema uses string literals that match GENDER_TYPES.map(g => g.id). Using GENDER_TYPES directly with z.enum() fails because it's marked with 'as const' which makes it a readonly tuple type incompatible with Zod's enum.
🔇 Additional comments (4)
src/components/Users/CreateUserForm.tsx (4)

3-4: LGTM!

The new imports support the mutation-based API calls and loading indicator.


210-227: LGTM!

The form submission logic is well-structured and type-safe.


563-570: ⚠️ Potential issue

Fix Loader2 component formatting.

The component needs to be properly formatted according to prettier rules.

         <Button
           type="submit"
           className="w-full"
           data-cy="submit-user-form"
           disabled={!form.formState.isDirty || isPending}
         >
-          {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}{" "}
+          {isPending && (
+            <Loader2
+              className="mr-2 h-4 w-4 animate-spin"
+              data-cy="submit-user-form"
+            />
+          )}{" "}
           {t("create_user")}
         </Button>

Likely invalid or redundant comment.


195-208: 🛠️ Refactor suggestion

Improve error handling robustness.

The current error handling has two issues:

  1. Unsafe type assertion with as any[]
  2. No fallback error message when errors array is empty
   onError: (error) => {
-    const errors = (error.cause?.errors as any[]) || [];
+    const errors = Array.isArray(error.cause?.errors) ? error.cause.errors : [];
     errors.forEach((err) => {
       const field = err.loc[0];
-      form.setError(field, { message: err.ctx?.error || err.msg });
+      form.setError(field, { message: err.ctx?.error || err.msg || t("unknown_error") });
     });
+    if (errors.length === 0) {
+      toast.error(t("something_went_wrong"));
+    }
   },

Likely invalid or redundant comment.

src/components/Users/CreateUserForm.tsx Show resolved Hide resolved
@rajku-dev
Copy link
Contributor Author

rajku-dev commented Jan 16, 2025

removed the isValid check on Submit button

@nihal467
Copy link
Member

@rajku-dev use proper PR heading

@rajku-dev rajku-dev changed the title changes to create user form Improvements in UserCreateForm Jan 16, 2025
@rajku-dev rajku-dev changed the title Improvements in UserCreateForm Improvements in CreateUserForm Jan 16, 2025
@nihal467
Copy link
Member

LGTM @rithviknishad can you review it

Copy link
Member

@rithviknishad rithviknishad left a comment

Choose a reason for hiding this comment

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

LGTM; types changes requires review from @bodhish

@rithviknishad rithviknishad requested a review from bodhish January 16, 2025 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Required Fields Error and Unnecessary Network Requests
6 participants