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

Modify CreateUserForm and add dirtyState to all react-hook-form #9749

Closed
wants to merge 33 commits into from

Conversation

rajku-dev
Copy link
Contributor

@rajku-dev rajku-dev commented Jan 4, 2025

Proposed Changes

  • Modified CreateUserForm to track errors as user types for individual fields to improve UX
  • Disable Submit Button in CreateUserForm until the form values are valid according to Zod Schema defined
  • Add asterisk for required fields
  • Used existing DateFormField to prevent users from selecting future DOB
  • Set Limit of 13 digits in PhoneNumber field
  • Used isDirty property in all react-hook-forms to prevent Unnecessary network requests

@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

Summary by CodeRabbit

  • New Features

    • Introduced isDirty state to prevent unnecessary form submissions across multiple components.
    • Enhanced user experience with more robust form controls and validation improvements, including the addition of a DatePicker for date of birth.
    • Expanded gender options in the user creation form.
    • Added localization support for validation messages, including username and phone number requirements.
    • Introduced a new UserCreateRequest type for user creation.
    • Added new components for improved error handling: InputWithError and InputErrors.
  • Bug Fixes

    • Disabled submit buttons when no form changes are detected, improving form usability.
    • Improved form validation logic across user-facing forms, ensuring non-negative age inputs and accurate year of birth calculations.
    • Enhanced error handling for form submissions, providing clearer feedback for users.
    • Streamlined the encounter update process by simplifying the user interface.

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

coderabbitai bot commented Jan 4, 2025

Walkthrough

The pull request introduces a consistent approach to form handling across multiple components by implementing an isDirty state variable. This state tracks whether a form has been modified and is used to conditionally disable submit buttons, preventing unnecessary network requests and improving user experience. The changes are applied to several forms including CreateEncounterForm, FacilityCreate, ScheduleExceptionForm, CreateUserForm, and PatientRegistration. Additionally, some components have enhanced validation for specific fields.

Changes

File Change Summary
src/components/Encounter/CreateEncounterForm.tsx Updated button to disable based on isPending and form.formState.isDirty.
src/components/Facility/FacilityCreate.tsx Implemented isDirty to control submit button state and prevent submissions without changes.
src/components/Schedule/ScheduleExceptionForm.tsx Modified button to disable based on isPending and form.formState.isDirty.
src/components/Users/CreateUserForm.tsx Enhanced form with isDirty, added new validation rules, and updated field labels.
src/pages/Appoinments/PatientRegistration.tsx Introduced isDirty to prevent submitting unchanged forms.
src/components/ui/date-picker.tsx Added disabled prop to DatePickerProps for conditional date disabling.
public/locale/en.json Added localization entries for validation messages and username rules.
src/components/Users/UserFormValidations.tsx Updated user form type to require additional fields and modified existing ones.
src/types/user/userApi.ts Changed request body type from UserBase to UserCreateRequest in the create method.
src/types/user/user.ts Introduced UserCreateRequest type for user creation structure.

Assessment against linked issues

Objective Addressed Explanation
Disable submit button using isDirty
Prevent unnecessary network requests
Add red asterisk for required fields
Validate date of birth Validation for future dates not fully implemented in all relevant forms.
Phone number field validation Partial implementation in CreateUserForm; unclear if all components are fully validated.

Possibly related issues

Possibly related PRs

  • Improve code splitting #8979: The changes in the main PR regarding the enabling logic of the "Create Encounter" button are related to the modifications in the FacilityCreate.tsx and ScheduleExceptionForm.tsx files, where similar logic for disabling buttons based on form state is implemented.
  • New Cypress Test for HCX Workflow in the platform #9007: The changes in the main PR about form state management and button enabling logic are relevant to the PatientRegistration.cy.ts test, which includes tests for form interactions that may involve similar state checks.
  • New Patient Search and Register UI #9400: The changes in the main PR regarding form handling and user input are related to the updates in the PatientRegistration.tsx, which also involves managing user input and form state.

Suggested labels

needs review, needs testing

Suggested reviewers

  • rithviknishad
  • Jacobjeevan

Poem

🐰 A rabbit's tale of forms so neat,
Where isDirty makes submission sweet.
No clicks in vain, no requests unwise,
Our form now dances with user-friendly ties.
Validation's magic, prevention's delight! 🚀


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 4, 2025

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit aaa7d41
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/677e9f81cf3b690007ae2ccf
😎 Deploy Preview https://deploy-preview-9749--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.

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

158-159: Remove or refine console logs for production.
console.log(!!errors, errors); may not be intended for production. It can clutter logs.

-  console.log(!!errors, errors);
+  // Remove this before production or replace with a proper logger if 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 4850743 and 5c43c3e.

📒 Files selected for processing (5)
  • src/components/Encounter/CreateEncounterForm.tsx (2 hunks)
  • src/components/Facility/FacilityCreate.tsx (2 hunks)
  • src/components/Schedule/ScheduleExceptionForm.tsx (2 hunks)
  • src/components/Users/CreateUserForm.tsx (15 hunks)
  • src/pages/Appoinments/PatientRegistration.tsx (2 hunks)
🧰 Additional context used
📓 Learnings (1)
src/pages/Appoinments/PatientRegistration.tsx (1)
Learnt from: kihan2518B
PR: ohcnetwork/care_fe#8956
File: src/components/Patient/PatientRegister.tsx:861-861
Timestamp: 2024-12-02T18:50:29.685Z
Learning: In `src/components/Patient/PatientRegister.tsx`, `insuranceDetails` is not part of `state.form`, so changes to it are not tracked by the `isDirty` state. Therefore, the form's `disabled` state needs to be conditionally set based on `insuranceDetails.length`.
🔇 Additional comments (17)
src/components/Schedule/ScheduleExceptionForm.tsx (2)

76-79: Good addition of isDirty for form-checking.
Using isDirty clarifies when the user has modified form data, enhancing UX by preventing accidental submissions. Nicely done!


259-263: Great user feedback improvement.
Disabling the submit button when the form is clean or a mutation is pending helps avoid redundant submissions. This aligns well with best practices.

src/components/Encounter/CreateEncounterForm.tsx (2)

148-151: Clear adoption of isDirty tracking.
Extracting isDirty from the form state neatly sets you up to conditionally enable/disable submission. No issues found here.


325-325: Submission button logic is consistent with design goals.
Disabling the button if the form has not been modified prevents unnecessary submissions. This is a solid improvement.

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

26-27: New DateFormField import.
Importing this custom date field is fine. Ensure unit tests cover edge cases (e.g., invalid dates, future dates).

Could you confirm if we have an existing suite for DateFormField coverage?


79-82: Schema definitions updated.
Refining date_of_birth as a z.date() and expanding gender options broadens validation scope. Nicely done!


103-103: Form validation mode switched to onChange.
Real-time validation is generally user-friendly and can catch errors earlier. Looks good.


114-117: Kudos on extracting more form states.
Accessing isDirty, errors, and isValid broadens control over user feedback.


194-194: Clear required field labeling.
Adding the required indicator improves clarity for end-users. Nice enhancement.

Also applies to: 208-208, 223-223, 238-238, 252-252, 271-271


286-293: Phone number length limit.
Setting maxLength={13} helps ensure consistent formatting. This is aligned with the requirement for +91 and 10 digits.


305-305: Renaming alt phone to WhatsApp is clear.
Enforcing the same max length ensures uniform input constraints. Good job.

Also applies to: 311-311


345-345: Use of disableFuture is user-friendly.
Disabling future dates adds appropriate domain constraints. Nicely implemented.

Also applies to: 347-352


462-466: Conditionally disabling submission.
Ensuring the form is both dirty and valid before submission is a strong UX improvement.

src/pages/Appoinments/PatientRegistration.tsx (2)

142-145: isDirty extraction is consistent with PR objectives.
This approach prevents registering unchanged data. No issues found.


455-455: Disable submit button when the form is clean.
Mirrors similar logic across the application, ensuring consistent user flow. Nicely aligned with other forms.

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

140-143: LGTM! Clean implementation of form state tracking.

The destructuring of isDirty from formState follows react-hook-form best practices and properly implements form modification tracking.


Line range hint 147-164: Verify form reset behavior with isDirty state.

The form reset after loading facility data might affect the dirty state tracking. Let's verify this behavior to ensure it doesn't cause unexpected issues.

✅ Verification successful

Form reset behavior is correctly implemented

The form reset behavior in FacilityCreate is properly implemented and doesn't cause any issues with the dirty state tracking:

  1. The component correctly tracks the form's dirty state using formState: { isDirty } from the form hook
  2. The form reset is used appropriately in the useEffect when loading facility data
  3. The submit button is properly disabled when the form is not dirty: disabled={isLoading || !isDirty}
  4. The form initialization includes proper default values, ensuring consistent state tracking

The current implementation follows the recommended pattern for form state management in React Hook Form, and the dirty state will accurately reflect whether the user has made changes to the form values.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar patterns in other form components to understand the reset behavior
ast-grep --pattern 'form.reset($$$)'

# Look for any related issues or discussions
rg -g '!node_modules' -l 'isDirty.*form\.reset|form\.reset.*isDirty'

Length of output: 1481


Script:

#!/bin/bash
# Let's check the form hook initialization and usage in FacilityCreate
ast-grep --pattern 'const form = useForm<$_>($$$)'

# Let's also check for any isDirty usage in the component
rg -A 5 'isDirty' src/components/Facility/FacilityCreate.tsx

# Check the form submission handler to understand the form state management
ast-grep --pattern 'const onSubmit = async ($$$) => {
  $$$
}'

Length of output: 11138

src/components/Facility/FacilityCreate.tsx Outdated Show resolved Hide resolved
src/components/Encounter/CreateEncounterForm.tsx Outdated Show resolved Hide resolved
src/components/Encounter/CreateEncounterForm.tsx Outdated Show resolved Hide resolved
src/components/Facility/FacilityCreate.tsx Outdated Show resolved Hide resolved
src/components/Facility/FacilityCreate.tsx Outdated Show resolved Hide resolved
src/components/Schedule/ScheduleExceptionForm.tsx Outdated Show resolved Hide resolved
src/components/Users/CreateUserForm.tsx Outdated Show resolved Hide resolved
src/components/Users/CreateUserForm.tsx Outdated Show resolved Hide resolved
src/components/Users/CreateUserForm.tsx Outdated Show resolved Hide resolved
src/pages/Appoinments/PatientRegistration.tsx Outdated Show resolved Hide resolved
src/pages/Appoinments/PatientRegistration.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)

300-305: Consider improving the phone number placeholder.

While the maxLength implementation is good, the placeholder could be more descriptive to match the validation requirements.

-                    placeholder="+91XXXXXXXXXX"
+                    placeholder="+91 followed by 10 digits"

Also applies to: 317-319, 325-325


363-368: Consider adding error handling for date changes.

While the DateFormField implementation looks good, consider adding error handling for the onChange callback.

-                    onChange={(date) => field.onChange(date.value)}
+                    onChange={(date) => {
+                      if (date?.value) {
+                        field.onChange(date.value);
+                      }
+                    }}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5c43c3e and 332ca54.

📒 Files selected for processing (5)
  • src/components/Encounter/CreateEncounterForm.tsx (1 hunks)
  • src/components/Facility/FacilityCreate.tsx (1 hunks)
  • src/components/Schedule/ScheduleExceptionForm.tsx (1 hunks)
  • src/components/Users/CreateUserForm.tsx (13 hunks)
  • src/pages/Appoinments/PatientRegistration.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/pages/Appoinments/PatientRegistration.tsx
  • src/components/Encounter/CreateEncounterForm.tsx
  • src/components/Schedule/ScheduleExceptionForm.tsx
  • src/components/Facility/FacilityCreate.tsx
🔇 Additional comments (2)
src/components/Users/CreateUserForm.tsx (2)

79-86: LGTM! Schema changes look good.

The date validation and gender options have been improved:

  • Date of birth validation now properly prevents future dates
  • Gender options are more inclusive with the addition of "transgender" and "non_binary"

107-107: LGTM! Form configuration enhances UX.

The form configuration improvements align with the PR objectives:

  • Real-time validation with "onChange" mode
  • Submit button properly disabled until form is both dirty and valid

Also applies to: 481-481

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: 0

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

475-479: Consider adding a loading state to the submit button

The form validation using both isDirty and isValid is excellent. However, to prevent double submissions and provide better feedback, consider adding a loading state to the button during form submission.

 <Button
   type="submit"
   className="w-full"
-  disabled={!form.formState.isDirty || !form.formState.isValid}
+  disabled={!form.formState.isDirty || !form.formState.isValid || form.formState.isSubmitting}
 >
-  Create User
+  {form.formState.isSubmitting ? "Creating..." : "Create User"}
 </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 332ca54 and ec6e72e.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (13 hunks)
🔇 Additional comments (5)
src/components/Users/CreateUserForm.tsx (5)

9-9: Good choice using shadcn's DatePicker!

The switch to shadcn's DatePicker component aligns with our component standardization efforts.


78-85: Well-implemented schema validation!

The date_of_birth validation is thorough with:

  • Required field validation
  • Future date restriction
  • Proper error messages

The gender options are now more inclusive with the addition of "transgender" and "non_binary".


106-106: Good implementation of real-time validation!

Setting form mode to "onChange" enables immediate feedback as users type, improving the user experience.


299-304: Good input constraints for phone number!

The maxLength attribute ensures phone numbers don't exceed 13 characters (including the +91 prefix).


362-365: Clean implementation of the date picker!

The DatePicker implementation is concise and properly handles the date value and onChange events.

@rajku-dev
Copy link
Contributor Author

Everything is working fine but
Why can't add the user? it's coming from backend.

@github-actions github-actions bot added needs-triage question Further information is requested labels Jan 5, 2025
@bodhish
Copy link
Member

bodhish commented Jan 5, 2025

Check the network response, you will be able top see the error message.

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/ui/date-picker.tsx (2)

19-19: Clarify prop naming for better readability.

The disabled prop name may be ambiguous since it's often associated with a boolean property that disables the entire component. Consider renaming this callback to something like disableDate or isDateDisabled to more clearly convey its purpose.


22-22: Ensure function defaults are handled properly.

If consumers do not pass the disabled prop, ensure you have a suitable fallback in place so the Calendar component won't receive undefined. You can default to a no-op function (always returning false) for a cleaner developer experience.

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

295-297: Consider clarifying phone input design.

You’ve limited the field to 13 characters (+91 + 10 digits). This works if phone numbers will always begin with "+91". For broader usage or future expansions beyond Indian country codes, you might need a separate strategy or dynamic length checks.

Also applies to: 299-304

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ec6e72e and ad412ce.

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

48-48: Verify that the Calendar component accepts a function for the disabled prop.

Ensure the Calendar component's interface expects a function for the disabled prop, as documented. Otherwise, it might cause unintended behavior or runtime errors.

✅ Verification successful

The disabled prop is correctly used with the Calendar component

Looking at the implementation in src/components/ui/calendar.tsx, the Calendar component is a wrapper around the DayPicker component and forwards all props (including disabled) through the spread operator {...props}. The component accepts all DayPicker props, which includes the disabled prop that can be a function, date, or array of dates to disable specific days.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the Calendar component signature for the 'disabled' prop
rg -A 10 "function Calendar" --type ts --type tsx

Length of output: 79


Script:

#!/bin/bash
# Search for Calendar component definition and its props interface/type
rg -t ts -t typescript -t tsx "Calendar.*Props|interface.*Calendar|type.*Calendar|function Calendar|const Calendar" -A 10

# Also search for any re-exports of Calendar component
rg -t ts -t typescript -t tsx "export.*Calendar"

Length of output: 244


Script:

#!/bin/bash
# Let's try with fd to find relevant files first
fd -e ts -e tsx

# Then use ast-grep to find Calendar component definition and props
ast-grep --pattern 'interface CalendarProps {
  $$$
}'

ast-grep --pattern 'type CalendarProps = {
  $$$
}'

ast-grep --pattern 'const Calendar = $$$'

ast-grep --pattern 'function Calendar($$$) {
  $$$
}'

Length of output: 29547

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

78-85: Confirm date comparison logic.

The Zod refinement checks that dob <= new Date(), which is correct to prevent future dates. However, confirm that all needed time zones or edge cases (e.g., local midnight offsets) are handled. For critical date validations, consider normalizing times (e.g., to midnight) prior to comparison.


106-106: Great use of onChange validation mode.

This aligns well with real-time user feedback, improving user experience.


191-193: Consistent required field indicators.

Appending “*” clarifies which fields are mandatory. The approach is clear and user-friendly, ensuring consistent labeling across the form.

Also applies to: 207-209, 224-226, 241-243, 257-259, 278-280


316-318: WhatsApp number approach.

Disabling the field when isWhatsApp is true is intuitive. If users later uncheck “WhatsApp number is same as phone number,” they can provide a different number. Just ensure you handle edge cases when toggling isWhatsApp on/off.

Also applies to: 324-324


476-480: Great synergy between isDirty and isValid checks.

Disabling the submit button if the form is either pristine or invalid ensures fewer erroneous or empty submissions. This usage is consistent with best practices for react-hook-form. Nicely done.

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: 0

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

299-304: Consider extracting the phone number maxLength as a constant.

The maxLength of 13 (accounting for "+91" prefix and 10 digits) is used in multiple places. Consider extracting it as a named constant for better maintainability and clarity.

+ const PHONE_NUMBER_MAX_LENGTH = 13; // +91 prefix (3) + 10 digits
  ...
  <Input
    type="tel"
    placeholder="+91XXXXXXXXXX"
-   maxLength={13}
+   maxLength={PHONE_NUMBER_MAX_LENGTH}
    {...field}
  />

Also applies to: 324-324


362-368: Consider extracting date constraints as named constants.

The date restrictions use magic values that could be more maintainable and self-documenting as constants.

+ const MIN_DATE_OF_BIRTH = new Date("1900-01-01");
+ // Prevent future dates and dates before 1900
+ const isDateDisabled = (date: Date) => 
+   date > new Date() || date < MIN_DATE_OF_BIRTH;
  ...
  <DatePicker
    date={field.value}
    onChange={(date) => field.onChange(date)}
-   disabled={(date) =>
-     date > new Date() || date < new Date("1900-01-01")
-   }
+   disabled={isDateDisabled}
  />
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ad412ce and ababd0d.

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

9-9: LGTM! Using the recommended DatePicker component.

The change follows the recommendation to use shadcn's datepicker instead of the deprecated DateFormField component.


78-85: LGTM! Comprehensive validation for date_of_birth and inclusive gender options.

The schema changes include:

  • Strong typing and validation for date_of_birth
  • Prevention of future dates
  • More inclusive gender options including "transgender" and "non_binary"

106-106: LGTM! Real-time validation enabled.

Setting form mode to "onChange" enables real-time error tracking as users input data, improving user experience.


478-482: LGTM! Robust form submission control.

The submit button implementation:

  • Prevents submission of unmodified forms (isDirty)
  • Ensures form validity before submission (isValid)
  • Reduces unnecessary network requests
    This implementation should be considered as the standard pattern for other forms in the application.

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

147-157: Consider optimizing error notifications

While the error handling is thorough, showing both form field errors and notifications for the same errors might be redundant. Consider showing notifications only for general errors and letting form field errors handle field-specific validation failures.

 if (error) {
   const errors = (error.errors as any[]) || [];

   errors.forEach((err) => {
     const field = err.loc[0];
     form.setError(field, { message: err.msg });
-    Notification.Error({
-      msg: err.msg,
-    });
   });
+  if (errors.length > 0) {
+    Notification.Error({
+      msg: "Please correct the highlighted fields",
+    });
+  }
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ababd0d and e924e69.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (14 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • 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: OSSAR-Scan
🔇 Additional comments (5)
src/components/Users/CreateUserForm.tsx (5)

78-85: Well-implemented schema changes!

The date of birth validation and expanded gender options are well thought out. The validation ensures dates are not in the future while the gender options are more inclusive.


106-106: Good choice of form validation mode!

Setting mode to "onChange" provides real-time feedback to users, enhancing the user experience by showing validation errors as they type.


307-312: Good input constraints for phone number!

The maxLength attribute ensures phone numbers don't exceed 13 characters (including the +91 prefix), which aligns with the validation requirements.


370-376: Well-implemented date picker constraints!

The date picker properly restricts both future dates and dates before 1900, providing a good user experience while ensuring valid data entry.


486-490: Excellent form submission control!

The submit button implementation correctly uses both isDirty and isValid states, preventing unnecessary API calls and ensuring data validity before submission. This matches the standardization suggested in previous reviews.

@rajku-dev
Copy link
Contributor Author

Check the network response, you will be able top see the error message.

got it,
I've added inline field error messages and Error notifications for API errors improving UX/DX

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 (1)
src/components/Patient/PatientRegistration.tsx (1)

522-531: Consider adding a maximum allowable age validation.

While this logic prevents negative ages, extremely large values may yield unrealistic birth years. Restricting the age range (e.g., 0-120) or dynamically validating the resulting year_of_birth could provide a more robust user experience.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e924e69 and 3a7772e.

📒 Files selected for processing (1)
  • src/components/Patient/PatientRegistration.tsx (1 hunks)

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Jan 6, 2025
Copy link

github-actions bot commented Jan 6, 2025

👋 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.

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

67-69: Consider making phone number validation more flexible

The current regex /^\+91[0-9]{10}$/ only allows Indian phone numbers. Consider making it more flexible for international numbers if the system needs to support users from different countries.

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

75-81: Enhance date of birth validation

While the future date validation is good, consider adding a reasonable minimum date validation in the schema to match the UI restriction.

   date_of_birth: z
     .date({
       required_error: t("this_field_is_required"),
     })
-    .refine((dob) => dob <= new Date(), {
-      message: t("date_of_birth_cannot_be_in_future"),
+    .refine((dob) => {
+      const minDate = new Date("1900-01-01");
+      const today = new Date();
+      return dob >= minDate && dob <= today;
+    }, {
+      message: t("invalid_date_of_birth_range"),
     }),

124-129: Improve type safety in error handling

The current error handling uses type assertion (as any[]). Consider defining proper error types for better type safety.

+ type ApiError = {
+   loc: string[];
+   ctx: { error: string };
+ };

- const errors = (error.cause?.errors as any[]) || [];
+ const errors = (error.cause?.errors as ApiError[]) || [];

266-271: Enhance phone number input validation

While maxLength helps, consider adding the pattern attribute to provide better input validation feedback in supported browsers.

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9382901 and 0908316.

📒 Files selected for processing (2)
  • src/components/Users/CreateUserForm.tsx (13 hunks)
  • src/types/user/userApi.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/types/user/userApi.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: OSSAR-Scan
  • GitHub Check: cypress-run (1)
🔇 Additional comments (1)
src/components/Users/CreateUserForm.tsx (1)

441-449: LGTM! Well-implemented submit button

The submit button implementation follows best practices:

  • Properly handles form state (isDirty and isValid)
  • Shows loading indicator during submission
  • Uses translations for button text

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)

44-91: Consider enhancing validation rules.

The form schema is well-structured, but consider these improvements:

  1. The phone number regex (/^\+91[0-9]{10}$/) only allows Indian numbers. Consider making it more flexible for international numbers if needed.
  2. The date validation could be more specific about the minimum allowed date.

115-128: Improve type safety in error handling.

The error handling could be more type-safe:

- const errors = (error.cause?.errors as any[]) || [];
+ type ApiError = { loc: string[]; ctx: { error: string } };
+ const errors = (error.cause?.errors as ApiError[]) || [];

264-269: Enhance phone number input accessibility.

Consider adding the pattern attribute to improve mobile keyboard experience:

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

Also applies to: 287-289

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0908316 and e134196.

📒 Files selected for processing (7)
  • public/locale/en.json (4 hunks)
  • src/components/Encounter/CreateEncounterForm.tsx (1 hunks)
  • src/components/Users/CreateUserForm.tsx (13 hunks)
  • src/components/Users/UserFormValidations.tsx (2 hunks)
  • src/pages/Appoinments/PatientRegistration.tsx (1 hunks)
  • src/types/user/user.ts (1 hunks)
  • src/types/user/userApi.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/pages/Appoinments/PatientRegistration.tsx
  • src/components/Encounter/CreateEncounterForm.tsx
  • src/types/user/userApi.ts
  • public/locale/en.json
🔇 Additional comments (4)
src/types/user/user.ts (1)

18-35: LGTM! Well-structured type definition.

The UserCreateRequest type properly captures all required fields for user creation with appropriate optionality and type constraints.

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

Line range hint 10-41: LGTM! Well-organized field groupings.

The field arrays are properly updated to use the new UserCreateRequest type and maintain logical groupings for different operations.

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

323-329: LGTM! Proper date constraints implemented.

The DatePicker implementation correctly handles date constraints and value management.


439-448: LGTM! Proper form submission handling.

The submit button correctly implements:

  • Form state validation (isDirty and isValid)
  • Loading state
  • Translations

@rithviknishad rithviknishad removed question Further information is requested needs-triage labels Jan 8, 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: 0

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

Missing required field in newUserFields array

The newUserFields array is missing the required date_of_birth field from UserCreateRequest. The fields mentioned in the review comment (c_password and phone_number_is_whatsapp) are not part of the type definition, so they should not be included.

  • Add date_of_birth to the newUserFields array in src/components/Users/UserFormValidations.tsx
🔗 Analysis chain

Line range hint 10-19: Verify field arrays match the schema

The field arrays have been updated to use UserCreateRequest, but some fields like c_password and phone_number_is_whatsapp are included in the schema but not in these arrays. Consider updating the arrays to match the schema exactly.

Also applies to: 22-27, 30-33, 36-39

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if all fields in userFormSchema are included in the field arrays

# Search for the schema definition
echo "Schema fields:"
rg "userFormSchema.*object.*\{" -A 50 "src/components/Users/CreateUserForm.tsx"

# Compare with field arrays
echo -e "\nField arrays:"
rg "Array<keyof UserCreateRequest>" -A 10 "src/components/Users/UserFormValidations.tsx"

Length of output: 954


Script:

#!/bin/bash
# Try different patterns to locate schema and type definitions

# Search for schema definitions with broader patterns
echo "Searching for schema definitions:"
rg "schema.*=.*{|type.*Schema.*=.*{" -A 20 "src/components/Users/CreateUserForm.tsx"

# Search for UserCreateRequest type definition
echo -e "\nSearching for UserCreateRequest type:"
ast-grep --pattern 'type UserCreateRequest = {
  $$$
}'

# Alternative: search for interface
ast-grep --pattern 'interface UserCreateRequest {
  $$$
}'

Length of output: 1341

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

93-94: Consider optimizing error handling

The mutation error handling assumes a specific error structure. Consider:

  1. Adding type safety for the error structure
  2. Adding a fallback error message for unexpected error formats
  onError: (error) => {
+   if (!error.cause?.errors?.length) {
+     toast.error(t("something_went_wrong"));
+     return;
+   }
    const errors = (error.cause?.errors as any[]) || [];
    errors.forEach((err) => {
      const field = err.loc[0];
      form.setError(field, { message: err.ctx.error });
    });
  },

Also applies to: 115-128


130-134: Simplify object destructuring

The current approach using an IIFE for object destructuring could be simplified.

- const onSubmit = (data: z.infer<typeof userFormSchema>) =>
-   createUser(
-     (({ c_password: _c, phone_number_is_whatsapp: _p, ...payload }) =>
-       payload)(data),
-   );
+ const onSubmit = ({ c_password, phone_number_is_whatsapp, ...payload }: z.infer<typeof userFormSchema>) =>
+   createUser(payload);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e134196 and fb1d00b.

📒 Files selected for processing (3)
  • src/components/Users/CreateUserForm.tsx (13 hunks)
  • src/components/Users/UserFormValidations.tsx (2 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 (4)
src/components/Users/CreateUserForm.tsx (4)

44-91: Schema validation looks robust

The schema includes comprehensive validation rules with proper error messages using translations. Good job on:

  • Username validation with regex patterns
  • Password complexity requirements
  • Phone number format validation
  • Date of birth validation

263-268: Good phone number input constraints

The maxLength attribute on phone number inputs helps prevent invalid input.

Also applies to: 286-286


322-328: Date picker implementation looks good

The date picker correctly:

  • Prevents selection of future dates
  • Sets a reasonable minimum date
  • Uses the new shadcn DatePicker component as recommended

438-446: Submit button implementation follows best practices

The button correctly:

  • Disables submission when form is invalid or unchanged
  • Shows loading state during submission
  • Uses translations for the button text

Comment on lines 131 to 134
createUser(
(({ c_password: _c, phone_number_is_whatsapp: _p, ...payload }) =>
payload)(data),
);
Copy link
Member

@rithviknishad rithviknishad Jan 8, 2025

Choose a reason for hiding this comment

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

this is not clean. let's not do weird things to achieve what's desired. let's maintain only readable code.

let's pick things only what we need manually here. so that later if we ever change the form for some reason (lets say we added a new field that doesn't needs to be sent to the backend, this would end up sending information that backend doesn't care about).

follow good patterns that are done in other places in the codebase that uses onSubmit with useForm.

createUser({
  username: data.username,
  first_name: data.first_name,
  ...  
})

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used transform method to prevent sending empty strings to backend for optional field
could've also done like

qualification: data.qualification || undefined  # for each optional field

works same.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fb1d00b and 5392459.

📒 Files selected for processing (1)
  • src/components/Users/CreateUserForm.tsx (13 hunks)
🔇 Additional comments (5)
src/components/Users/CreateUserForm.tsx (5)

44-104: LGTM! Well-structured schema with comprehensive validation rules.

The schema implementation is thorough with:

  • Strong validation rules for username and password
  • Proper use of translations for error messages
  • Type-safe enums for user_type and gender
  • Smart handling of optional fields with transform

Line range hint 106-127: LGTM! Form configuration follows best practices.

Good implementation of:

  • "onChange" validation mode for real-time feedback
  • Sensible default values
  • Proper phone number synchronization with WhatsApp

290-295: LGTM! Phone number input constraints implemented correctly.

Good implementation of:

  • maxLength constraint for phone numbers
  • Proper disabled state for WhatsApp number when synced

Also applies to: 313-315


349-355: LGTM! Date picker implementation with proper constraints.

Correctly implements:

  • Future date restriction
  • Reasonable minimum date (1900-01-01)
  • Proper date handling with the DatePicker component

465-474: LGTM! Submit button implementation with proper states.

Well implemented:

  • Disabled state based on form validity and dirty state
  • Loading indicator during submission
  • Translated button text

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

github-actions bot commented Jan 8, 2025

👋 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 Deploy-Failed Deplyment is not showing preview label Jan 8, 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/Patient/PatientRegistration.tsx (1)

574-583: LGTM! Age validation logic looks good.

The age validation logic effectively prevents negative ages and correctly calculates the year of birth. Consider adding an upper limit to prevent unrealistic ages.

   onChange={(e) => {
-    const age = Math.max(0, Number(e.target.value));
+    const age = Math.min(150, Math.max(0, Number(e.target.value)));
     setForm((f) => ({
       ...f,
       age: String(age),
       year_of_birth: age
         ? new Date().getFullYear() - age
         : undefined,
     }));
   }}
public/locale/en.json (1)

1748-1748: Consider enhancing the required field message for better UX.

While "This field is required" is functional, consider making it more user-friendly and specific, e.g., "Please fill in this field" or "This information is needed".

-  "this_field_is_required": "This field is required",
+  "this_field_is_required": "Please fill in this field",
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5392459 and ad9b270.

📒 Files selected for processing (2)
  • public/locale/en.json (4 hunks)
  • src/components/Patient/PatientRegistration.tsx (1 hunks)
🧰 Additional context used
🪛 GitHub Check: cypress-run (1)
src/components/Patient/PatientRegistration.tsx

[failure] 567-567:
Cannot find name 'InputWithError'.


[failure] 586-586:
Cannot find name 'InputWithError'.

🪛 GitHub Actions: Cypress Tests
src/components/Patient/PatientRegistration.tsx

[error] 567-567: Cannot find name 'InputWithError'. The component or type 'InputWithError' is not defined or imported.

🪛 GitHub Actions: Deploy Care Fe
src/components/Patient/PatientRegistration.tsx

[error] 567-567: Cannot find name 'InputWithError'


[error] 586-586: Cannot find name 'InputWithError'

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: OSSAR-Scan
  • GitHub Check: CodeQL-Build
🔇 Additional comments (7)
public/locale/en.json (7)

672-672: LGTM! Clear validation message for date of birth.

The message "Date of birth cannot be in future" is clear, concise, and effectively communicates the validation rule to users.


1420-1420: LGTM! Clear phone number format specification.

The message "Phone number must start with +91 followed by 10 digits" clearly specifies the required format and aligns with the 13-digit limit requirement.


1868-1868: LGTM! Clear username validation rule.

The message clearly explains that consecutive special characters are not allowed in usernames.


1869-1869: LGTM! Clear specification of allowed characters.

The message clearly specifies which characters are allowed in usernames (lowercase letters, numbers, and specific symbols).


1870-1871: LGTM! Clear username length restrictions.

The messages clearly specify both minimum (4 characters) and maximum (16 characters) length requirements for usernames.


1873-1873: LGTM! Clear rule for username boundaries.

The message clearly specifies that usernames must start and end with either a letter or number.


Line range hint 672-1873: Overall excellent validation message implementation.

The validation messages are well-structured, clear, and comprehensive. They effectively support all the validation requirements mentioned in the PR objectives:

  • Date of birth future date restriction
  • Phone number 13-digit format
  • Required field validation
  • Username validation rules

The messages are user-friendly and will help users understand and correct validation errors quickly.

This reverts commit ad9b270, reversing
changes made to 5392459.
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

🧹 Nitpick comments (10)
src/components/Patient/PatientInfoCard.tsx (1)

265-271: Consider i18n and UX improvements for the edit button.

The button implementation looks good overall, with proper routing and conditional rendering. Consider these enhancements:

  1. Use i18n translation for "Update Encounter" text for consistency with other translated strings in the component
  2. Add a tooltip to explain why the button is disabled when the encounter is completed
 <Button asChild variant="primary">
   <Link
     href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/edit_encounter`}
+    title={completedEncounterStatus.includes(encounter.status) ? t('encounter_edit_disabled_tooltip') : ''}
   >
-    Update Encounter
+    {t('encounter_edit_button')}
   </Link>
 </Button>
src/Routers/routes/ConsultationRoutes.tsx (2)

45-52: Consider maintaining consistency in parameter naming.

The URL parameter :id is passed as consultationId prop. For better maintainability and clarity, consider keeping the naming consistent:

  "/facility/:facilityId/patient/:patientId/consultation/:id/consent-records":
    ({ facilityId, patientId, id }) => (
      <PatientConsentRecords
        facilityId={facilityId}
        patientId={patientId}
-       consultationId={id}
+       id={id}
      />
    ),

53-64: Improve route path consistency and structure.

A few suggestions for improvement:

  1. The URL parameter uses encounterId while others use kebab-case
  2. The trailing slash is unnecessary
  3. The hardcoded "encounter" type could be made dynamic if needed
-  "/facility/:facilityId/patient/:patientId/encounterId/:id/files/": ({
+  "/facility/:facilityId/patient/:patientId/encounter/:id/files": ({
    facilityId,
    patientId,
    id,
  }) => (
    <FileUploadPage
      facilityId={facilityId}
      patientId={patientId}
      encounterId={id}
-     type="encounter"
+     type={type} // Consider making this dynamic if needed
    />
  ),
src/components/ui/errors.tsx (1)

1-11: Consider accessibility and key improvements.

The component looks good but could benefit from these enhancements:

  1. Use a more semantic HTML element like ul/li for error lists
  2. Add appropriate ARIA attributes for screen readers
  3. Use unique error message content as key instead of array index
 export function InputErrors({ errors }: { errors?: string[] }) {
   return errors && !!errors.length ? (
-    <div className="mt-1" data-input-error>
+    <ul className="mt-1" role="alert" data-input-error>
       {errors?.map((error, i) => (
-        <div key={i} className="text-red-500 text-xs">
+        <li key={error} className="text-red-500 text-xs">
           {error}
-        </div>
+        </li>
       ))}
-    </div>
+    </ul>
   ) : null;
 }
src/components/ui/input-with-error.tsx (1)

4-24: Enhance accessibility with ARIA attributes and htmlFor.

The component looks well-structured, but could be improved for accessibility:

 export default function InputWithError(props: {
   label?: string;
   required?: boolean;
   errors?: string[];
   children: React.ReactNode;
+  id?: string;
 }) {
-  const { label, errors, children, required } = props;
+  const { label, errors, children, required, id } = props;
 
   return (
     <>
       {label && (
-        <Label className="mb-2">
+        <Label className="mb-2" htmlFor={id}>
           {label}
-          {required && <span className="text-red-500">*</span>}
+          {required && <span className="text-red-500" aria-label="required">*</span>}
         </Label>
       )}
-      {children}
+      <div aria-required={required} aria-invalid={!!errors?.length}>
+        {children}
+      </div>
       <InputErrors errors={errors} />
     </>
   );
 }
src/components/Patient/allergy/list.tsx (1)

Line range hint 103-143: Consider extracting badge styling logic to separate utility functions.

The badge styling logic could be simplified by moving it to separate utility functions or using a mapping object:

const STATUS_BADGE_STYLES = {
  active: "bg-green-100 text-green-800 border-green-200",
  inactive: "bg-gray-100 text-gray-800 border-gray-200",
  default: "bg-gray-100 text-gray-800 border-gray-200",
} as const;

const getStatusBadgeStyle = (status: string = "") => 
  STATUS_BADGE_STYLES[status.toLowerCase() as keyof typeof STATUS_BADGE_STYLES] 
  ?? STATUS_BADGE_STYLES.default;
🧰 Tools
🪛 Biome (1.9.4)

[error] 103-103: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

src/pages/Organization/components/OrganizationSelector.tsx (2)

Line range hint 25-25: Address TODO comment about component renaming.

The TODO comment suggests renaming to GovtOrganizationSelector. This would better reflect the component's specific purpose.

Would you like me to help create a GitHub issue to track this renaming task?


142-148: Simplify complex label translation logic.

The nested ternary operation in the label prop could be simplified for better readability:

-            label={t(
-              lastLevel
-                ? `SYSTEM__govt_org_type__${lastLevel.metadata?.govt_org_children_type || "default"}`
-                : "SYSTEM__govt_org_type__default",
-            )}
+            label={t(`SYSTEM__govt_org_type__${
+              lastLevel?.metadata?.govt_org_children_type ?? "default"
+            }`)}
src/components/Patient/PatientRegistration.tsx (2)

334-341: Consider using a phone number validation library.

While the current implementation limits phone numbers to 13 digits, consider using a library like libphonenumber-js for:

  • Proper phone number validation
  • Consistent formatting
  • Country code handling
+import { parsePhoneNumber as parsePhoneNumberLib } from 'libphonenumber-js';

-if (e.target.value.length > 13) return;
+const phoneNumber = parsePhoneNumberLib(e.target.value);
+if (!phoneNumber?.isValid()) return;

Also applies to: 375-380


450-501: Enhance date validation for better user experience.

The current date input implementation could be improved:

  1. Add validation for valid date combinations (e.g., February 30th)
  2. Consider using a date picker component for better UX
  3. Add validation for future dates

Consider using a date picker component:

<DatePicker
  value={form.date_of_birth}
  onChange={(date) => setForm((f) => ({ ...f, date_of_birth: date }))}
  maxDate={new Date()}
  minDate={new Date('1900-01-01')}
/>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ad9b270 and aaa7d41.

📒 Files selected for processing (10)
  • crowdin.yml (1 hunks)
  • public/locale/en.json (4 hunks)
  • src/Routers/routes/ConsultationRoutes.tsx (2 hunks)
  • src/components/Patient/PatientInfoCard.tsx (2 hunks)
  • src/components/Patient/PatientRegistration.tsx (8 hunks)
  • src/components/Patient/allergy/list.tsx (1 hunks)
  • src/components/ui/errors.tsx (1 hunks)
  • src/components/ui/input-with-error.tsx (1 hunks)
  • src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx (3 hunks)
  • src/pages/Organization/components/OrganizationSelector.tsx (2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/Patient/allergy/list.tsx

[error] 103-103: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (9)
src/components/Patient/PatientInfoCard.tsx (1)

26-26: LGTM!

The Button import is correctly placed and properly supports the new edit encounter functionality.

src/Routers/routes/ConsultationRoutes.tsx (1)

83-86: 🛠️ Refactor suggestion

Address route inconsistencies and unused parameters.

Several issues to address:

  1. The route uses underscore (questionnaire_response) instead of kebab-case
  2. URL parameters facilityId and encounterId are captured but not used
  3. Inconsistent parameter naming (idresponseId)
-  "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire_response/:id":
+  "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire-response/:id":
-    ({ patientId, id }) => (
+    ({ facilityId, patientId, encounterId, id }) => (
      <QuestionnaireResponseView
-       responseId={id}
+       id={id}
        patientId={patientId}
+       facilityId={facilityId}
+       encounterId={encounterId}
      />
    ),

Let's verify if these parameters are required by the component:

src/pages/Organization/components/OrganizationSelector.tsx (1)

114-134: ⚠️ Potential issue

Add missing key prop to parent div in map.

The parent div in the map iteration is missing a key prop:

-      {selectedLevels.map((level, index) => (
-        <div>
+      {selectedLevels.map((level, index) => (
+        <div key={level.id}>

Likely invalid or redundant comment.

src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx (1)

Line range hint 109-188: Well-structured implementation of InputWithError component!

The refactoring improves error handling and maintains UI consistency across the application.

crowdin.yml (1)

2-3: Improved translation file organization!

The dynamic path structure using {{lang}} and %original_file_name% enhances maintainability of localization files.

public/locale/en.json (1)

670-670: Well-structured validation messages!

The added messages provide clear feedback for:

  • Date of birth validation
  • Phone number format requirements
  • Required field indicators
  • Username format requirements

This enhances the user experience by providing clear validation feedback.

Also applies to: 1415-1415, 1742-1742, 1862-1867

src/components/Patient/PatientRegistration.tsx (3)

11-11: Verify the import paths for InputWithError and InputErrors components.

There was a previous build failure related to the InputWithError import. Ensure that the import paths are correct and the components are properly exported from their respective modules.

#!/bin/bash
# Verify the existence and exports of the UI components
ast-grep --pattern 'export $_ InputWithError' 
ast-grep --pattern 'export $_ InputErrors'

Also applies to: 52-52


523-531: Well implemented age validation!

The age validation implementation is robust:

  • Prevents negative values
  • Automatically calculates year of birth
  • Provides immediate feedback to users

Line range hint 319-635: Well-structured form implementation with robust validation.

The form implementation shows good practices:

  • Consistent error handling using InputWithError
  • Real-time validation feedback
  • Proper state management for form fields
  • Good UX with field dependencies (same phone/address checkboxes)

@@ -86,22 +85,22 @@ export function AllergyList({ patientId, encounterId }: AllergyListProps) {
return (
<Card className="p-0">
<CardHeader className="px-4 py-0 pt-4">
<CardTitle>{t("allergies")}</CardTitle>
<CardTitle>Allergies</CardTitle>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Restore i18n translations for better internationalization.

The removal of translations for table headers and title reduces the application's internationalization capabilities. Consider restoring the translations:

-        <CardTitle>Allergies</CardTitle>
+        <CardTitle>{t("allergies")}</CardTitle>
         // ...
-              <TableHead>Allergen</TableHead>
-              <TableHead>Category</TableHead>
-              <TableHead>Status</TableHead>
-              <TableHead>Criticality</TableHead>
-              <TableHead>Created By</TableHead>
+              <TableHead>{t("allergen")}</TableHead>
+              <TableHead>{t("category")}</TableHead>
+              <TableHead>{t("status")}</TableHead>
+              <TableHead>{t("criticality")}</TableHead>
+              <TableHead>{t("created_by")}</TableHead>

Also applies to: 94-98

</TableRow>
</TableHeader>
<TableBody>
{allergies.results.map((allergy: AllergyIntolerance) => (
<TableRow key={allergy.id}>
<TableRow>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add missing key prop to mapped TableRow.

React requires a unique key prop when mapping over elements:

-              <TableRow>
+              <TableRow key={allergy.id}>

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (1.9.4)

[error] 103-103: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

@rajku-dev
Copy link
Contributor Author

rajku-dev commented Jan 8, 2025

Hey @rithviknishad , I am going to make one more PR with the changes we made, things have gone a little messy here. apologies.

@rajku-dev rajku-dev mentioned this pull request Jan 8, 2025
6 tasks
@github-actions github-actions bot added merge conflict pull requests with merge conflict and removed merge conflict pull requests with merge conflict labels Jan 9, 2025
Copy link

github-actions bot commented Jan 9, 2025

👋 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changes required Deploy-Failed Deplyment is not showing preview merge conflict pull requests with merge conflict
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants