diff --git a/public/locale/en.json b/public/locale/en.json
index ead37516fa7..a3d0f4ec52d 100644
--- a/public/locale/en.json
+++ b/public/locale/en.json
@@ -1215,6 +1215,7 @@
"choose_state": "Choose State",
"choose_your_login_method_to_continue": "Choose your login method to continue",
"chosen_encounter": "Chosen Encounter",
+ "chosen_overlapping_slots_warning": "You've chosen overlapping slots. You can still book both if the patient is okay with it.",
"chronic_condition_one": "Chronic Condition",
"chronic_condition_other": "Chronic Conditions",
"claim__add_item": "Add Item",
@@ -1249,6 +1250,7 @@
"claim__use__claim": "Claim",
"claim__use__preauthorization": "Pre Authorization",
"claims": "Claims",
+ "clash_new_slot_overlaps": "The new slot selected with {{resourceName}} at {{time}} overlaps slightly.",
"class": "Class",
"class_history": "Class History",
"classification": "Classification",
@@ -1536,6 +1538,7 @@
"contexts": "Contexts",
"continue": "Continue",
"continue_and_clear": "Continue and Clear",
+ "continue_anyway": "Continue anyway",
"continue_watching": "Continue watching",
"contribute_github": "Contribute on Github",
"copied_to_clipboard": "Copied to clipboard!",
@@ -3568,6 +3571,7 @@
"moving_camera": "Moving Camera",
"mrp": "MRP",
"multi_invoice": "Multi Invoice",
+ "multiple_appointment_alert": "Multiple Appointment Alert",
"multiple_users_linked_to_phone": "Multiple users linked to this phone number",
"multiple_users_linked_to_phone_hint": "Enter your username so we can reset the correct account.",
"must_be_greater_than_value": "Must be greater than {{value}}",
@@ -4242,6 +4246,7 @@
"patient__volunteer-contact": "Volunteer Contact",
"patient_address": "Patient Address",
"patient_age": "Age",
+ "patient_already_has_appointment_on": "This patient already has an appointment on",
"patient_and_billing_details": "Patient and billing details",
"patient_basics": "Patient Basics",
"patient_birth_year_for_identity": "Please enter the patient's year of birth to verify their identity",
@@ -4396,6 +4401,7 @@
"phone_number_validation_error": "Entered phone number is not valid",
"phone_number_verified": "Phone Number Verified",
"pick_a_date": "Pick a date",
+ "pick_another_slot": "Pick another slot",
"pin": "PIN",
"pin_page": "Pin/Add to Overview",
"pin_page_already_pinned_description": "This page is already pinned to your dashboard. You can unpin it from the dashboard if you wish to pin a different page.",
@@ -6140,6 +6146,7 @@
"time_of_death": "Time of death",
"time_slot": "Time Slot",
"time_slots_per_day": "Time slot per day",
+ "timing_clash_alert": "Timing clash alert!",
"title": "Title",
"title_is_required": "Title is required",
"title_of_request": "Title of Request",
@@ -6252,6 +6259,7 @@
"try_different_abha_linking_option": "Want to try a different linking option, here are some more:",
"try_different_search": "Try a different search term",
"try_different_search_terms": "Try different search terms",
+ "trying_to_book_another_slot_same_doctor": "You're trying to book another slot with the same doctor at:",
"tube": "Tube",
"two_factor_authentication": "Two Factor Authentication",
"two_factor_authentication_active": "Two-factor authentication is currently active on your account.",
@@ -6655,6 +6663,7 @@
"welcome_back": "Welcome back!",
"welcome_back_to_hospital_dashboard": "Welcome back to the overview ",
"what_facility_assign_the_patient_to": "What facility would you like to assign the patient to",
+ "what_would_you_like_to_do": "What would you like to do?",
"whatsapp_number": "Whatsapp Number",
"whatsapp_number_same_as_phone_number": "WhatsApp number is same as phone number",
"why_the_asset_is_not_working": "Why the asset is not working?",
diff --git a/src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx b/src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
new file mode 100644
index 00000000000..1f50e5ca173
--- /dev/null
+++ b/src/pages/Appointments/BookAppointment/AppointmentConflictAlert.tsx
@@ -0,0 +1,168 @@
+import { format } from "date-fns";
+import { MessageCircleWarning, X } from "lucide-react";
+import { Trans, useTranslation } from "react-i18next";
+
+import { Button } from "@/components/ui/button";
+
+import { ScheduleResourceIcon } from "@/components/Schedule/ScheduleResourceIcon";
+import {
+ Appointment,
+ formatScheduleResourceName,
+ SchedulableResourceType,
+ ScheduleResource,
+ TokenSlot,
+} from "@/types/scheduling/schedule";
+
+export type AppointmentConflictType = "duplicate" | "clash";
+
+interface AppointmentConflictAlertProps {
+ type: AppointmentConflictType;
+ conflictingAppointment: Appointment;
+ newSlot: Pick;
+ newResource?: ScheduleResource;
+ onPickAnotherSlot: () => void;
+ onContinueAnyway: () => void;
+ onClose: () => void;
+}
+
+export const AppointmentConflictAlert = ({
+ type,
+ conflictingAppointment,
+ newSlot,
+ newResource,
+ onPickAnotherSlot,
+ onContinueAnyway,
+ onClose,
+}: AppointmentConflictAlertProps) => {
+ const { t } = useTranslation();
+
+ const existingStart = new Date(
+ conflictingAppointment.token_slot.start_datetime,
+ );
+ const newStart = new Date(newSlot.start_datetime);
+
+ return (
+