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

Refactor Scheduling and Appointments; support for delete schedule, cancel booking, improved date filter in appointments page, etc. #9799

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

Conversation

rithviknishad
Copy link
Member

@rithviknishad rithviknishad commented Jan 6, 2025

Required Backend Changes

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

Based on the comprehensive changes, here are the release notes:

  • New Features

    • Enhanced scheduling capabilities with more detailed availability and session management
    • Added support for creating and managing schedule templates
    • Improved appointment booking and tracking functionality
  • Improvements

    • Refined localization and internationalization support
    • Updated type definitions for more robust data handling
    • Streamlined API interactions for scheduling and appointments
  • Deprecations

    • Deprecated several form field components in favor of shadcn/ui components
    • Replaced follow-up appointment types with more generic appointment types
  • Bug Fixes

    • Improved error handling and data validation for scheduling and appointment workflows

Copy link
Contributor

coderabbitai bot commented Jan 6, 2025

Warning

Rate limit exceeded

@rithviknishad has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 38 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 24a53e2 and d5ffc1b.

📒 Files selected for processing (1)
  • public/locale/en.json (27 hunks)

Walkthrough

This pull request introduces comprehensive changes to the scheduling and appointment management system, focusing on enhancing type definitions, API interactions, and user interface components. The modifications span multiple files across the project, introducing new type structures, refactoring existing components, and updating API integrations for schedule templates, appointments, and availability management.

Changes

File/Group Change Summary
public/locale/en.json Added numerous keys for scheduling, availability types, and session management
src/CAREUI/interactive/WeekdayCheckbox.tsx Refactored day selection with enum and improved type safety
src/Utils/request/errorHandler.ts Made error handling properties optional
src/Utils/request/utils.ts Changed error notification method from Notification to toast
src/Utils/types.ts Expanded Time type to include HH:MM:SS format
src/components/Facility/FacilityUsers.tsx Simplified title prop assignment in Page component
src/components/Form/FormFields/* Added deprecation notices for multiple form field components
src/components/Patient/PatientDetailsTab/Appointments.tsx Updated API import and query function for fetching appointments
src/components/Schedule/* Numerous updates to scheduling components, including new ScheduleTemplateEditForm and adjustments to existing components
src/types/scheduling/* Introduced new types and interfaces for scheduling and appointments
src/types/scheduling/scheduleApis.ts Created new API definition structure for scheduling operations

Assessment against linked issues

Objective Addressed Explanation
Delete functionality for schedules [#9663]
Responsive weekday display [#9738] WeekdayCheckbox component refactored
Appointments page layout [#9764] Partial improvements in date range handling
Slot count and rendering [#9790] Requires further investigation
Schedule exceptions functionality [#9802] Partial improvements in type definitions

Possibly related PRs

Suggested labels

tested, reviewed

Suggested reviewers

  • Jacobjeevan
  • bodhish

Poem

🐰 Scheduling magic, types so bright,
APIs dancing with pure delight,
Slots and templates, now refined,
A rabbit's code, precisely designed!
Hop along the type-safe way! 🌈

Finishing Touches

  • 📝 Generate Docstrings

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

Deploy Preview for care-ohc ready!

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

cypress bot commented Jan 6, 2025

CARE    Run #4219

Run Properties:  status check passed Passed #4219  •  git commit d5ffc1b79a: Refactor Scheduling and Appointments; support for delete schedule, cancel bookin...
Project CARE
Branch Review rithviknishad/feat/schedule-validations
Run status status check passed Passed #4219
Run duration 01m 52s
Commit git commit d5ffc1b79a: Refactor Scheduling and Appointments; support for delete schedule, cancel bookin...
Committer Rithvik Nishad
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 6
View all changes introduced in this branch ↗︎

Copy link

cloudflare-workers-and-pages bot commented Jan 7, 2025

Deploying care-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: d5ffc1b
Status: ✅  Deploy successful!
Preview URL: https://93d8f1dd.care-fe.pages.dev
Branch Preview URL: https://rithviknishad-feat-schedule.care-fe.pages.dev

View logs

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

github-actions bot commented Jan 7, 2025

👋 Hi, @rithviknishad,
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 merge conflict pull requests with merge conflict and removed merge conflict pull requests with merge conflict labels Jan 7, 2025
Copy link

github-actions bot commented Jan 8, 2025

👋 Hi, @rithviknishad,
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 removed the merge conflict pull requests with merge conflict label Jan 8, 2025
@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Jan 9, 2025
Copy link

github-actions bot commented Jan 9, 2025

👋 Hi, @rithviknishad,
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 removed the merge conflict pull requests with merge conflict label Jan 9, 2025
@rithviknishad rithviknishad marked this pull request as ready for review January 9, 2025 14:42
@rithviknishad rithviknishad requested a review from a team as a code owner January 9, 2025 14:42
@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Jan 9, 2025
Copy link

github-actions bot commented Jan 9, 2025

👋 Hi, @rithviknishad,
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 removed the merge conflict pull requests with merge conflict label Jan 9, 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: 20

🧹 Nitpick comments (27)
src/pages/Patient/index.tsx (1)

Line range hint 91-106: Consider extracting appointment filtering logic.

The appointment filtering and sorting logic could be moved to a custom hook to improve reusability and maintainability.

Consider creating a custom hook:

function useFilteredAppointments(appointments: Appointment[], patientId: string) {
  return {
    pastAppointments: useMemo(() => 
      appointments
        ?.filter(appointment => appointment?.patient.id === patientId)
        ?.filter(appointment => 
          dayjs().isAfter(dayjs(appointment.token_slot.start_datetime))
        )
        ?.sort((a, b) => 
          new Date(a.token_slot.start_datetime).getTime() -
          new Date(b.token_slot.start_datetime).getTime()
        ),
      [appointments, patientId]
    ),
    scheduledAppointments: useMemo(() => 
      // Similar logic for scheduled appointments
    ),
  };
}
src/components/Form/FormFields/TextAreaFormField.tsx (1)

22-24: Consider providing migration guide for shadcn/ui textarea

While the deprecation notice is clear, it would be helpful to provide:

  1. A link to shadcn/ui textarea documentation
  2. Example of how to migrate existing usage
  3. Timeline for when this component will be removed
src/components/Form/FormFields/DateFormField.tsx (1)

22-22: Document date handling requirements for migration

Given this component's use in scheduling features and its custom date handling (especially for yesterday() and time support), ensure the migration guide to shadcn/ui date-picker addresses:

  1. Handling of string vs Date values
  2. Past/future date restrictions
  3. Time selection support
src/components/Form/FormFields/RadioFormField.tsx (1)

20-22: Document layout requirements for shadcn/ui radio-group

The current implementation supports multiple layouts (auto, vertical, horizontal, grid). Ensure the migration guide addresses:

  1. How to achieve similar layouts with shadcn/ui
  2. Any CSS customizations needed
src/components/Form/FormFields/SelectFormField.tsx (1)

24-26: Document option handling migration strategy

Both components use sophisticated option handling with callbacks for labels, descriptions, icons, etc. The migration guide should address:

  1. How to map current option callbacks to shadcn/ui's API
  2. Handling of generic type parameters
  3. Migration path for disabled options and custom rendering

Also applies to: 64-66

src/types/scheduling/schedule.ts (4)

45-46: Consider using a more specific date type for 'valid_from' and 'valid_to'

The fields valid_from and valid_to are typed as string, with comments indicating they are datetime values. To enhance type safety and clarity, consider using a more specific type such as Date or a standardized string format like ISO 8601.


65-66: Specify the date format for 'valid_from' and 'valid_to'

In the ScheduleException interface, valid_from and valid_to are typed as string with comments specifying the format as YYYY-MM-DD. It would be beneficial to enforce this format through validation or by creating a custom type to prevent potential format inconsistencies.


97-99: Clarify the key format in 'AvailabilityHeatmapResponse'

The AvailabilityHeatmapResponse interface uses a string index signature for dates. To avoid ambiguity and ensure consistent parsing, specify the expected date format for the keys, such as YYYY-MM-DD.


135-135: Consider using a consistent datetime type for 'booked_on'

The booked_on field in the Appointment interface is typed as string. For consistency and type safety across the codebase, consider using a standardized datetime type or format, similar to other datetime fields.

src/components/Schedule/ScheduleTemplatesList.tsx (1)

94-108: Add error handling for the delete template mutation

The mutation for deleting a schedule template doesn't handle errors. If the deletion fails, the user won't receive any feedback. Consider adding an onError handler to inform the user about the failure.

Apply this diff to include error handling:

 const { mutate: deleteTemplate, isPending } = useMutation({
   mutationFn: mutate(scheduleApis.templates.delete, {
     pathParams: {
       facility_id: facilityId,
       id: template.id,
     },
   }),
   onSuccess: () => {
     toast.success(t("template_deleted"));
     queryClient.invalidateQueries({
       queryKey: ["user-schedule-templates", { facilityId, userId }],
     });
   },
+  onError: () => {
+    toast.error(t("template_delete_failed"));
+  },
 });
src/components/Schedule/ScheduleTemplateForm.tsx (2)

146-158: Add error handling for the create template mutation

The mutation for creating a schedule template lacks error handling. Without an onError handler, failures during the mutation won't provide feedback to the user. Adding error handling improves user experience by notifying them of any issues.

Apply this diff to include error handling:

 const { mutate: createTemplate, isPending } = useMutation({
   mutationFn: mutate(scheduleApis.templates.create, {
     pathParams: { facility_id: facilityId },
   }),
   onSuccess: () => {
     toast.success(t("template_create_success"));
     setOpen(false);
     form.reset();
     queryClient.invalidateQueries({
       queryKey: ["user-schedule-templates", { facilityId, userId }],
     });
   },
+  onError: () => {
+    toast.error(t("template_create_failed"));
+  },
 });

Ensure that you have the template_create_success and template_create_failed keys in your translation files.


207-213: Optimize 'timeAllocationCallout' function to prevent unnecessary renders

The timeAllocationCallout function is called within the render method and uses form.watch, which can cause performance issues due to frequent re-renders. Consider using useMemo to memoize the computed values or restructuring the code to optimize performance.

src/components/Schedule/ScheduleTemplateEditForm.tsx (1)

298-303: Add confirmation prompt before deleting an availability

Deleting an availability immediately upon button click may lead to accidental deletions without user confirmation.

Implement a confirmation dialog to confirm the deletion action:

<Button
  variant="ghost"
  size="icon"
- onClick={() => deleteAvailability()}
+ onClick={() => {
+   if (confirm(t("confirm_delete_availability"))) {
+     deleteAvailability();
+   }
+ }}
  disabled={isDeleting}
  className="text-red-600 hover:text-red-700 hover:bg-red-50"
>
  <CareIcon icon="l-trash" className="text-lg" />
</Button>

Additionally, consider using a modal confirmation for better user experience.

src/components/Schedule/Appointments/AppointmentsPage.tsx (1)

422-499: Refactor repetitive date range selection handlers into a utility function

The date range selection buttons have repetitive code assigning date ranges to qParams. This can be refactored to improve maintainability.

Create a utility function to handle date range updates:

const updateDateRange = (from: Date, to: Date) => {
  setQParams({
    ...qParams,
    date_from: dateQueryString(from),
    date_to: dateQueryString(to),
    slot: null,
  });
};

// Then replace the onClick handlers with calls to updateDateRange
<Button
  variant="link"
  size="xs"
  onClick={() => updateDateRange(subDays(today, 14), today)}
>
  {t("last_fortnight_short")}
</Button>

This refactor reduces duplication and makes it easier to manage date range updates.

src/CAREUI/display/Callout.tsx (1)

44-46: Consider accessibility improvements

While the flex layout is good, consider adding appropriate ARIA roles and labels for better accessibility.

-      <div className="flex-1">
+      <div className="flex-1" role="alert" aria-label={props.badge}>
         <span className="font-medium">{props.children}</span>
       </div>
src/CAREUI/interactive/WeekdayCheckbox.tsx (1)

17-19: Consider adding JSDoc comments for props.

The new props would benefit from JSDoc documentation, especially the format prop which has specific valid values.

Add documentation like this:

interface Props {
+  /** Array of selected days */
   value?: DayOfWeek[];
+  /** Callback when selection changes */
   onChange?: (value: DayOfWeek[]) => void;
+  /** Display format for day names: 
+   * - "alphabet": Single letter (M, T, W...)
+   * - "short": Short name (Mon, Tue, Wed...)
+   * - "long": Full name (Monday, Tuesday...)
+   */
   format?: "alphabet" | "short" | "long";
}
src/Utils/request/errorHandler.ts (1)

90-99: Consider improving error message readability.

While the error handling logic is correct, we could enhance the error message formatting for better readability.

Consider this improvement:

-    toast.error(msg, {
-      description: `${type}: '${loc.join(".")}'`,
+    toast.error(msg, {
+      description: `Location: ${loc.join(" > ")}
+Type: ${type}`,
      duration: 8000,
    });
src/components/Schedule/Appointments/AppointmentTokenCard.tsx (1)

Line range hint 71-73: Address TODO: Implement proper token number generation.

The current implementation uses a temporary fake token number generation system. This should be replaced with a proper backend implementation.

Would you like me to help create a GitHub issue to track the implementation of a proper token number generation system?

src/components/Schedule/ScheduleExceptionsList.tsx (1)

Line range hint 122-128: Address TODO: Implement appointment cancellation information.

The commented-out code suggests a planned feature for showing information about cancelled appointments.

Would you like me to help create a GitHub issue to track the implementation of the appointment cancellation information display?

src/types/scheduling/scheduleApis.ts (2)

140-144: Consider making the cancel reason type more flexible.

The cancel endpoint's reason type is limited to "cancelled" | "entered_in_error". Consider using a more extensible approach to handle future reason types.

-      TBody: Type<{ reason: "cancelled" | "entered_in_error" }>(),
+      TBody: Type<{ reason: CancellationReason }>(),

Add to the types file:

export type CancellationReason = "cancelled" | "entered_in_error" | "no_show" | "other";

96-118: Add documentation for slot-related parameters.

The slot-related APIs would benefit from additional documentation describing the expected format for parameters like day and the structure of TokenSlot.

src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx (1)

72-72: Consider adding error handling for API calls.

The API calls for resource and slot fetching should include error handling to improve user experience when network issues occur.

 const resourcesQuery = useQuery({
   queryKey: ["availableResources", facilityId],
   queryFn: query(scheduleApis.appointments.availableUsers, {
     pathParams: { facility_id: facilityId },
   }),
+  onError: (error) => {
+    toast.error(t("failed_to_fetch_resources"));
+  }
 });

 const slotsQuery = useQuery({
   queryKey: [
     "slots",
     facilityId,
     resource?.id,
     dateQueryString(selectedDate),
   ],
   queryFn: query(scheduleApis.slots.getSlotsForDay, {
     pathParams: { facility_id: facilityId },
     body: {
       user: resource?.id,
       day: dateQueryString(selectedDate),
     },
   }),
   enabled: !!resource && !!selectedDate,
+  onError: (error) => {
+    toast.error(t("failed_to_fetch_slots"));
+  }
 });

Also applies to: 84-84

src/pages/Appoinments/PatientSelect.tsx (1)

22-26: Type updates look good, but consider improving error handling.

The transition to new types (TokenSlot, AppointmentCreateRequest) is implemented correctly. However, the error handling in the mutation could be more specific.

 onError: (error) => {
+  const errorMessage = error?.response?.data?.detail || 
+    error?.message || 
+    t("failed_to_create_appointment");
   Notification.Error({
-    msg: error?.message || t("failed_to_create_appointment"),
+    msg: errorMessage,
   });
 },

Also applies to: 38-38, 74-74

src/components/Schedule/ScheduleExceptionForm.tsx (1)

75-86: Cache invalidation strategy looks good, but consider error handling.

The mutation setup with cache invalidation is well implemented. However, error handling could be improved.

 const { mutate: createException, isPending } = useMutation({
   mutationFn: mutate(scheduleApis.exceptions.create, {
     pathParams: { facility_id: facilityId },
   }),
   onSuccess: () => {
     toast.success(t("exception_created"));
     setOpen(false);
     form.reset();
     queryClient.invalidateQueries({
       queryKey: ["user-schedule-exceptions", { facilityId, userId }],
     });
   },
+  onError: (error) => {
+    toast.error(t("failed_to_create_exception"));
+    console.error("Failed to create exception:", error);
+  },
 });
src/components/Users/UserAvailabilityTab.tsx (1)

245-248: Props drilling could be improved.

Consider using React Context for facilityId and userId as they are passed down to multiple components.

src/components/Schedule/Appointments/AppointmentDetailsPage.tsx (1)

383-395: Consider adding error handling to the cancel mutation.

While the success case is handled, there's no error handling for the cancel mutation. Consider adding an onError handler to show appropriate error messages to users.

 const { mutate: cancelAppointment } = useMutation({
   mutationFn: mutate(scheduleApis.appointments.cancel, {
     pathParams: {
       facility_id: facilityId,
       id: appointment.id,
     },
   }),
   onSuccess: () => {
     queryClient.invalidateQueries({
       queryKey: ["appointment", appointment.id],
     });
   },
+  onError: (error) => {
+    toast.error(error?.message || t("failed_to_cancel_appointment"));
+  },
 });
src/Utils/request/utils.ts (1)

46-49: Consider implementing the suggested type inference improvement.

The TODO comment suggests a valuable improvement to infer types from routes. This would enhance type safety and reduce potential runtime errors.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 12e0938 and 5da3dc2.

📒 Files selected for processing (45)
  • public/locale/en.json (27 hunks)
  • src/CAREUI/display/Callout.tsx (3 hunks)
  • src/CAREUI/interactive/WeekdayCheckbox.tsx (2 hunks)
  • src/Utils/request/errorHandler.ts (2 hunks)
  • src/Utils/request/utils.ts (2 hunks)
  • src/Utils/types.ts (1 hunks)
  • src/components/Facility/FacilityUsers.tsx (1 hunks)
  • src/components/Form/FormFields/DateFormField.tsx (1 hunks)
  • src/components/Form/FormFields/FormField.tsx (1 hunks)
  • src/components/Form/FormFields/RadioFormField.tsx (1 hunks)
  • src/components/Form/FormFields/SelectFormField.tsx (2 hunks)
  • src/components/Form/FormFields/TextAreaFormField.tsx (1 hunks)
  • src/components/Form/FormFields/TextFormField.tsx (1 hunks)
  • src/components/Patient/PatientDetailsTab/Appointments.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx (5 hunks)
  • src/components/Questionnaire/QuestionTypes/QuestionInput.tsx (2 hunks)
  • src/components/Questionnaire/structured/handlers.ts (2 hunks)
  • src/components/Questionnaire/structured/types.ts (3 hunks)
  • src/components/Schedule/Appointments/AppointmentCreatePage.tsx (4 hunks)
  • src/components/Schedule/Appointments/AppointmentDetailsPage.tsx (8 hunks)
  • src/components/Schedule/Appointments/AppointmentTokenCard.tsx (1 hunks)
  • src/components/Schedule/Appointments/AppointmentsPage.tsx (17 hunks)
  • src/components/Schedule/Appointments/utils.ts (3 hunks)
  • src/components/Schedule/ScheduleExceptionForm.tsx (5 hunks)
  • src/components/Schedule/ScheduleExceptionsList.tsx (2 hunks)
  • src/components/Schedule/ScheduleTemplateEditForm.tsx (1 hunks)
  • src/components/Schedule/ScheduleTemplateForm.tsx (17 hunks)
  • src/components/Schedule/ScheduleTemplatesList.tsx (4 hunks)
  • src/components/Schedule/api.ts (0 hunks)
  • src/components/Schedule/helpers.ts (3 hunks)
  • src/components/Schedule/types.ts (0 hunks)
  • src/components/Users/UserAvailabilityTab.tsx (9 hunks)
  • src/components/Users/UserHome.tsx (1 hunks)
  • src/components/ui/sidebar/facility-nav.tsx (1 hunks)
  • src/pages/Appoinments/PatientRegistration.tsx (3 hunks)
  • src/pages/Appoinments/PatientSelect.tsx (3 hunks)
  • src/pages/Appoinments/Schedule.tsx (5 hunks)
  • src/pages/Patient/Utils.tsx (1 hunks)
  • src/pages/Patient/index.tsx (4 hunks)
  • src/types/questionnaire/form.ts (3 hunks)
  • src/types/questionnaire/question.ts (1 hunks)
  • src/types/scheduling/PublicAppointmentApi.ts (1 hunks)
  • src/types/scheduling/schedule.ts (1 hunks)
  • src/types/scheduling/scheduleApis.ts (1 hunks)
  • src/types/user/userApi.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • src/components/Schedule/api.ts
  • src/components/Schedule/types.ts
✅ Files skipped from review due to trivial changes (4)
  • src/components/Form/FormFields/TextFormField.tsx
  • src/components/Facility/FacilityUsers.tsx
  • src/components/Form/FormFields/FormField.tsx
  • src/types/user/userApi.ts
🧰 Additional context used
📓 Learnings (1)
src/CAREUI/interactive/WeekdayCheckbox.tsx (1)
Learnt from: Jacobjeevan
PR: ohcnetwork/care_fe#9747
File: src/CAREUI/interactive/WeekdayCheckbox.tsx:49-49
Timestamp: 2025-01-09T04:11:30.690Z
Learning: When using the `cn()` utility for composing class strings in React components, ensure that each item in the array (including ternary expressions) has a trailing comma according to the Prettier configuration.
🔇 Additional comments (41)
src/pages/Patient/index.tsx (1)

Line range hint 1-29: LGTM! Import statements are well-organized.

The new imports for mutation handling are correctly added and properly organized with the existing imports.

src/components/Form/FormFields/TextAreaFormField.tsx (1)

Line range hint 1-53: Verify impact of FormField deprecation

This component depends on FormField which is also being deprecated. Ensure that the migration to shadcn/ui textarea accounts for this dependency.

Run the following to identify all components using TextAreaFormField:

✅ Verification successful

Migration path for TextAreaFormField is well-defined

The component is correctly marked as deprecated with a clear migration path to shadcn/ui's textarea component. The impact is contained to 6 components that need migration, and the shadcn/ui textarea is already widely adopted across 16 different files in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find all files importing TextAreaFormField
rg -l "TextAreaFormField" --type ts --type tsx

Length of output: 74


Script:

#!/bin/bash
# Search for TextAreaFormField usage with correct file type specs
rg "TextAreaFormField" -t typescript -t javascriptreact -t typescriptreact

# Search for FormField usage to understand dependencies
rg "FormField" -t typescript -t javascriptreact -t typescriptreact

# Look for any shadcn/ui textarea implementations
rg "textarea" -t typescript -t javascriptreact -t typescriptreact

Length of output: 312


Script:

#!/bin/bash
# Find all TypeScript/React files and search for patterns
fd -e ts -e tsx | xargs rg "TextAreaFormField"

# Search for FormField usage
fd -e ts -e tsx | xargs rg "FormField"

# Look for shadcn textarea implementations
fd -e ts -e tsx | xargs rg "from.*[\"']@/components/ui/textarea[\"']"

Length of output: 29415

src/components/Form/FormFields/DateFormField.tsx (1)

Line range hint 1-61: Verify usage in scheduling features

Since this PR involves refactoring scheduling and appointments, we should verify the impact of deprecating this component.

Run the following to find scheduling-related usage:

✅ Verification successful

Deprecation has minimal impact on scheduling features

The component is only used once in src/pages/Appoinments/PatientRegistration.tsx for a basic date of birth input field. No critical scheduling features depend on this component, making it safe to proceed with the deprecation and migration to shadcn/ui's date-picker.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find DateFormField usage in scheduling components
rg -l "DateFormField" --type ts --type tsx | xargs rg -l "schedule|appointment" 

Length of output: 2001


Script:

#!/bin/bash
# Find direct imports and usage of DateFormField in scheduling components
echo "=== Searching for DateFormField imports in scheduling components ==="
rg "import.*DateFormField" "src/components/Schedule/" "src/pages/Appoinments/"

echo -e "\n=== Searching for DateFormField usage patterns ==="
rg "<DateFormField" "src/components/Schedule/" "src/pages/Appoinments/"

Length of output: 615


Script:

#!/bin/bash
# Show the DateFormField usage context in PatientRegistration
echo "=== DateFormField usage context in PatientRegistration ==="
rg -A 5 -B 5 "<DateFormField" src/pages/Appoinments/PatientRegistration.tsx

Length of output: 748

src/components/Form/FormFields/RadioFormField.tsx (1)

Line range hint 77-95: Clarify deprecation status of RadioInput component

The RadioInput component is exported separately but lacks a deprecation notice. Consider:

  1. Adding a deprecation notice
  2. Documenting if it should be migrated to a shadcn/ui component
  3. Updating components that might be using it directly

Run the following to find direct RadioInput usage:

src/components/Schedule/Appointments/AppointmentsPage.tsx (1)

264-266: 🛠️ Refactor suggestion

Handle date range when fetching slots

The slotsQuery is currently fetching slots for a single day (qParams.date_from), but the application supports a date range (date_from to date_to). This may not align with the user's expectations when selecting a date range.

Update the slotsQuery to handle the date range:

queryKey: ["slots", facilityId, qParams.practitioner, qParams.date_from, qParams.date_to],
queryFn: query(scheduleApis.slots.getSlotsForRange, {
  pathParams: { facility_id: facilityId },
  body: {
    user: practitioner?.id ?? "",
-   day: qParams.date_from ?? "",
+   date_from: qParams.date_from ?? "",
+   date_to: qParams.date_to ?? "",
  },
}),

Note: This requires backend support for fetching slots over a date range. Ensure the backend API getSlotsForRange is implemented accordingly.

Please confirm if the backend API supports fetching slots over a date range. If not, consider updating the backend or adjusting the frontend logic.

Also applies to: 268-276

src/pages/Patient/Utils.tsx (1)

19-19: Verify all usages of 'AppointmentPatient' accommodate 'emergency_phone_number'

Adding emergency_phone_number to the AppointmentPatient type requires updates in all components and functions that create or manipulate AppointmentPatient instances to ensure they correctly handle the new property.

Run the following script to identify all usages of AppointmentPatient and verify that they have been updated:

Carefully review each occurrence to confirm that emergency_phone_number is being handled appropriately, preventing potential undefined property access errors.

✅ Verification successful

All usages of AppointmentPatient properly handle emergency_phone_number field

The field is correctly implemented across all components:

  • Forms include proper validation and initialization
  • Display components render the field
  • API types and state management are updated
  • No potential undefined property access issues found
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of 'AppointmentPatient' to ensure compatibility.

# Search for 'AppointmentPatient' across the codebase
rg --type-add 'typescript:*.ts,*.tsx' -ttypescript 'AppointmentPatient'

Length of output: 220


Script:

#!/bin/bash
# Search for AppointmentPatient type definition and usages
echo "=== Searching for type definition ==="
ast-grep --pattern 'type AppointmentPatient = {$$$}'

echo -e "\n=== Searching for interface definition ==="
ast-grep --pattern 'interface AppointmentPatient {$$$}'

echo -e "\n=== Searching for direct usages ==="
rg "AppointmentPatient"

echo -e "\n=== Looking for object creation patterns ==="
rg -A 5 "emergency_phone_number"

Length of output: 11867

src/types/scheduling/PublicAppointmentApi.ts (3)

4-5: LGTM! Import changes align with the refactoring

The replacement of old types with AppointmentCreateRequest and TokenSlot aligns with the broader refactoring of scheduling and appointments functionality.


22-24: LGTM! Improved type safety

The response and body types for createAppointment are now properly typed with Appointment and AppointmentCreateRequest respectively.


11-12: Verify the impact of changing GET to POST method

The HTTP method for getSlotsForDay has been changed from GET to POST. While this allows for a request body, it breaks REST conventions for read operations.

Run this script to check for any frontend components that might be affected by this change:

✅ Verification successful

POST method usage is justified and correctly implemented

While GET is conventional for read operations, POST is appropriate here due to the structured request payload and potential security considerations for user IDs. All frontend components are already correctly using POST with the required body parameters.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for components using getSlotsForDay
rg -l "getSlotsForDay" | while read -r file; do
  echo "=== $file ==="
  rg -A 5 "getSlotsForDay" "$file"
done

Length of output: 2567

src/CAREUI/display/Callout.tsx (2)

19-19: LGTM! Improved vertical spacing

The increased padding (py-2) provides better vertical spacing for the callout component.


32-32: LGTM! Consistent badge styling

The badge styling is well-defined with appropriate border colors for each variant.

src/Utils/types.ts (1)

51-51: Verify time format validation

The Time type now supports both HH:MM and HH:MM:SS formats. Ensure that validation logic in components handles both formats correctly.

Let's check the usage of this type:

✅ Verification successful

Time format validation is properly implemented

The codebase correctly handles both HH:MM and HH:MM:SS formats through the use of standard Date object parsing and the dayjs library. The validation logic in src/components/Schedule/helpers.ts is particularly robust, using ISO date string parsing which supports both formats seamlessly.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find files using the Time type
rg -l "Time\s*[:=]" | while read -r file; do
  echo "=== $file ==="
  # Look for time format validation or parsing
  rg -B 2 -A 2 "Time\s*[:=]" "$file"
done

Length of output: 8179

src/types/questionnaire/form.ts (1)

10-10: LGTM! Updated import for new appointment type

The import change from FollowUpAppointmentRequest to CreateAppointmentQuestion aligns with the refactoring.

src/components/Questionnaire/structured/types.ts (1)

8-11: LGTM! Import paths updated for better organization.

The change from Schedule/types to scheduling/schedule aligns with the broader refactoring effort to improve appointment handling.

src/CAREUI/interactive/WeekdayCheckbox.tsx (2)

6-14: LGTM! Improved type safety with enum.

The introduction of DayOfWeek enum improves type safety and maintains Python's day-of-week convention.


61-65: Verify translation keys exist for all formats.

Ensure all required translation keys exist for the different day formats.

Let's verify the translation keys:

✅ Verification successful

All translation keys are present and properly formatted

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for day translation keys
rg -l "DAYS_OF_WEEK__[0-6]" public/locale/
rg -l "DAYS_OF_WEEK_SHORT__[0-6]" public/locale/

Length of output: 139


Script:

#!/bin/bash
# Check content of en.json and look for day translations
cat public/locale/en.json | jq 'keys' | grep -i "day"
# Also search for any other day-related translation patterns
rg -i "day.*short" public/locale/en.json

Length of output: 908

src/Utils/request/errorHandler.ts (1)

73-76: LGTM! Type improvements enhance error handling flexibility.

The changes to make loc, input, and url properties optional improve the type's flexibility to handle various error scenarios.

src/components/Schedule/helpers.ts (1)

4-4: LGTM! Improved type organization.

The migration from local types to centralized type definitions in @/types/scheduling/schedule improves code organization and maintainability.

Also applies to: 53-53, 65-65

src/components/Schedule/Appointments/AppointmentTokenCard.tsx (1)

12-12: LGTM! Consistent type import.

The import change aligns with the centralized type definitions pattern.

src/components/Schedule/ScheduleExceptionsList.tsx (2)

22-23: LGTM! Improved props structure.

Making facilityId and userId required props improves the component's context clarity and type safety.

Also applies to: 26-30


68-68: LGTM! Enhanced mutation and query invalidation.

The changes properly structure the mutation and query invalidation with the necessary context parameters.

Also applies to: 71-71, 77-80

src/components/Patient/PatientDetailsTab/Appointments.tsx (1)

23-23: LGTM! API migration looks good.

The changes correctly implement the migration from ScheduleAPIs to the new scheduleApis structure. The query function has been properly updated to use the new API endpoints.

Also applies to: 31-31

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

75-75: Verify permission requirements for AVAILABILITY tab.

The visibility condition has been simplified to only check for facilityId, removing the previous editPermissions check. This change could potentially affect access control.

✅ Verification successful

Permission check removal appears intentional and safe

The visibility change to only check facilityId aligns with the codebase patterns. Access control for availability features is likely handled at the API/route level, similar to other facility-scoped features. The removed editPermissions check was potentially redundant.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any permission checks related to availability access
rg -A 5 "availability.*permission|permission.*availability" --type ts --type tsx

# Look for similar permission patterns in other tabs/features
ast-grep --pattern 'hidden: !$_permission'

Length of output: 155


Script:

#!/bin/bash
# Search for permission-related patterns in TypeScript files
rg -t ts "availability.*permission|permission.*availability"

# Search for the UserHome component implementation
rg -t ts "UserHome" -A 5

# Look for hidden prop patterns in tabs
rg -t ts "hidden: .*permission"

# Find any permission-related constants or types
rg -t ts "Permission|permission" -A 3

Length of output: 21167

src/components/Questionnaire/structured/handlers.ts (1)

Line range hint 150-164: LGTM! Handler implementation looks correct.

The new appointment handler properly replaces the old follow_up_appointment handler, maintaining consistent structure with other handlers and correctly handling the appointment creation request.

src/types/scheduling/scheduleApis.ts (2)

1-19: LGTM! Well-structured imports and type definitions.

The imports are well-organized and the type definitions are comprehensive.


20-155: LGTM! API structure follows best practices.

The API structure is well-organized, follows RESTful conventions, and maintains consistent typing throughout. The use of const assertion ensures type safety.

src/components/Questionnaire/QuestionTypes/QuestionInput.tsx (1)

6-6: LGTM! Component transition looks good.

The transition from FollowUpAppointmentQuestion to AppointmentQuestion is implemented correctly, with proper import and usage in the structured question type handler.

Also applies to: 121-122

src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx (1)

29-30: Type safety improvements look good.

The transition to more specific types (CreateAppointmentQuestion) and the use of the new scheduleApis module improves type safety and API organization.

Also applies to: 40-40, 51-51, 55-62

src/components/Schedule/ScheduleExceptionForm.tsx (1)

53-54: Props refactoring improves component reusability.

The transition from passing a user object to specific IDs improves component reusability and reduces prop drilling.

Also applies to: 57-60

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

41-47: Good use of URL-based state management!

The shift from local state to query parameters for view management improves URL shareability and browser navigation support.


198-209: Verify the slot visibility logic.

The new conditional rendering for appointment slots might hide important information for other slot types. Please confirm if this is the intended behavior.

✅ Verification successful

Slot visibility logic is correctly implemented

The conditional rendering is appropriate as slot calculations (number and duration) are only applicable to appointment-type slots. Other slot types (open/closed) are designed without slot-specific properties.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other slot types in the codebase
# to ensure we're not accidentally hiding important information

# Search for slot type definitions
rg -A 2 "slot_type.*=|slot_type.*:" 

Length of output: 4756

src/pages/Appoinments/Schedule.tsx (1)

2-2: Consistent use of date-fns and updated types.

The migration from dayjs to date-fns and the type updates from SlotAvailability to TokenSlot improve consistency across the codebase.

However, verify that all date-fns usage patterns are consistent with the rest of the application.

Also applies to: 31-31, 43-43, 84-84

✅ Verification successful

Date library usage is consistent with the codebase patterns

The use of date-fns in Schedule.tsx follows the established pattern where schedule-related components consistently use date-fns with similar format patterns (HH:mm for time slots). The implementation aligns with other schedule components in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining dayjs usage
# and verify date-fns usage patterns

# Check for any remaining dayjs imports
rg "import.*dayjs"

# Check date-fns usage patterns
rg "import.*date-fns"

Length of output: 2774


Script:

#!/bin/bash
# Check format patterns used with both libraries
echo "=== date-fns format patterns ==="
rg "format\((.*?)\)" -g "*.{ts,tsx}" -A 1

echo -e "\n=== dayjs format patterns ==="
rg "dayjs.*format\((.*?)\)" -g "*.{ts,tsx}" -A 1

# Check for migration documentation
echo -e "\n=== Migration documentation ==="
fd -e md -x grep -l -i "date.\?fns\|dayjs" {} \;

Length of output: 9236

src/components/Schedule/Appointments/AppointmentCreatePage.tsx (1)

37-37: API migration looks good.

The consistent update of API imports and endpoint usage improves code maintainability.

Verify that all API endpoint migrations are complete across the codebase.

Also applies to: 57-57, 78-78, 89-89

✅ Verification successful

API migration verification complete - all endpoints migrated successfully

All schedule-related components consistently use the new scheduleApis import from "@/types/scheduling/scheduleApis" with no remnants of the old API pattern found in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining old API usage

# Search for old API imports
rg "import.*ScheduleAPIs"

# Search for old API usage patterns
rg "ScheduleAPIs\."

Length of output: 49


Script:

#!/bin/bash
# Case-insensitive search for old API patterns with variations
rg -i "scheduleapis|scheduleAPI|scheduleapi" --type ts --type tsx

# Search for new API pattern adoption
rg "scheduleApis" --type ts --type tsx

# Search for any schedule-related API imports to catch variations
rg "import.*schedule.*api" -i --type ts --type tsx

Length of output: 243


Script:

#!/bin/bash
# Search for old API imports using ast-grep
ast-grep --pattern 'import $_ from "$_ScheduleAPI$_"'

# Search for old and new API patterns without file type restrictions
rg "import.*ScheduleAPI" -i
rg "import.*scheduleApis"
rg "ScheduleAPI\." -i
rg "scheduleApis\."

# Find all schedule-related API files to verify migration scope
fd -e ts -e tsx | grep -i "schedule.*api"

Length of output: 5746

src/components/Schedule/Appointments/utils.ts (2)

23-28: Improved type safety and organization.

The consolidation of types and their consistent usage across utility functions enhances code reliability.

Also applies to: 30-33


108-108: Verify the infinite availability implementation.

The AvailabilityHeatmapResponse usage in getInfiniteAvailabilityHeatmap needs verification to ensure it correctly handles the infinite availability case.

✅ Verification successful

The infinite availability implementation is correctly implemented and used consistently.

The AvailabilityHeatmapResponse type properly supports infinite availability, and the codebase correctly handles calculations and display logic for both finite and infinite slots.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of infinite availability
# to ensure consistent implementation

# Search for infinite availability handling
rg -A 5 "Infinity.*total_slots|total_slots.*Infinity"

Length of output: 437


Script:

#!/bin/bash
# Find type definition and usage
ast-grep --pattern 'type AvailabilityHeatmapResponse'
ast-grep --pattern 'interface AvailabilityHeatmapResponse'

# Find where this response type is used
rg -l "AvailabilityHeatmapResponse"

# Look for any validation or transformation of total_slots
rg -A 3 "total_slots" --type typescript

Length of output: 343


Script:

#!/bin/bash
# Check type definitions
cat src/types/scheduling/scheduleApis.ts
cat src/types/scheduling/schedule.ts

# Look for total_slots usage and validation
rg -A 3 "total_slots"

# Look for any validation or transformation patterns
rg -A 3 "(total_slots|availab).*(>|<|===|!==|>=|<=)"

Length of output: 22360

src/components/Schedule/Appointments/AppointmentDetailsPage.tsx (3)

52-57: Well-structured type imports!

The explicit type imports improve type safety and make the code more maintainable.


Line range hint 79-85: Good API standardization!

The switch to scheduleApis and the use of strongly typed request objects improve consistency and type safety.

Also applies to: 99-107


221-224: Improved type safety for status badges!

The use of Partial<Record<Appointment["status"], BadgeProps["variant"]>> ensures type safety when mapping appointment statuses to badge variants.

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

43-47: Good type alignment with the new scheduling system!

The switch from SlotAvailability to TokenSlot and the addition of AppointmentCreateRequest align well with the broader refactoring of the scheduling system.

Also applies to: 74-74

src/Utils/request/utils.ts (1)

57-57: Good switch to toast notifications!

Using toast.error instead of Notification.Error maintains consistency with the application's notification system.

public/locale/en.json (1)

195-200: Well-documented scheduling translations!

The added translations provide clear descriptions for different availability types, improving user understanding of the scheduling system.

src/pages/Patient/index.tsx Show resolved Hide resolved
Comment on lines +148 to +157
<Button
variant="destructive"
disabled={isPending}
onClick={() =>
cancelAppointment({
appointment: appointment.id,
patient: appointment.patient.id,
})
}
>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance UX for appointment cancellation.

The current implementation lacks a confirmation step before cancellation, which could lead to accidental cancellations.

Consider adding a confirmation dialog:

 <Button
   variant="destructive"
   disabled={isPending}
-  onClick={() =>
-    cancelAppointment({
-      appointment: appointment.id,
-      patient: appointment.patient.id,
-    })
+  onClick={() => {
+    const confirmed = window.confirm(t("confirm_cancel_appointment"));
+    if (confirmed) {
+      cancelAppointment({
+        appointment: appointment.id,
+        patient: appointment.patient.id,
+      });
+    }
+  }}
 >
-  <span>{t("cancel")}</span>
+  <span>
+    {isPending ? t("cancelling") : t("cancel")}
+  </span>
 </Button>

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

src/types/scheduling/schedule.ts Show resolved Hide resolved
src/types/scheduling/schedule.ts Show resolved Hide resolved
@@ -19,7 +18,7 @@ export interface StructuredDataMap {
symptom: Symptom;
diagnosis: Diagnosis;
encounter: Encounter;
follow_up_appointment: FollowUpAppointmentRequest;
appointment: CreateAppointmentQuestion;
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Review QuestionnaireEditor's appointment type selector

The type change is safe, but there's one UI component that needs attention:

  • src/components/Questionnaire/QuestionnaireEditor.tsx still uses follow_up_appointment as a select option value
🔗 Analysis chain

Verify the impact of appointment type changes.

The transition from follow_up_appointment to appointment suggests a more generic approach to appointment handling. This change could affect existing questionnaires that specifically use follow-up appointments.

Let's verify the usage:

Also applies to: 32-32

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to follow_up_appointment
rg -i "follow_up_appointment" --type ts --type tsx

# Search for components using the old types
ast-grep --pattern 'import { $_ } from "@/components/Schedule/types"'

Length of output: 150


Script:

#!/bin/bash
# Search for both old and new appointment types
rg -i "follow_up_appointment|appointment:" --type typescript

# Search for type definitions and imports
ast-grep --pattern 'type $_ = {
  $$$
  appointment: $_
  $$$
}'

# Search for imports from Questionnaire directory
ast-grep --pattern 'import { $_ } from "$_/Questionnaire/$_"'

Length of output: 228


Script:

#!/bin/bash
# Search for appointment-related types in .ts files
rg -g "*.ts" -g "*.tsx" "follow_up_appointment|appointment:" src/

# Find type definitions and usages
fd -e ts -e tsx . src/ --exec grep -l "CreateAppointmentQuestion\|follow_up_appointment"

# Check imports and type definitions
ast-grep --pattern 'CreateAppointmentQuestion'

Length of output: 2351

@@ -48,7 +48,7 @@ function generateFacilityLinks(

if (user) {
links.push({
name: t("schedules"),
name: t("my_schedules"),
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Missing translations for "my_schedules"

The translation key exists in en.json but is missing in other locale files:

  • hi.json (Hindi)
  • kn.json (Kannada)
  • ml.json (Malayalam)
  • mr.json (Marathi)
  • ta.json (Tamil)
🔗 Analysis chain

Verify translation key exists.

The change from "schedules" to "my_schedules" improves clarity but requires a corresponding translation key.

Let's verify the translation key exists:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if my_schedules key exists in locale files
rg -l "my_schedules" public/locale/

Length of output: 57


Script:

#!/bin/bash
# Check the content of locale files containing my_schedules
rg "my_schedules" public/locale/ -A 1 -B 1

Length of output: 190


Script:

#!/bin/bash
# List all locale files
ls -la public/locale/

Length of output: 494


Script:

#!/bin/bash
# Check my_schedules in all locale files
for file in public/locale/*.json; do
  echo "=== $file ==="
  rg "my_schedules" "$file" -A 1 -B 1
done

Length of output: 1005

@@ -23,7 +23,7 @@ export type StructuredQuestionType =
| "symptom"
| "diagnosis"
| "encounter"
| "follow_up_appointment";
| "appointment";
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Update required in QuestionnaireEditor component

The type change from "follow_up_appointment" to "appointment" is incomplete. Found inconsistency in:

  • src/components/Questionnaire/QuestionnaireEditor.tsx: Still uses the old value "follow_up_appointment" in SelectItem component
🔗 Analysis chain

Verify all consumers are updated for the type change.

The change from "follow_up_appointment" to "appointment" in StructuredQuestionType needs to be reflected in all consuming components.

Let's verify all consumers are updated:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for components using StructuredQuestionType
ast-grep --pattern 'type: "follow_up_appointment"'

# Search for any remaining references
rg -i "follow_up_appointment.*structured" --type ts --type tsx

Length of output: 145


Script:

#!/bin/bash
# Search for any remaining references to the old type
rg "follow_up_appointment" -B 2 -A 2

# Search for current usage of the new type
rg '"appointment"' -B 2 -A 2

# Search for StructuredQuestionType imports and usage
rg "StructuredQuestionType" -B 2 -A 2

Length of output: 18728

Comment on lines +40 to +69
<div className="flex gap-2 md:gap-4">
{[
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY",
].map((day) => {
const dow = DayOfWeek[day as keyof typeof DayOfWeek];
const isSelected = value.includes(dow);

return (
<li key={day}>
<div
className={cn(
"flex flex-col items-center justify-center gap-2 rounded-lg border px-8 py-6 transition-all duration-200 ease-in-out",
isChecked
? "border-primary-500 bg-white shadow"
: "border-gray-300",
)}
>
<Checkbox
id={`day_of_week_checkbox_${day}`}
checked={isChecked}
onCheckedChange={() => handleDayToggle(day)}
/>
<label
htmlFor={`day_of_week_checkbox_${day}`}
className="cursor-pointer text-xs font-semibold uppercase"
onClick={(e) => e.stopPropagation()}
>
{t(`DAYS_OF_WEEK_SHORT__${day}`)}
</label>
</div>
</li>
<Button
key={dow}
type="button"
variant={isSelected ? "outline_primary" : "outline"}
onClick={() => handleDayToggle(dow)}
size={format === "alphabet" ? "icon" : "default"}
>
{format === "alphabet"
? day[0]
: format === "short"
? t(`DAYS_OF_WEEK_SHORT__${dow}`)
: t(`DAYS_OF_WEEK__${dow}`)}
</Button>
);
})}
</ul>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance accessibility for day selection buttons.

The buttons need proper ARIA labels for screen readers.

Apply this improvement:

 <Button
   key={dow}
   type="button"
   variant={isSelected ? "outline_primary" : "outline"}
   onClick={() => handleDayToggle(dow)}
   size={format === "alphabet" ? "icon" : "default"}
+  aria-pressed={isSelected}
+  aria-label={t(`DAYS_OF_WEEK__${dow}`)}
 >
   {format === "alphabet"
     ? day[0]
     : format === "short"
       ? t(`DAYS_OF_WEEK_SHORT__${dow}`)
       : t(`DAYS_OF_WEEK__${dow}`)}
 </Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="flex gap-2 md:gap-4">
{[
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY",
].map((day) => {
const dow = DayOfWeek[day as keyof typeof DayOfWeek];
const isSelected = value.includes(dow);
return (
<li key={day}>
<div
className={cn(
"flex flex-col items-center justify-center gap-2 rounded-lg border px-8 py-6 transition-all duration-200 ease-in-out",
isChecked
? "border-primary-500 bg-white shadow"
: "border-gray-300",
)}
>
<Checkbox
id={`day_of_week_checkbox_${day}`}
checked={isChecked}
onCheckedChange={() => handleDayToggle(day)}
/>
<label
htmlFor={`day_of_week_checkbox_${day}`}
className="cursor-pointer text-xs font-semibold uppercase"
onClick={(e) => e.stopPropagation()}
>
{t(`DAYS_OF_WEEK_SHORT__${day}`)}
</label>
</div>
</li>
<Button
key={dow}
type="button"
variant={isSelected ? "outline_primary" : "outline"}
onClick={() => handleDayToggle(dow)}
size={format === "alphabet" ? "icon" : "default"}
>
{format === "alphabet"
? day[0]
: format === "short"
? t(`DAYS_OF_WEEK_SHORT__${dow}`)
: t(`DAYS_OF_WEEK__${dow}`)}
</Button>
);
})}
</ul>
</div>
<div className="flex gap-2 md:gap-4">
{[
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY",
].map((day) => {
const dow = DayOfWeek[day as keyof typeof DayOfWeek];
const isSelected = value.includes(dow);
return (
<Button
key={dow}
type="button"
variant={isSelected ? "outline_primary" : "outline"}
onClick={() => handleDayToggle(dow)}
size={format === "alphabet" ? "icon" : "default"}
aria-pressed={isSelected}
aria-label={t(`DAYS_OF_WEEK__${dow}`)}
>
{format === "alphabet"
? day[0]
: format === "short"
? t(`DAYS_OF_WEEK_SHORT__${dow}`)
: t(`DAYS_OF_WEEK__${dow}`)}
</Button>
);
})}
</div>

Comment on lines +101 to 109
function onSubmit(data: FormValues) {
createException({
reason: data.reason,
valid_from: dateQueryString(data.valid_from),
valid_to: dateQueryString(data.valid_to),
start_time: data.start_time,
end_time: data.end_time,
user: user.id,
user: userId,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

The time range validation suggestion is valid and necessary.

The form currently lacks validation to ensure end time is after start time, which could lead to invalid schedule exceptions. The suggested implementation aligns with the codebase patterns, using existing toast notifications and translations.

🔗 Analysis chain

Consider validating time ranges in form submission.

The onSubmit function should validate that the end time is after the start time.

 function onSubmit(data: FormValues) {
+  const startTime = new Date(`1970-01-01T${data.start_time}`);
+  const endTime = new Date(`1970-01-01T${data.end_time}`);
+
+  if (endTime <= startTime) {
+    toast.error(t("end_time_must_be_after_start_time"));
+    return;
+  }
+
   createException({
     reason: data.reason,
     valid_from: dateQueryString(data.valid_from),
     valid_to: dateQueryString(data.valid_to),
     start_time: data.start_time,
     end_time: data.end_time,
     user: userId,
   });
 }
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Get the complete content of ScheduleExceptionForm.tsx
fd ScheduleExceptionForm.tsx --exec cat {}

# Look for similar form components with time validation
fd -e tsx -e ts | grep -i "schedule.*form" | xargs cat

# Search for validation-related functions
rg -g "*.{ts,tsx}" "function.*valid.*time" -A 5

# Check toast usage patterns
rg -g "*.{ts,tsx}" "toast\." -A 2

# Check translation patterns related to time
rg -g "*.{ts,tsx}" "t\([\"'].*time.*[\"']\)"

Length of output: 66460

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)
public/locale/en.json (2)

196-196: Fix typo in closed availability description.

There's a typo in the word "Inidcates" which should be "Indicates".

-  "SCHEDULE_AVAILABILITY_TYPE_DESCRIPTION__closed": "Inidcates the practitioner is not available for in this session's time",
+  "SCHEDULE_AVAILABILITY_TYPE_DESCRIPTION__closed": "Indicates the practitioner is not available for in this session's time"

898-898: Consider more descriptive labels for time-related keys.

While the time-related keys are consistent, consider making them more descriptive to better distinguish between different types of time settings (e.g., session end time vs. schedule end time).

-  "end_time": "End Time",
+  "end_time": "Session End Time",
-  "start_time": "Start Time",
+  "start_time": "Session Start Time"

Also applies to: 1648-1650, 1779-1780

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5da3dc2 and 24a53e2.

📒 Files selected for processing (1)
  • public/locale/en.json (27 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cloudflare Pages: care-fe
🔇 Additional comments (5)
public/locale/en.json (5)

657-658: LGTM! Keys follow consistent naming pattern.

The schedule template related keys are well-structured and maintain consistency with the existing naming conventions.

Also applies to: 779-779


1653-1667: LGTM! Comprehensive session configuration keys.

The session configuration keys provide complete coverage for managing schedule sessions, including time settings, type selection, slot configuration, and weekday selection. The descriptions are clear and user-friendly.


1651-1652: LGTM! Clear template management keys with helpful placeholders.

The schedule remarks and template naming keys are well-structured with clear, user-friendly placeholders that guide users on expected input.

Also applies to: 1661-1663


1438-1438: LGTM! Well-structured slot configuration with helpful feedback.

The slot configuration keys are comprehensive and include a helpful allocation callout that provides immediate feedback about slot duration based on configuration.

Also applies to: 1657-1660, 1828-1828


928-928: LGTM! Complete coverage for schedule validity and exceptions.

The keys provide comprehensive support for managing schedule template validity periods and exceptions, following consistent naming patterns.

Also applies to: 1940-1942, 1998-1998

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

github-actions bot commented Jan 9, 2025

👋 Hi, @rithviknishad,
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 removed the merge conflict pull requests with merge conflict label Jan 9, 2025
@rithviknishad rithviknishad self-assigned this Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Review required
1 participant