Skip to content

[ENG-783] Added popup to indicate appointment clash/duplication - #16589

Open
shivankacker wants to merge 2 commits into
developfrom
appointment-clash-popup
Open

[ENG-783] Added popup to indicate appointment clash/duplication#16589
shivankacker wants to merge 2 commits into
developfrom
appointment-clash-popup

Conversation

@shivankacker

@shivankacker shivankacker commented Jul 21, 2026

Copy link
Copy Markdown
Member

Proposed Changes

image image

Tagging: @ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate the bug or test the new feature.
  • Update product documentation.
  • Ensure that UI text is placed in I18n files.
  • Prepare a screenshot or demo video for the changelog entry and attach it to the issue.
  • Request peer reviews.
  • Complete QA on mobile devices.
  • Complete QA on desktop devices.
  • Add or update Playwright tests for related changes

Summary by CodeRabbit

  • New Features

    • Added appointment slot conflict alerts for duplicate and overlapping appointments.
    • Users can review the conflicting appointment details, pick another slot, or continue anyway.
    • Added overlapping-slot warnings when proceeding with a conflict.
    • Improved slot-selection and scheduling prompts with clearer conflict-related messaging.
  • Enhancements

    • Updated booking flow controls to require a selected slot before confirming, and improved drawer step behavior.

@github-actions

Copy link
Copy Markdown

⚠️ Merge Checklist Incomplete

Thank you for your contribution! To help us review your PR efficiently, please complete the merge checklist in your PR description.

Your PR will be reviewed once you have marked the appropriate checklist items.

To update the checklist:

  • Change - [ ] to - [x] for completed items
  • Only check items that are relevant to your PR
  • Leave items unchecked if they don't apply

The checklist helps ensure code quality, testing coverage, and documentation are properly addressed.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

Appointment booking now checks selected slots against the patient’s upcoming appointments, displays duplicate or overlap alerts with localized actions, and carries acknowledged-overlap state through desktop and drawer booking flows.

Appointment conflict booking

Layer / File(s) Summary
Conflict alert contract and presentation
src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx, public/locale/en.json
Adds duplicate and clash alert rendering with appointment/resource details, localized messages, close, alternate-slot, and continue-anyway actions.
Slot conflict detection and responsive alert rendering
src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Fetches patient appointments, classifies slot conflicts, resets stale conflict state, forwards button refs, and displays alerts in mobile drawers or desktop popovers.
Booking-flow acknowledgement and warnings
src/pages/Appointments/BookAppointment/BookAppointmentDetails.tsx
Passes conflict context through desktop and drawer pickers, tracks acknowledged overlaps, displays warnings, and updates drawer navigation and confirmation rules.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: appointment conflict/duplication popups.
Description check ✅ Passed The description matches the template broadly, but it omits the issue reference and a textual change list under Proposed Changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch appointment-clash-popup

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds appointment conflict warnings to the booking flow. The main changes are:

  • Detect duplicate and overlapping active appointments.
  • Show responsive conflict alerts with clear follow-up actions.
  • Record explicit acknowledgement when booking a conflicting slot.
  • Add localized conflict and warning messages.

Confidence Score: 5/5

This looks safe to merge.

  • Dismissing a conflict alert now clears the conflicting slot selection.
  • Explicit continuation preserves the selected slot and records acknowledgement.
  • Conflict-query cache entries are separated by facility and patient.
  • No blocking issue was found in the updated code.

Important Files Changed

Filename Overview
src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx Adds conflict detection, responsive alerts, facility-aware query caching, and slot deselection when an alert is dismissed.
src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx Adds the duplicate and overlap alert with actions to select another slot or continue.
src/pages/Appointments/BookAppointment/BookAppointmentDetails.tsx Connects patient and resource context to conflict checks and displays acknowledgement warnings.
public/locale/en.json Adds English translations for conflict alerts, actions, and warnings.

Reviews (2): Last reviewed commit: "fixes" | Re-trigger Greptile

Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an appointment conflict/duplication warning flow to the appointment slot selection UX, so staff get an explicit prompt when selecting a potentially conflicting slot.

Changes:

  • Fetches a patient’s upcoming appointments and checks for “duplicate” (same resource/day) and “clash” (time overlap with another practitioner) when a slot is clicked.
  • Shows a conflict UI (Popover on desktop, Drawer on mobile) with actions to pick another slot or continue anyway, and surfaces a follow-up warning banner after acknowledgement.
  • Adds new i18n strings for the conflict UI.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/pages/Appointments/BookAppointment/BookAppointmentDetails.tsx Tracks conflict acknowledgement state, passes conflict-check context to the slot picker, and shows an acknowledgement warning.
src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx Implements conflict detection (via upcoming appointments query) and renders the conflict prompt UI via Popover/Drawer.
src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx New UI component for the conflict prompt content and actions.
public/locale/en.json Adds translations for conflict prompt, actions, and warning text.

Comment thread src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
Comment thread public/locale/en.json
Comment thread public/locale/en.json Outdated
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx (1)

120-203: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Conflict check can run against stale/incomplete data while patientAppointmentsQuery is still loading.

checkForConflict reads patientAppointmentsQuery.data?.results ?? [] (line 125) directly inside handleSlotClick, with no check against patientAppointmentsQuery.isLoading/isFetching. If the user clicks a slot before this query resolves (e.g. slow network), appointments is treated as an empty list and a genuine duplicate/clash is silently missed — no warning is shown for a conflict that does exist.

Consider disabling slot selection (or short-circuiting handleSlotClick) while patientAppointmentsQuery.isLoading is true, or surfacing a loading state so users don't click through before the check is possible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx` around
lines 120 - 203, Prevent conflict evaluation in handleSlotClick while
patientAppointmentsQuery is loading or fetching, so incomplete appointment data
cannot be treated as conflict-free. Short-circuit before selecting or checking
the slot (or otherwise surface the loading state), while preserving the existing
selection and conflict behavior once patientAppointmentsQuery has finished
loading.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx`:
- Around line 57-63: Add an accessible name to the icon-only close button in
AppointmentConflictAlert by supplying a descriptive aria-label, while preserving
its existing onClick={onClose} behavior and styling.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx`:
- Around line 105-118: Update the patientAppointmentsQuery queryKey to include
facilityId alongside patientId, keeping it synchronized with the facility
queryParams used by the queryFn so facility changes fetch and cache the correct
appointment data for checkForConflict.
- Around line 370-428: Update the conflict alert dismissal paths in
AppointmentSlotPicker’s conflictAlertContent, Drawer onOpenChange, and Popover
onOpenChange handlers so closing via the X, Escape, or outside click clears the
alert and calls handleSlotSelect(undefined). Keep the explicit onContinueAnyway
acknowledgment flow unchanged, and ensure every non-explicit dismissal deselects
the conflicting slot.

---

Outside diff comments:
In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx`:
- Around line 120-203: Prevent conflict evaluation in handleSlotClick while
patientAppointmentsQuery is loading or fetching, so incomplete appointment data
cannot be treated as conflict-free. Short-circuit before selecting or checking
the slot (or otherwise surface the loading state), while preserving the existing
selection and conflict behavior once patientAppointmentsQuery has finished
loading.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6c8aed2a-6d6a-4bbb-868a-2e940654ed65

📥 Commits

Reviewing files that changed from the base of the PR and between 70b2972 and 32186b9.

📒 Files selected for processing (4)
  • public/locale/en.json
  • src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
  • src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
  • src/pages/Appointments/BookAppointment/BookAppointmentDetails.tsx

Comment thread src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

🎭 Playwright Test Results

Status: ✅ Passed
Test Shards: 3

Metric Count
Total Tests 332
✅ Passed 332
❌ Failed 0
⏭️ Skipped 0

📊 Detailed results are available in the playwright-final-report artifact.

Run: #10369

Copilot AI review requested due to automatic review settings July 21, 2026 15:10
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying care-preview with  Cloudflare Pages  Cloudflare Pages

Latest commit: d9997a0
Status: ✅  Deploy successful!
Preview URL: https://a5641da1.care-preview-a7w.pages.dev
Branch Preview URL: https://appointment-clash-popup.care-preview-a7w.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx (5)

209-212: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reset conflict state when the patient changes.

conflictAlert stores a full appointment, but this reset effect excludes patientId. If the picker remains mounted while switching patients, the previous patient’s appointment details can remain attached to the selected slot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx` around
lines 209 - 212, Update the conflict-alert reset useEffect in
AppointmentSlotPicker to include patientId in its dependency array, ensuring
conflictAlert is cleared when the selected patient changes alongside the
existing resource and date changes.

452-465: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use an interface for TokenSlotButton props.

The component currently uses an inline object type. Extract a TokenSlotButtonProps interface, as required by the repository’s TypeScript guidelines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx` around
lines 452 - 465, Replace the inline props object type on TokenSlotButton with a
named TokenSlotButtonProps interface, preserving the existing slot,
availability, selectedSlotId, onClick, className, and ref types, and use that
interface in the component declaration.

Source: Coding guidelines


392-395: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clear acknowledgement when the selected slot changes.

The supplied parent wiring only sets hasOverlapAcknowledged to true. After “Continue anyway,” selecting a different non-conflicting slot can leave the warning displayed for the wrong slot. Add a reset/boolean callback or clear the parent state whenever selection changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx` around
lines 392 - 395, Update the conflict acknowledgement flow around
AppointmentSlotPicker’s onContinueAnyway callback so changing the selected
appointment slot clears the parent’s hasOverlapAcknowledged state. Add or wire a
reset/boolean callback through the relevant selection-change handler, while
preserving the existing onConflictAcknowledged behavior for continuing with the
current conflicting slot.

124-130: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make conflict validation authoritative for every selection path.

While appointments are loading or the query errors, data?.results ?? [] is treated as “no appointments,” allowing the slot to be selected without validation. The first auto-selected slot also goes through handleSlotSelect directly, bypassing handleSlotClick entirely. Block selection until the query succeeds and route automatic selection through the same conflict-aware path.

Also applies to: 193-205, 255-259

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx` around
lines 124 - 130, Make conflict validation authoritative in checkForConflict and
all selection paths: prevent selection while patientAppointmentsQuery is loading
or has errored instead of treating missing results as empty. Route the first
auto-selected slot through handleSlotClick (or the shared conflict-aware
selection flow) rather than calling handleSlotSelect directly, while preserving
normal handleSlotSelect behavior after validation succeeds.

Source: Coding guidelines


423-437: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add an accessible name to the desktop conflict popover. PopoverContent still renders without aria-labelledby/aria-label; reuse the conflict title from AppointmentConflictAlert so assistive tech gets a stable dialog name.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx` around
lines 423 - 437, Add an accessible name to the desktop conflict PopoverContent
in AppointmentSlotPicker by reusing the conflict title exposed by
AppointmentConflictAlert via aria-labelledby or aria-label. Keep the existing
popover behavior and content unchanged while ensuring the rendered dialog has a
stable name for assistive technologies.

Source: Coding guidelines

src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx (1)

69-74: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use locale-aware formatting for appointment timestamps.

These medical timestamps use fixed date-fns formats, so month names, ordering, AM/PM markers, locale, and timezone presentation do not follow the active locale. Use the repository’s localized date/time formatter.

Also applies to: 108-110, 121-124

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx` around
lines 69 - 74, Replace the fixed date-fns format calls in
AppointmentConflictAlert, including the occurrences around existingStart and the
additional timestamp blocks, with the repository’s locale-aware date/time
formatter. Ensure appointment dates and times use the active locale’s ordering,
month names, markers, and timezone presentation while preserving the existing
timestamp values and display structure.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx`:
- Around line 69-74: Replace the fixed date-fns format calls in
AppointmentConflictAlert, including the occurrences around existingStart and the
additional timestamp blocks, with the repository’s locale-aware date/time
formatter. Ensure appointment dates and times use the active locale’s ordering,
month names, markers, and timezone presentation while preserving the existing
timestamp values and display structure.

In `@src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx`:
- Around line 209-212: Update the conflict-alert reset useEffect in
AppointmentSlotPicker to include patientId in its dependency array, ensuring
conflictAlert is cleared when the selected patient changes alongside the
existing resource and date changes.
- Around line 452-465: Replace the inline props object type on TokenSlotButton
with a named TokenSlotButtonProps interface, preserving the existing slot,
availability, selectedSlotId, onClick, className, and ref types, and use that
interface in the component declaration.
- Around line 392-395: Update the conflict acknowledgement flow around
AppointmentSlotPicker’s onContinueAnyway callback so changing the selected
appointment slot clears the parent’s hasOverlapAcknowledged state. Add or wire a
reset/boolean callback through the relevant selection-change handler, while
preserving the existing onConflictAcknowledged behavior for continuing with the
current conflicting slot.
- Around line 124-130: Make conflict validation authoritative in
checkForConflict and all selection paths: prevent selection while
patientAppointmentsQuery is loading or has errored instead of treating missing
results as empty. Route the first auto-selected slot through handleSlotClick (or
the shared conflict-aware selection flow) rather than calling handleSlotSelect
directly, while preserving normal handleSlotSelect behavior after validation
succeeds.
- Around line 423-437: Add an accessible name to the desktop conflict
PopoverContent in AppointmentSlotPicker by reusing the conflict title exposed by
AppointmentConflictAlert via aria-labelledby or aria-label. Keep the existing
popover behavior and content unchanged while ensuring the rendered dialog has a
stable name for assistive technologies.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e1c38c01-9a8c-4fec-be6c-e2ae692ad640

📥 Commits

Reviewing files that changed from the base of the PR and between 32186b9 and d9997a0.

📒 Files selected for processing (3)
  • public/locale/en.json
  • src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
  • src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
💤 Files with no reviewable changes (1)
  • public/locale/en.json

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
Comment thread src/pages/Appointments/BookAppointment/AppointmentSlotPicker.tsx
@github-actions github-actions Bot added the Merge Conflict pull requests with merge conflict label Jul 31, 2026
@github-actions

Copy link
Copy Markdown

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Merge Conflict pull requests with merge conflict needs review needs testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants