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

Appointment as structured question + other enhancements #9661

Merged
merged 8 commits into from
Jan 2, 2025

Conversation

rithviknishad
Copy link
Member

@rithviknishad rithviknishad commented Jan 2, 2025

Proposed Changes

  • Fixes #issue_number
  • Change 1
  • Change 2
  • More?

@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

  • New Features

    • Added follow-up appointment functionality to the questionnaire.
    • Introduced ability to select time and time slots.
    • Added new localization strings for time selection.
    • Implemented a print feature for appointment details.
    • Enhanced appointment list visibility by adjusting layout.
  • Bug Fixes

    • Refined appointment status checking logic.
  • Style

    • Updated layout and styling for appointment and questionnaire components.
    • Adjusted button and container spacing.

Copy link
Contributor

coderabbitai bot commented Jan 2, 2025

Walkthrough

This pull request introduces enhancements to the application's follow-up appointment functionality. The changes include the addition of new localization strings, the creation of a dedicated React component for handling follow-up appointment questions, updates to type definitions, and modifications to existing questionnaire and scheduling components to integrate the new feature effectively.

Changes

File Change Summary
public/locale/en.json Added new localization keys: "select_time", "select_time_slot", and "slots_left"
src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx New component for handling follow-up appointment questions
src/components/Questionnaire/QuestionTypes/QuestionInput.tsx Added import and rendering support for FollowUpAppointmentQuestion
src/components/Questionnaire/structured/handlers.ts Added handler for follow_up_appointment with getRequests method; modified getRequests for encounter
src/components/Questionnaire/structured/types.ts Added FollowUpAppointmentRequest interface; updated StructuredDataMap and StructuredRequestMap
src/components/Schedule/Appointments/AppointmentCreatePage.tsx Minor layout adjustment in button class
src/components/Schedule/Appointments/AppointmentDetailsPage.tsx Added print functionality and updated button logic based on appointment status
src/components/Schedule/Appointments/AppointmentsPage.tsx Adjusted appointment list height and updated SlotFilter props for better filtering
src/components/Schedule/types.ts Added FollowUpAppointmentRequest interface
src/types/questionnaire/form.ts Updated ResponseValue type to include follow-up appointment
src/types/questionnaire/question.ts Added "follow_up_appointment" to StructuredQuestionType

Possibly related PRs

Suggested labels

needs review, tested, P1

Suggested reviewers

  • Jacobjeevan

Poem

🐰 Hop, hop, a new feature springs to life!
Follow-up appointments cut through strife
Slots and times, now crystal clear
Questionnaires dance with rabbit cheer
Technology blooms, precise and bright! 🌟


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

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit e696114
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/6776be9731998300088a66ac
😎 Deploy Preview https://deploy-preview-9661--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.

@github-actions github-actions bot added the Deploy-Failed Deplyment is not showing preview label Jan 2, 2025
Copy link

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

Deploying care-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: e696114
Status: ✅  Deploy successful!
Preview URL: https://baa4da5f.care-fe.pages.dev
Branch Preview URL: https://rithviknishad-feat-follow-up.care-fe.pages.dev

View logs

Copy link

cypress bot commented Jan 2, 2025

CARE    Run #4141

Run Properties:  status check passed Passed #4141  •  git commit e69611413e: Appointment as structured question + other enhancements
Project CARE
Branch Review rithviknishad/feat/follow-up-question
Run status status check passed Passed #4141
Run duration 01m 07s
Commit git commit e69611413e: Appointment as structured question + other enhancements
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 3
View all changes introduced in this branch ↗︎

@rithviknishad rithviknishad changed the title Rithviknishad/feat/follow up question Appointment as structured question + other enhancements Jan 2, 2025
@rithviknishad rithviknishad removed the Deploy-Failed Deplyment is not showing preview label Jan 2, 2025
@rithviknishad rithviknishad marked this pull request as ready for review January 2, 2025 16:14
@rithviknishad rithviknishad requested a review from a team as a code owner January 2, 2025 16:14
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 (11)
src/components/Questionnaire/structured/handlers.ts (1)

156-171: Add Null Check for Array Access

The new follow_up_appointment handler expects [0] to exist in followUpAppointment. Consider adding a safeguard for cases where the array might be empty to avoid potential runtime errors.

+    if (!followUpAppointment.length) {
+      return [];
+    }
src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx (2)

22-39: Props and Interface Naming

FollowUpVisitQuestionProps is well-defined. However, consider harmonizing naming conventions with other structured question components (e.g., FollowUpAppointmentQuestionProps) for better consistency.

-interface FollowUpVisitQuestionProps {
+interface FollowUpAppointmentQuestionProps {

97-218: UI Rendering and Edge Cases

The component correctly handles loading states, absence of slots, and merges user input back into the questionnaire. Adding user feedback for partial or invalid input might further enhance usability, but this looks good overall.

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

359-363: Use of isSameDay Check

Ensuring that the “check-in” and “start consultation” buttons are disabled for days other than the current day is logical. Confirm no user scenario requires same-day logic across midnight boundaries (e.g., late-night appointments).


Line range hint 412-426: Marking Appointments as Fulfilled

The approach to restrict “fulfill” to the day of the appointment only is intuitive but might be too limiting in certain workflows (e.g., backdating or retroactive fulfillment). Keep an eye on user feedback.

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

15-15: Confirm usage scenarios.
getFakeTokenNumber is an interesting helper. If you plan to pivot to the real token numbers in the future, ensure that you maintain consistent usage across the codebase.


132-132: Keep function boundaries small.
Consider splitting any heavy logic (like constructing HTML content) into helper functions if printAppointment grows longer.

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

698-698: Edge case handling.
Validate or log a message if no slots are found. The current logic gracefully returns early, but consider a user-facing message to clarify “No available slots.”


710-714: Improve readability.
For the schedule time display, .replace(":00", "") makes sense for dropping trailing zeros. Confirm that removing minutes is valid for all locales/time formats.


734-734: Button size consistency.
Using className="min-w-60" is consistent with prior usage. Ensure it aligns well with responsive designs and text length.

public/locale/en.json (1)

1839-1839: Check for potential duplication.
"view_patient": "View Patient" is already a common phrase. Confirm no duplication or conflicting usage in UI strings.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b58db6a and bbfa7da.

📒 Files selected for processing (13)
  • public/locale/en.json (3 hunks)
  • src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx (1 hunks)
  • src/components/Questionnaire/QuestionTypes/QuestionInput.tsx (2 hunks)
  • src/components/Questionnaire/QuestionnaireForm.tsx (1 hunks)
  • src/components/Questionnaire/structured/handlers.ts (2 hunks)
  • src/components/Questionnaire/structured/types.ts (3 hunks)
  • src/components/Schedule/Appointments/AppointmentCreatePage.tsx (1 hunks)
  • src/components/Schedule/Appointments/AppointmentDetailsPage.tsx (7 hunks)
  • src/components/Schedule/Appointments/AppointmentsPage.tsx (4 hunks)
  • src/components/Schedule/Appointments/utils.ts (2 hunks)
  • src/components/Schedule/types.ts (1 hunks)
  • src/types/questionnaire/form.ts (3 hunks)
  • src/types/questionnaire/question.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/components/Questionnaire/QuestionnaireForm.tsx
  • src/components/Schedule/Appointments/AppointmentCreatePage.tsx
🔇 Additional comments (29)
src/types/questionnaire/form.ts (3)

1-1: Clean and straightforward import.
Importing FollowUpAppointmentQuestionRequest aligns with the introduced follow-up appointment feature.


25-26: Extending the union with a new structured type.
Incorporating "follow_up_appointment" within ResponseValue.type correctly broadens the feature set to handle follow-up appointment data.


38-39: Ensuring consistency for the new data structure.
Adding FollowUpAppointmentQuestionRequest to ResponseValue.value supports capturing the relevant details in questionnaire responses.

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

1-4: New imports for scheduling and appointments.
Introducing AppointmentCreate and FollowUpAppointmentQuestionRequest from @/components/Schedule/types is a valid approach to extend the questionnaire with scheduling data.


25-25: New property in StructuredDataMap.
This addition allows the questionnaire to store follow-up appointment details.


36-36: Extending StructuredRequestMap for appointment creation.
Mapping "follow_up_appointment" to AppointmentCreate ensures streamlined request handling of follow-up appointments.

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

25-26: New structured question type.
Adding "follow_up_appointment" to StructuredQuestionType is consistent with the recently introduced scheduling data.

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

108-111: Well-defined interface for follow-up appointments.
FollowUpAppointmentQuestionRequest neatly captures the essential data for scheduling a follow-up appointment.

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

Line range hint 132-154: Remove Unused Context Parameter

You removed facilityId from context and updated the logic to return an empty array if there’s no encounterId. This seems like a valid simplification. Just ensure the rest of the codebase no longer relies on the old facilityId parameter.

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

5-6: Import Statement for FollowUpAppointmentQuestion

The import of FollowUpAppointmentQuestion is straightforward and aligns with the new question type. Make sure to keep your imports organized if more question components are added in the future.


166-167: Proper Integration of Follow-Up Appointment Case

Adding the "follow_up_appointment" case in the switch statement ensures the correct rendering of the new question type. The approach is consistent with how other structured questions are handled.

src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx (3)

1-21: Imports and Basic Setup

All essential dependencies are properly imported, including react-query, date utilities, UI components, and hooks. This cohesive setup looks good, but be mindful of bundle size if additional libraries are introduced in the future.


40-69: Local State & Data Handling

Initializing local state for resource and selectedDate is a good approach. The handleUpdate method merges updates precisely onto existing values. This structure appears clean.


70-95: Conditional React Query for Slots

Using enabled: !!resource && !!selectedDate to avoid extraneous fetches is a solid best practice. This prevents unnecessary queries and optimizes performance.

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

14-15: Leverage isSameDay for Appointment Status

Replacing “Appointment Has Started” with isSameDay is a simpler approach for controlling same-day statuses. Confirm that future or next-day appointments intended for partial check-ins are not mistakenly excluded.


41-44: Printing Utility

Importing and calling printAppointment centralizes printing logic. Make sure the utility gracefully handles missing or incomplete data (e.g., if appointment or facility lacks certain details).


136-143: Print Button Layout

The new print button next to the save button is cohesive. This offers a convenient user workflow for quickly printing or saving appointment details.


163-171: Navigate to Patient Verification

This ensures a seamless transition for viewing patients from the appointment context. Be mindful of any potential need to carry additional query parameters for specialized patient checks.


353-353: New onViewPatient Prop

The additional prop for onViewPatient in AppointmentActionsProps properly extends the interface to handle patient navigation. No issues found.


393-407: “View Patient” Button

Displaying “view patient” only when the status is “booked” is a sensible channel to confirm patient identity prior to check-in. You might revisit if it is beneficial for other statuses as well.

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

10-11: Use named imports carefully.
Imports for TFunction and toast look good. Confirm that they are properly utilized in any newly added functions to prevent dead code or unexpected bundler issues.


13-13: Check for potential shape mismatches.
Ensure that FacilityModel aligns with the facility properties consumed by printAppointment, especially if you plan to display or format facility attributes that may not exist in the model.


23-27: Good consolidation of utilities.
Adding formatPatientAge to the import block looks consistent with other date/time or formatting utilities.

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

388-388: Slightly increased height.
Switching from calc(100vh-22rem) to calc(100vh-18rem) shrinks the margin, increasing visible list height by 4rem. Looks good for displaying more appointment items, but verify design acceptance.


681-682: Ensure new props are used consistently.
The newly introduced disableInline and disabled props expand the SlotFilter usage. Confirm that the parent component sets appropriate boolean values for these new props.


687-691: Exporting SlotFilter.
Exporting SlotFilter is helpful for reusability. Check if it’s imported in other files, ensuring consistent usage patterns.


702-706: Disable logic for the "all" tab.
The TabsTrigger with disabled={props.disabled} is a good addition. Double-check if your UI visually differs when the tab is disabled (for clarity to the user).

public/locale/en.json (2)

1591-1592: New i18n keys for time selection.
Keys "select_time" and "select_time_slot" appear correct. Confirm usage and references in appointment booking or scheduling components.


1636-1636: Ensure dynamic interpolation.
"slots_left" might need a placeholder if you plan dynamic insertion (e.g., "{count} slots left"). Keep an eye on usage.

Comment on lines +133 to +401
Token No.
</label>
<p
style="
font-size: 3rem; /* text-5xl */
font-weight: 700; /* font-bold */
line-height: 1; /* leading-none */
margin: 0;
"
>
${getFakeTokenNumber(appointment)}
</p>
</div>
</div>
</div>

<!-- Bottom row: Practitioner & date/time + QR -->
<div
style="
margin-top: 1rem; /* mt-4 */
display: flex; /* flex */
justify-content: space-between; /* justify-between */
"
>
<div
style="
display: flex;
flex-direction: column;
row-gap: 0.5rem; /* space-y-2 approximation */
"
>
<div>
<label
style="
font-size: 0.875rem; /* text-sm */
font-weight: 500; /* font-medium */
"
>
Practitioner:
</label>
<p
style="
font-size: 0.875rem; /* text-sm */
font-weight: 600; /* font-semibold */
margin: 0.25rem 0 0 0;
"
>
${appointment.resource.first_name} ${appointment.resource.last_name}
</p>
</div>
<div>
<p
style="
font-size: 0.875rem; /* text-sm */
font-weight: 600; /* font-semibold */
color: #4B5563; /* text-gray-600 */
margin: 0.25rem 0 0 0;
"
>
${format(appointment.token_slot.start_datetime, "MMMM d, yyyy")}, ${format(appointment.token_slot.start_datetime, "h:mm a")} - ${format(appointment.token_slot.end_datetime, "h:mm a")}
</p>
</div>
</div>
<div>
<!-- Example QR (as <svg>) -->
<svg
height="64"
width="64"
viewBox="0 0 29 29"
role="img"
>
<path
fill="#FFFFFF"
d="M0,0 h29v29H0z"
shape-rendering="crispEdges"
></path>
<path
fill="#000000"
d="M0 0h7v1H0zM9 0h1v1H9zM12 0h2v1H12zM15 0h1v1H15zM19 0h1v1H19zM22,0 h7v1H22zM0 1h1v1H0zM6 1h1v1H6zM12 1h6v1H12zM20 1h1v1H20zM22 1h1v1H22zM28,1 h1v1H28zM0 2h1v1H0zM2 2h3v1H2zM6 2h1v1H6zM8 2h4v1H8zM13 2h1v1H13zM18 2h1v1H18zM22 2h1v1H22zM24 2h3v1H24zM28,2 h1v1H28zM0 3h1v1H0zM2 3h3v1H2zM6 3h1v1H6zM8 3h1v1H8zM11 3h1v1H11zM14 3h2v1H14zM17 3h4v1H17zM22 3h1v1H22zM24 3h3v1H24zM28,3 h1v1H28zM0 4h1v1H0zM2 4h3v1H2zM6 4h1v1H6zM8 4h1v1H8zM10 4h1v1H10zM16 4h4v1H16zM22 4h1v1H22zM24 4h3v1H24zM28,4 h1v1H28zM0 5h1v1H0zM6 5h1v1H6zM8 5h5v1H8zM15 5h1v1H15zM22 5h1v1H22zM28,5 h1v1H28zM0 6h7v1H0zM8 6h1v1H8zM10 6h1v1H10zM12 6h1v1H12zM14 6h1v1H14zM16 6h1v1H16zM18 6h1v1H18zM20 6h1v1H20zM22,6 h7v1H22zM8 7h1v1H8zM10 7h2v1H10zM14 7h2v1H14zM20 7h1v1H20zM0 8h1v1H0zM2 8h5v1H2zM11 8h2v1H11zM15 8h3v1H15zM22 8h5v1H22zM3 9h1v1H3zM7 9h2v1H7zM10 9h1v1H10zM13 9h2v1H13zM18 9h3v1H18zM22 9h1v1H22zM24 9h2v1H24zM28,9 h1v1H28zM6 10h2v1H6zM10 10h1v1H10zM13 10h4v1H13zM20 10h3v1H20zM24 10h4v1H24zM0 11h3v1H0zM4 11h1v1H4zM8 11h1v1H8zM10 11h1v1H10zM12 11h2v1H12zM18 11h1v1H18zM23 11h3v1H23zM27,11 h2v1H27zM1 12h3v1H1zM6 12h1v1H6zM8 12h1v1H8zM10 12h1v1H10zM14 12h2v1H14zM17 12h5v1H17zM23 12h1v1H23zM26 12h1v1H26zM0 13h2v1H0zM3 13h3v1H3zM7 13h1v1H7zM9 13h1v1H9zM11 13h1v1H11zM16 13h1v1H16zM19 13h1v1H19zM21 13h2v1H21zM24 13h2v1H24zM27,13 h2v1H27zM0 14h1v1H0zM3 14h1v1H3zM6 14h1v1H6zM8 14h1v1H8zM10 14h2v1H10zM15 14h1v1H15zM20 14h1v1H20zM22 14h3v1H22zM2 15h1v1H2zM8 15h2v1H8zM14 15h1v1H14zM16 15h1v1H16zM20 15h1v1H20zM23 15h2v1H23zM4 16h4v1H4zM11 16h2v1H11zM15 16h1v1H15zM17 16h3v1H17zM21 16h1v1H21zM23 16h1v1H23zM25,16 h4v1H25zM0 17h2v1H0zM3 17h1v1H3zM7 17h1v1H7zM9 17h1v1H9zM11 17h1v1H11zM13 17h2v1H13zM16 17h2v1H16zM19 17h1v1H19zM22 17h1v1H22zM24 17h2v1H24zM28,17 h1v1H28zM0 18h1v1H0zM2 18h2v1H2zM5 18h3v1H5zM9 18h1v1H9zM12 18h5v1H12zM18 18h1v1H18zM20 18h1v1H20zM23 18h3v1H23zM27 18h1v1H27zM0 19h1v1H0zM3 19h1v1H3zM5 19h1v1H5zM8 19h4v1H8zM13 19h1v1H13zM18 19h1v1H18zM21 19h1v1H21zM23 19h3v1H23zM27,19 h2v1H27zM0 20h1v1H0zM2 20h2v1H2zM6 20h1v1H6zM8 20h2v1H8zM14 20h2v1H14zM17 20h2v1H17zM20 20h5v1H20zM26 20h2v1H26zM8 21h1v1H8zM10 21h3v1H10zM16 21h1v1H16zM19 21h2v1H19zM24 21h1v1H24zM27,21 h2v1H27zM0 22h7v1H0zM11 22h1v1H11zM15 22h3v1H15zM19 22h2v1H19zM22 22h1v1H22zM24 22h1v1H24zM26 22h1v1H26zM0 23h1v1H0zM6 23h1v1H6zM8 23h1v1H8zM10 23h1v1H10zM14 23h3v1H14zM20 23h1v1H20zM24 23h1v1H24zM27 23h1v1H27zM0 24h1v1H0zM2 24h3v1H2zM6 24h1v1H6zM8 24h1v1H8zM11 24h2v1H11zM15 24h3v1H15zM20 24h7v1H20zM0 25h1v1H0zM2 25h3v1H2zM6 25h1v1H6zM8 25h1v1H8zM10 25h1v1H10zM12 25h1v1H12zM14 25h1v1H14zM18 25h1v1H18zM21 25h1v1H21zM23 25h1v1H23zM25 25h1v1H25zM27,25 h2v1H27zM0 26h1v1H0zM2 26h3v1H2zM6 26h1v1H6zM8 26h2v1H8zM11 26h2v1H11zM14 26h3v1H14zM19 26h1v1H19zM22 26h1v1H22zM24 26h4v1H24zM0 27h1v1H0zM6 27h1v1H6zM10 27h2v1H10zM19 27h2v1H19zM23 27h2v1H23zM27 27h1v1H27zM0 28h7v1H0zM8 28h1v1H8zM11 28h1v1H11zM15 28h4v1H15zM21 28h1v1H21zM23 28h1v1H23zM26 28h1v1H26z"
shape-rendering="crispEdges"
></path>
</svg>
</div>
</div>
</div>
</div>
</div>

</body>
</html>
`);

printWindow.document.close();

// Wait for content to load before printing
printWindow.onload = () => {
printWindow.print();
printWindow.onafterprint = () => printWindow.close();
};
};
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

Validate new inline styling for maintainability.
This newly added printAppointment function utilizes a large inlined HTML block with tailwind classes and direct styling attributes. While it may be acceptable for a quick solution, it can become difficult to maintain or update.

-    printWindow.document.write(`
-      <html>
-        ...
-    `);
+    // Consider: build the HTML string with smaller templated parts 
+    // or move styling to a dedicated CSS file for maintainability.

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

@@ -797,4 +812,4 @@ function SlotFilter({ selectedSlot, onSelect, ...props }: SlotFilterProps) {
</SelectContent>
</Select>
);
}
};
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

Clean up unreachable code.
There seems to be a second return statement for <Select>. If this code is never reached, consider removing it to avoid confusion.

-  return (
-    <Select value={selectedSlot ?? "all"} onValueChange={onSelect}>
-      ...
-    </Select>
-  );

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

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/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx (2)

40-68: Enhance type safety in state management.

Consider improving type safety in the following areas:

  1. The type casting of questionnaireResponse values
  2. The handleUpdate function's value merging

Apply this diff to improve type safety:

-  const values =
-    (questionnaireResponse.values?.[0]
-      ?.value as unknown as FollowUpAppointmentRequest[]) || [];
+  const values = (questionnaireResponse.values?.[0]?.value ?? []) as FollowUpAppointmentRequest[];

-  const value = values[0] ?? {};
+  const value: FollowUpAppointmentRequest = values[0] ?? {
+    reason_for_visit: '',
+    slot_id: undefined,
+  };

   const handleUpdate = (updates: Partial<FollowUpAppointmentRequest>) => {
-    const followUpAppointment = { ...value, ...updates };
+    const followUpAppointment: FollowUpAppointmentRequest = { ...value, ...updates };
     updateQuestionnaireResponseCB({

95-216: Enhance form accessibility.

While the UI is well-structured, consider improving accessibility for better user experience.

Add the following accessibility enhancements:

  1. Add aria-labels and descriptions:
   <Textarea
     placeholder={t("reason_for_visit_placeholder")}
     value={value.reason_for_visit || ""}
     onChange={(e) => handleUpdate({ reason_for_visit: e.target.value })}
     disabled={disabled}
+    aria-label={t("reason_for_visit")}
+    aria-required={question.required}
   />

   <Select
     disabled={resourcesQuery.isLoading || disabled}
     value={resource?.id}
+    aria-label={t("select_practitioner")}
+    aria-required={question.required}
   >
  1. Add error announcements for screen readers:
   {resourcesQuery.isError && (
-    <div className="text-red-500">
+    <div className="text-red-500" role="alert" aria-live="polite">
       {t("error_fetching_doctors")}
     </div>
   )}
  1. Add loading announcements:
   {slotsQuery.isLoading && (
+    <div className="sr-only" role="status" aria-live="polite">
+      {t("loading_slots")}
+    </div>
   )}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bbfa7da and e696114.

📒 Files selected for processing (4)
  • src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx (1 hunks)
  • src/components/Questionnaire/structured/types.ts (3 hunks)
  • src/components/Schedule/types.ts (1 hunks)
  • src/types/questionnaire/form.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/Questionnaire/structured/types.ts
  • src/components/Schedule/types.ts
  • src/types/questionnaire/form.ts
🔇 Additional comments (2)
src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx (2)

1-38: Well-organized imports and clear type definitions!

The code demonstrates good organization with logically grouped imports and a well-defined props interface.


1-216: Verify all translation keys are defined.

Please ensure all translation keys used in the component are defined in the localization files.

Run the following script to verify translation keys:

✅ Verification successful

All translation keys are properly defined in the localization files

The verification script checked for all translation keys used in the component:

  • reason_for_visit
  • reason_for_visit_placeholder
  • select_practitioner
  • show_all
  • select_date
  • select_time
  • no_slots_available
  • select_time_slot
  • slots_left

All keys were found in the localization files under public/locale/, as indicated by the exit code 0 for each key check.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if all translation keys used in the component are defined in the localization files.

# Extract translation keys from the component
KEYS=(
  "reason_for_visit"
  "reason_for_visit_placeholder"
  "select_practitioner"
  "show_all"
  "select_date"
  "select_time"
  "no_slots_available"
  "select_time_slot"
  "slots_left"
)

# Check if keys exist in the localization files
echo "Checking translation keys..."
for key in "${KEYS[@]}"; do
  rg -q "\"$key\":" public/locale/
  if [ $? -ne 0 ]; then
    echo "Warning: Translation key '$key' not found"
  fi
done

Length of output: 1033

Comment on lines +69 to +93
const facilityId = useSlug("facility");

const resourcesQuery = useQuery({
queryKey: ["availableResources", facilityId],
queryFn: query(ScheduleAPIs.appointments.availableDoctors, {
pathParams: { facility_id: facilityId },
}),
});

const slotsQuery = useQuery({
queryKey: [
"slots",
facilityId,
resource?.id,
dateQueryString(selectedDate),
],
queryFn: query(ScheduleAPIs.slots.getSlotsForDay, {
pathParams: { facility_id: facilityId },
body: {
resource: resource?.id,
day: dateQueryString(selectedDate),
},
}),
enabled: !!resource && !!selectedDate,
});
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

Add error handling for data fetching.

The queries lack error handling which could lead to poor user experience when network requests fail.

Consider adding error handling and loading states:

   const resourcesQuery = useQuery({
     queryKey: ["availableResources", facilityId],
     queryFn: query(ScheduleAPIs.appointments.availableDoctors, {
       pathParams: { facility_id: facilityId },
     }),
+    retry: 2,
+    onError: (error) => {
+      // Handle error (e.g., show toast notification)
+      console.error('Failed to fetch available doctors:', error);
+    }
   });

   const slotsQuery = useQuery({
     queryKey: [
       "slots",
       facilityId,
       resource?.id,
       dateQueryString(selectedDate),
     ],
     queryFn: query(ScheduleAPIs.slots.getSlotsForDay, {
       pathParams: { facility_id: facilityId },
       body: {
         resource: resource?.id,
         day: dateQueryString(selectedDate),
       },
     }),
     enabled: !!resource && !!selectedDate,
+    retry: 2,
+    onError: (error) => {
+      // Handle error (e.g., show toast notification)
+      console.error('Failed to fetch slots:', error);
+    }
   });

Also, consider displaying error states in the UI:

{resourcesQuery.isError && (
  <div className="text-red-500">
    {t("error_fetching_doctors")}
  </div>
)}

{slotsQuery.isError && (
  <div className="text-red-500">
    {t("error_fetching_slots")}
  </div>
)}

@@ -17,6 +22,7 @@ export interface StructuredDataMap {
symptom: Symptom;
diagnosis: Diagnosis;
encounter: Encounter;
follow_up_appointment: FollowUpAppointmentQuestionRequest;
Copy link
Member

Choose a reason for hiding this comment

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

Concerned about the naming here

@gigincg gigincg merged commit 5b1050c into develop Jan 2, 2025
24 checks passed
@gigincg gigincg deleted the rithviknishad/feat/follow-up-question branch January 2, 2025 16:34
Copy link

github-actions bot commented Jan 2, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants