medos-sdk 1.1.9 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/client/MedosClient.d.ts +1 -0
  2. package/dist/client/MedosClient.js +7 -0
  3. package/dist/components/AppointmentCalender.js +22 -8
  4. package/dist/components/AppointmentConfirmationStep.d.ts +4 -0
  5. package/dist/components/AppointmentConfirmationStep.js +50 -52
  6. package/dist/components/AppointmentDateTimeModal.d.ts +4 -0
  7. package/dist/components/AppointmentDateTimeModal.js +216 -165
  8. package/dist/components/AppointmentSummaryStep.d.ts +12 -0
  9. package/dist/components/AppointmentSummaryStep.js +168 -0
  10. package/dist/components/BookingOptionStep.d.ts +14 -0
  11. package/dist/components/BookingOptionStep.js +346 -0
  12. package/dist/components/ContactInformationStep.js +13 -6
  13. package/dist/components/ContactPreferenceStep.js +16 -6
  14. package/dist/components/DoctorSelectModal.d.ts +5 -0
  15. package/dist/components/DoctorSelectModal.js +169 -74
  16. package/dist/components/EnquiryForm.js +84 -72
  17. package/dist/components/Icons/CloseIcon.d.ts +9 -0
  18. package/dist/components/Icons/CloseIcon.js +5 -0
  19. package/dist/components/InquiryDetailsStep.js +11 -6
  20. package/dist/components/PatientDetailsStep.js +17 -12
  21. package/dist/components/PatientSelectionStep.d.ts +12 -0
  22. package/dist/components/PatientSelectionStep.js +254 -0
  23. package/dist/components/PhoneVerificationStep.js +1 -1
  24. package/dist/components/SuccessStep.js +1 -1
  25. package/dist/components/appointment-booking/AppointmentCalender.d.ts +5 -0
  26. package/dist/components/appointment-booking/AppointmentCalender.js +247 -0
  27. package/dist/components/appointment-booking/hooks/index.d.ts +3 -0
  28. package/dist/components/appointment-booking/hooks/index.js +3 -0
  29. package/dist/components/appointment-booking/hooks/useAppointmentFlow.d.ts +8 -0
  30. package/dist/components/appointment-booking/hooks/useAppointmentFlow.js +318 -0
  31. package/dist/components/appointment-booking/hooks/useAppointmentState.d.ts +9 -0
  32. package/dist/components/appointment-booking/hooks/useAppointmentState.js +125 -0
  33. package/dist/components/appointment-booking/hooks/useInitializeAddresses.d.ts +1 -0
  34. package/dist/components/appointment-booking/hooks/useInitializeAddresses.js +55 -0
  35. package/dist/components/appointment-booking/index.d.ts +5 -0
  36. package/dist/components/appointment-booking/index.js +3 -0
  37. package/dist/components/appointment-booking/types.d.ts +291 -0
  38. package/dist/components/appointment-booking/types.js +49 -0
  39. package/dist/components/appointment-modal-styles.d.ts +259 -0
  40. package/dist/components/appointment-modal-styles.js +395 -0
  41. package/dist/components/constant.d.ts +2 -0
  42. package/dist/components/constant.js +15 -0
  43. package/dist/components/custom-calendar.js +20 -11
  44. package/dist/components/styles.js +93 -52
  45. package/dist/components/theme-styles.d.ts +5 -4
  46. package/dist/components/theme-styles.js +221 -125
  47. package/dist/components/types.d.ts +12 -139
  48. package/dist/components/types.js +15 -32
  49. package/dist/components/uiComponents/SelectDropdown.d.ts +1 -1
  50. package/dist/components/uiComponents/SelectDropdown.js +24 -24
  51. package/dist/components/utils.d.ts +3 -0
  52. package/dist/components/utils.js +59 -0
  53. package/dist/components/validation.d.ts +2 -0
  54. package/dist/components/validation.js +41 -0
  55. package/dist/core/theme/index.d.ts +1 -0
  56. package/dist/core/theme/index.js +1 -0
  57. package/dist/core/theme/responsive.d.ts +15 -0
  58. package/dist/core/theme/responsive.js +113 -0
  59. package/dist/core/theme/themes.js +16 -4
  60. package/dist/core/theme/types.d.ts +8 -0
  61. package/dist/enquiry-form/validation.js +1 -1
  62. package/dist/index.d.ts +3 -1
  63. package/dist/index.js +2 -1
  64. package/dist/react/ThemeProvider.d.ts +2 -1
  65. package/dist/react/ThemeProvider.js +49 -10
  66. package/dist/react/index.d.ts +2 -1
  67. package/dist/react/index.js +1 -1
  68. package/dist/services/AppointmentService.d.ts +80 -2
  69. package/dist/services/AppointmentService.js +114 -5
  70. package/dist/services/WorkspaceService.d.ts +58 -3
  71. package/dist/services/WorkspaceService.js +10 -1
  72. package/dist/vanilla/AppointmentCalendarWidget.d.ts +9 -7
  73. package/dist/vanilla/AppointmentCalendarWidget.js +834 -384
  74. package/dist/vanilla/EnquiryFormWidget.d.ts +1 -0
  75. package/dist/vanilla/EnquiryFormWidget.js +25 -43
  76. package/dist/vanilla/client/MedosClient.d.ts +1 -0
  77. package/dist/vanilla/components/AppointmentConfirmationStep.d.ts +4 -0
  78. package/dist/vanilla/components/AppointmentDateTimeModal.d.ts +4 -0
  79. package/dist/vanilla/components/AppointmentSummaryStep.d.ts +12 -0
  80. package/dist/vanilla/components/BookingOptionStep.d.ts +14 -0
  81. package/dist/vanilla/components/DoctorSelectModal.d.ts +5 -0
  82. package/dist/vanilla/components/Icons/CloseIcon.d.ts +9 -0
  83. package/dist/vanilla/components/PatientSelectionStep.d.ts +12 -0
  84. package/dist/vanilla/components/VanillaCalendar.js +33 -18
  85. package/dist/vanilla/components/VanillaIcons.d.ts +5 -0
  86. package/dist/vanilla/components/VanillaIcons.js +92 -0
  87. package/dist/vanilla/components/VanillaSelect.d.ts +3 -0
  88. package/dist/vanilla/components/VanillaSelect.js +93 -5
  89. package/dist/vanilla/components/appointment-booking/AppointmentCalender.d.ts +5 -0
  90. package/dist/vanilla/components/appointment-booking/hooks/index.d.ts +3 -0
  91. package/dist/vanilla/components/appointment-booking/hooks/useAppointmentFlow.d.ts +8 -0
  92. package/dist/vanilla/components/appointment-booking/hooks/useAppointmentState.d.ts +9 -0
  93. package/dist/vanilla/components/appointment-booking/hooks/useInitializeAddresses.d.ts +1 -0
  94. package/dist/vanilla/components/appointment-booking/index.d.ts +5 -0
  95. package/dist/vanilla/components/appointment-booking/types.d.ts +291 -0
  96. package/dist/vanilla/components/appointment-modal-styles.d.ts +259 -0
  97. package/dist/vanilla/components/constant.d.ts +2 -0
  98. package/dist/vanilla/components/theme-styles.d.ts +5 -4
  99. package/dist/vanilla/components/types.d.ts +12 -139
  100. package/dist/vanilla/components/uiComponents/SelectDropdown.d.ts +1 -1
  101. package/dist/vanilla/components/utils.d.ts +3 -0
  102. package/dist/vanilla/components/validation.d.ts +2 -0
  103. package/dist/vanilla/core/theme/index.d.ts +1 -0
  104. package/dist/vanilla/core/theme/responsive.d.ts +15 -0
  105. package/dist/vanilla/core/theme/types.d.ts +8 -0
  106. package/dist/vanilla/enquiry-widget.js +374 -53
  107. package/dist/vanilla/index.d.ts +3 -1
  108. package/dist/vanilla/react/ThemeProvider.d.ts +2 -1
  109. package/dist/vanilla/react/index.d.ts +2 -1
  110. package/dist/vanilla/services/AppointmentService.d.ts +80 -2
  111. package/dist/vanilla/services/WorkspaceService.d.ts +58 -3
  112. package/dist/vanilla/vanilla/AppointmentCalendarWidget.d.ts +9 -7
  113. package/dist/vanilla/vanilla/EnquiryFormWidget.d.ts +1 -0
  114. package/dist/vanilla/vanilla/components/VanillaIcons.d.ts +5 -0
  115. package/dist/vanilla/vanilla/components/VanillaSelect.d.ts +3 -0
  116. package/dist/vanilla/widget.css +833 -207
  117. package/dist/vanilla/widget.js +6463 -5687
  118. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { AppointmentService, } from "../services/AppointmentService";
2
2
  import { PatientService } from "../services/PatientService";
3
3
  import { MedosClient } from "../client/MedosClient";
4
- import { INITIAL_STATE, COUNTRY_CODES, GENDER_OPTIONS, BLOOD_GROUP_OPTIONS, } from "../components/types";
4
+ import { INITIAL_STATE, COUNTRY_CODES, mapBloodGroupToApi, } from "../components/types";
5
5
  import { validatePhoneNumber, validateCountryCode, } from "../components/validation";
6
6
  import { formatDateToISO, parsePatientName } from "../components/utils";
7
7
  import { VanillaIcons } from "./components/VanillaIcons";
@@ -215,7 +215,6 @@ class AppointmentCalendarWidget {
215
215
  this.state.patientState &&
216
216
  this.state.patientCountry &&
217
217
  this.state.patientZipcode &&
218
- this.state.patientEmail &&
219
218
  this.state.patientAge &&
220
219
  this.state.otpVerified;
221
220
  submitBtn.disabled = !(canSubmit && !this.state.loading);
@@ -359,11 +358,11 @@ class AppointmentCalendarWidget {
359
358
  workspaceId: this.state.workspaceId,
360
359
  workspaceAddressId: this.state.selectedAddress,
361
360
  doctorId: this.state.selectedDoctor,
362
- mode: "OFFLINE",
361
+ mode: this.state.consultationMode || "OFFLINE",
363
362
  appointmentDate,
364
363
  fromDateTimeTs,
365
364
  toDateTimeTs,
366
- consultationCharge: this.state.consultationCharge || "0",
365
+ consultationCharge: this.state.consultationMode === "ONLINE" ? "500" : "300",
367
366
  type: "CONSULTATION",
368
367
  source: "SDK_POWERED_WEBSITE",
369
368
  patientPayload: {
@@ -378,6 +377,9 @@ class AppointmentCalendarWidget {
378
377
  gender: this.state.patientGender
379
378
  ? this.state.patientGender.toUpperCase()
380
379
  : undefined,
380
+ bloodGroup: this.state.bloodGroup
381
+ ? mapBloodGroupToApi(this.state.bloodGroup)
382
+ : mapBloodGroupToApi("UNKNOWN"),
381
383
  },
382
384
  patientAddress: patientAddressPayload,
383
385
  });
@@ -396,34 +398,92 @@ class AppointmentCalendarWidget {
396
398
  }
397
399
  goToNext() {
398
400
  if (this.state.step === 0) {
401
+ if (!this.state.otpVerified)
402
+ return;
403
+ this.state.step = 1;
404
+ this.render();
405
+ return;
406
+ }
407
+ if (this.state.step === 1) {
408
+ if (!this.state.bookingOptionType)
409
+ return;
410
+ if (this.state.showPackageExplorer) {
411
+ if (this.state.selectedNewPackage) {
412
+ this.state.showPackageExplorer = false;
413
+ this.state.step = 2;
414
+ this.render();
415
+ }
416
+ return;
417
+ }
418
+ this.state.step = 2;
419
+ this.render();
420
+ return;
421
+ }
422
+ if (this.state.step === 2) {
399
423
  if (this.state.addresses.length > 1 && !this.state.selectedAddress)
400
424
  return;
401
425
  if (this.doctors.length > 1 && !this.state.selectedDoctor)
402
426
  return;
427
+ this.state.step = 3;
428
+ const dateStr = formatDateToISO(this.state.selectedDate);
429
+ if (dateStr) {
430
+ this.loadSlots();
431
+ }
432
+ else {
433
+ this.render();
434
+ }
435
+ return;
436
+ }
437
+ if (this.state.step === 3) {
438
+ const dateStr = formatDateToISO(this.state.selectedDate);
439
+ if (!dateStr || !this.state.selectedSlot)
440
+ return;
441
+ this.state.step = 4;
442
+ this.render();
443
+ return;
444
+ }
445
+ if (this.state.step === 4) {
446
+ if (!this.state.selectedPatient)
447
+ return;
448
+ this.state.step = 5;
449
+ this.render();
450
+ return;
451
+ }
452
+ this.state.step = Math.min(6, this.state.step + 1);
453
+ this.render();
454
+ }
455
+ goBack() {
456
+ if (this.state.step === 1) {
457
+ if (this.state.showPackageExplorer) {
458
+ this.state.showPackageExplorer = false;
459
+ this.state.selectedNewPackage = null;
460
+ this.render();
461
+ return;
462
+ }
463
+ this.state.step = 0;
464
+ this.render();
465
+ return;
466
+ }
467
+ if (this.state.step === 2) {
403
468
  this.state.step = 1;
404
469
  this.render();
405
470
  return;
406
471
  }
407
- const dateStr = formatDateToISO(this.state.selectedDate);
408
- if (this.state.step === 1 && dateStr) {
472
+ if (this.state.step === 3) {
409
473
  this.state.step = 2;
410
- this.loadSlots();
474
+ this.render();
411
475
  return;
412
476
  }
413
- if (this.state.step === 2 && this.state.selectedSlot) {
477
+ if (this.state.step === 4) {
414
478
  this.state.step = 3;
415
479
  this.render();
416
480
  return;
417
481
  }
418
- if (this.state.step === 3 && this.state.otpVerified) {
482
+ if (this.state.step === 5) {
419
483
  this.state.step = 4;
420
484
  this.render();
421
485
  return;
422
486
  }
423
- this.state.step = Math.min(5, this.state.step + 1);
424
- this.render();
425
- }
426
- goBack() {
427
487
  this.state.step = Math.max(0, this.state.step - 1);
428
488
  this.render();
429
489
  }
@@ -444,13 +504,6 @@ class AppointmentCalendarWidget {
444
504
  <div class="medos-appointment-card">
445
505
  <div class="medos-appointment-header">
446
506
  <h2 class="medos-appointment-title">Book Appointment</h2>
447
- <div class="medos-appointment-stepper">
448
- <div class="medos-appointment-step-pill ${this.state.step === 0 ? "active" : ""}">1 Address</div>
449
- <div class="medos-appointment-step-pill ${this.state.step === 1 ? "active" : ""}">2 Date</div>
450
- <div class="medos-appointment-step-pill ${this.state.step === 2 ? "active" : ""}">3 Slot</div>
451
- <div class="medos-appointment-step-pill ${this.state.step === 3 ? "active" : ""}">4 Phone</div>
452
- <div class="medos-appointment-step-pill ${this.state.step === 4 ? "active" : ""}">5 Details</div>
453
- </div>
454
507
  </div>
455
508
 
456
509
  ${this.state.loading
@@ -469,6 +522,30 @@ class AppointmentCalendarWidget {
469
522
  }
470
523
  initializeCustomComponents() {
471
524
  if (this.state.step === 0) {
525
+ const countryCodeContainer = this.container.querySelector("#medos-country-code-container");
526
+ if (countryCodeContainer) {
527
+ const countryOptions = COUNTRY_CODES.map((c) => ({
528
+ value: c.code,
529
+ label: c.label,
530
+ }));
531
+ this.countryCodeSelect = new VanillaSelect(countryCodeContainer, countryOptions, {
532
+ placeholder: "Country",
533
+ onValueChange: (value) => {
534
+ this.state.countryCode = value;
535
+ const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
536
+ if (sendOtpBtn) {
537
+ const canSendOtp = this.state.countryCode &&
538
+ this.state.patientPhone.length >= 10;
539
+ sendOtpBtn.disabled = !canSendOtp;
540
+ }
541
+ },
542
+ });
543
+ if (this.state.countryCode) {
544
+ this.countryCodeSelect.setValue(this.state.countryCode);
545
+ }
546
+ }
547
+ }
548
+ if (this.state.step === 2 && !this.state.showPackageExplorer) {
472
549
  const addressContainer = this.container.querySelector("#medos-address-select-container");
473
550
  if (addressContainer && this.state.addresses.length > 0) {
474
551
  const addressOptions = this.state.addresses.map((a) => ({
@@ -496,7 +573,7 @@ class AppointmentCalendarWidget {
496
573
  onValueChange: (value) => {
497
574
  this.state.selectedDoctor = Number(value) || null;
498
575
  const selectedDoc = this.doctors.find((d) => d.id === this.state.selectedDoctor);
499
- if (selectedDoc && selectedDoc.consultationCharge) {
576
+ if (selectedDoc?.consultationCharge) {
500
577
  this.state.consultationCharge = selectedDoc.consultationCharge;
501
578
  }
502
579
  this.render();
@@ -507,7 +584,7 @@ class AppointmentCalendarWidget {
507
584
  }
508
585
  }
509
586
  }
510
- if (this.state.step === 1) {
587
+ if (this.state.step === 3) {
511
588
  const calendarContainer = this.container.querySelector("#medos-calendar-container");
512
589
  if (calendarContainer) {
513
590
  this.calendar = new VanillaCalendar(calendarContainer, {
@@ -515,237 +592,35 @@ class AppointmentCalendarWidget {
515
592
  pastDisabled: true,
516
593
  onSelect: (date) => {
517
594
  this.state.selectedDate = date;
518
- this.render();
519
- },
520
- });
521
- }
522
- }
523
- if (this.state.step === 3) {
524
- const countryCodeContainer = this.container.querySelector("#medos-country-code-container");
525
- if (countryCodeContainer) {
526
- const countryOptions = COUNTRY_CODES.map((c) => ({
527
- value: c.code,
528
- label: c.label,
529
- }));
530
- this.countryCodeSelect = new VanillaSelect(countryCodeContainer, countryOptions, {
531
- placeholder: "Country",
532
- onValueChange: (value) => {
533
- this.state.countryCode = value;
534
- const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
535
- if (sendOtpBtn) {
536
- const canSendOtp = this.state.countryCode &&
537
- this.state.patientPhone.length >= 10;
538
- sendOtpBtn.disabled = !canSendOtp;
539
- }
540
- },
541
- });
542
- if (this.state.countryCode) {
543
- this.countryCodeSelect.setValue(this.state.countryCode);
544
- }
545
- }
546
- }
547
- if (this.state.step === 4) {
548
- const genderContainer = this.container.querySelector("#medos-gender-container");
549
- if (genderContainer) {
550
- this.genderSelect = new VanillaSelect(genderContainer, GENDER_OPTIONS, {
551
- placeholder: "Select gender",
552
- onValueChange: (value) => {
553
- this.state.patientGender = value;
554
- this.updateSubmitButtonState();
595
+ this.loadSlots();
555
596
  },
556
597
  });
557
- if (this.state.patientGender) {
558
- this.genderSelect.setValue(this.state.patientGender);
559
- }
560
- }
561
- const bloodGroupContainer = this.container.querySelector("#medos-blood-group-container");
562
- if (bloodGroupContainer) {
563
- this.bloodGroupSelect = new VanillaSelect(bloodGroupContainer, BLOOD_GROUP_OPTIONS, {
564
- placeholder: "Select blood group (optional)",
565
- onValueChange: (value) => {
566
- this.state.bloodGroup = value;
567
- },
568
- });
569
- if (this.state.bloodGroup) {
570
- this.bloodGroupSelect.setValue(this.state.bloodGroup);
571
- }
572
598
  }
573
599
  }
574
600
  }
575
601
  renderStep() {
576
602
  switch (this.state.step) {
577
603
  case 0:
578
- return this.renderStep0();
604
+ return this.renderPhoneVerificationStep();
579
605
  case 1:
580
- return this.renderStep1();
606
+ return this.renderBookingOptionStep();
581
607
  case 2:
582
- return this.renderStep2();
608
+ return this.state.showPackageExplorer
609
+ ? this.renderPackageExplorerStep()
610
+ : this.renderLocationDoctorStep();
583
611
  case 3:
584
- return this.renderStep3();
612
+ return this.renderNewAppointmentStep();
585
613
  case 4:
586
- return this.renderStep4();
614
+ return this.renderPatientSelectionStep();
587
615
  case 5:
588
- return this.renderStep5();
616
+ return this.renderAppointmentSummaryStep();
617
+ case 6:
618
+ return this.renderSuccessStep();
589
619
  default:
590
620
  return "";
591
621
  }
592
622
  }
593
- renderStep0() {
594
- const canProceed = this.canProceedFromMergedStep();
595
- return `
596
- <div class="medos-section-card">
597
- <div class="medos-section-header">
598
- ${VanillaIcons.mapPin(14)}
599
- <span class="medos-section-title">Location & Doctor</span>
600
- </div>
601
- <div class="medos-section-body">
602
- <div class="medos-form-group">
603
- <label class="medos-label">Preferred Location <span class="medos-required">*</span></label>
604
- <div id="medos-address-select-container"></div>
605
- </div>
606
- <div class="medos-form-group">
607
- <label class="medos-label">Preferred Doctor <span class="medos-required">*</span></label>
608
- <div id="medos-doctor-select-container"></div>
609
- </div>
610
- <div class="medos-form-group">
611
- <label class="medos-label">Chief Complaint <span class="medos-optional">(optional)</span></label>
612
- <textarea
613
- class="medos-textarea"
614
- id="medos-chief-complaint"
615
- placeholder="Enter Chief Complaint or Appointment Notes"
616
- ></textarea>
617
- </div>
618
- </div>
619
- </div>
620
- <div class="medos-actions">
621
- <button class="medos-btn medos-btn-primary" id="medos-btn-next" ${!canProceed ? "disabled" : ""}>Next</button>
622
- </div>
623
- `;
624
- }
625
- renderStep1() {
626
- const dateStr = formatDateToISO(this.state.selectedDate);
627
- const selectedDoctor = this.doctors.find((d) => d.id === this.state.selectedDoctor);
628
- const selectedDoctorData = this.doctors.find((d) => d.id === this.state.selectedDoctor);
629
- const consultationCharge = selectedDoctorData?.consultationCharge ||
630
- selectedDoctor?.consultationCharge ||
631
- this.state.consultationCharge ||
632
- "N/A";
633
- return `
634
- <div class="medos-section-card">
635
- <div class="medos-section-header">
636
- ${VanillaIcons.consultationType(14)}
637
- <span class="medos-section-title">Consultation Type</span>
638
- </div>
639
- <div class="medos-section-body">
640
- <div class="medos-consultation-options">
641
- <label class="medos-radio-option ${this.state.consultationMode === "OFFLINE" ? "selected" : ""}">
642
- <input
643
- type="radio"
644
- name="consultationMode"
645
- value="OFFLINE"
646
- ${this.state.consultationMode === "OFFLINE" ? "checked" : ""}
647
- class="medos-radio-input"
648
- />
649
- <span class="medos-radio-label">In-Person Visit</span>
650
- </label>
651
- <label class="medos-radio-option ${this.state.consultationMode === "ONLINE" ? "selected" : ""}">
652
- <input
653
- type="radio"
654
- name="consultationMode"
655
- value="ONLINE"
656
- ${this.state.consultationMode === "ONLINE" ? "checked" : ""}
657
- class="medos-radio-input"
658
- />
659
- <span class="medos-radio-label">Online Consultation</span>
660
- </label>
661
- </div>
662
- <div class="medos-consultation-charge">
663
- <span class="medos-charge-label">Consultation Charge:</span>
664
- <span class="medos-charge-value">${consultationCharge !== "N/A"
665
- ? "₹" + consultationCharge
666
- : consultationCharge}</span>
667
- </div>
668
- </div>
669
- </div>
670
-
671
- <div class="medos-section-card">
672
- <div class="medos-section-header">
673
- ${VanillaIcons.dateTime(14)}
674
- <span class="medos-section-title">Select Date</span>
675
- </div>
676
- <div class="medos-section-body">
677
- <div id="medos-calendar-container"></div>
678
- </div>
679
- </div>
680
-
681
- <div class="medos-actions">
682
- <button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
683
- <button class="medos-btn medos-btn-primary" id="medos-btn-next" ${dateStr ? "" : "disabled"}>Next</button>
684
- </div>
685
- `;
686
- }
687
- renderStep2() {
688
- const dateDisplay = this.state.selectedDate
689
- ? this.state.selectedDate.toLocaleDateString("en-US", {
690
- weekday: "long",
691
- year: "numeric",
692
- month: "long",
693
- day: "numeric",
694
- })
695
- : "";
696
- return `
697
- <div class="medos-section-card">
698
- <div class="medos-section-header">
699
- ${VanillaIcons.clock(14)}
700
- <span class="medos-section-title">Select Time Slot</span>
701
- </div>
702
- <div class="medos-section-body">
703
- <div class="medos-selected-date-display">
704
- ${VanillaIcons.dateTime(16)}
705
- <span>${dateDisplay}</span>
706
- </div>
707
- ${this.state.slots.length === 0
708
- ? '<div class="medos-empty-slots">No slots available for selected date</div>'
709
- : `
710
- <div class="medos-slots-grid">
711
- ${this.state.slots
712
- .map((s) => {
713
- const start = new Date(s.start).toLocaleTimeString([], {
714
- hour: "2-digit",
715
- minute: "2-digit",
716
- });
717
- const end = new Date(s.end).toLocaleTimeString([], {
718
- hour: "2-digit",
719
- minute: "2-digit",
720
- });
721
- const selected = this.state.selectedSlot?.start === s.start &&
722
- this.state.selectedSlot?.end === s.end;
723
- return `
724
- <div class="medos-slot-card ${selected ? "selected" : ""}"
725
- data-slot-id="${this.escapeHtml(s.id || `${s.start}-${s.end}`)}"
726
- data-slot-start="${this.escapeHtml(s.start)}"
727
- data-slot-end="${this.escapeHtml(s.end)}">
728
- <span class="medos-slot-time">${start}</span>
729
- <span class="medos-slot-separator">-</span>
730
- <span class="medos-slot-time">${end}</span>
731
- ${selected
732
- ? `<span class="medos-slot-check">${VanillaIcons.check(14)}</span>`
733
- : ""}
734
- </div>
735
- `;
736
- })
737
- .join("")}
738
- </div>
739
- `}
740
- </div>
741
- </div>
742
- <div class="medos-actions">
743
- <button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
744
- <button class="medos-btn medos-btn-primary" id="medos-btn-next" ${this.state.selectedSlot ? "" : "disabled"} style="opacity: ${this.state.selectedSlot ? 1 : 0.6}">Next</button>
745
- </div>
746
- `;
747
- }
748
- renderStep3() {
623
+ renderPhoneVerificationStep() {
749
624
  const countryCodeValid = this.state.countryCode && validateCountryCode(this.state.countryCode);
750
625
  const phoneValid = this.state.patientPhone && validatePhoneNumber(this.state.patientPhone);
751
626
  const canSendOtp = countryCodeValid && phoneValid && !this.state.otpSending;
@@ -754,10 +629,10 @@ class AppointmentCalendarWidget {
754
629
  <div class="medos-section-card">
755
630
  <div class="medos-section-header">
756
631
  ${VanillaIcons.phone(14)}
757
- <span class="medos-section-title">Phone Verification</span>
632
+ <span class="medos-section-title">Search Patient</span>
758
633
  </div>
759
634
  <div class="medos-section-body">
760
- <p class="medos-section-description">Please enter your phone number for verification</p>
635
+ <p class="medos-section-description">Enter Phone Number</p>
761
636
  <div class="medos-phone-input-row">
762
637
  <div class="medos-country-code-wrapper">
763
638
  <div id="medos-country-code-container"></div>
@@ -767,7 +642,7 @@ class AppointmentCalendarWidget {
767
642
  type="tel"
768
643
  class="medos-input"
769
644
  id="medos-phone"
770
- placeholder="Enter phone number"
645
+ placeholder="XXXXXXXXXX"
771
646
  value="${this.escapeHtml(this.state.patientPhone)}"
772
647
  maxlength="15"
773
648
  />
@@ -779,8 +654,8 @@ class AppointmentCalendarWidget {
779
654
  </div>
780
655
  </div>
781
656
  <div class="medos-actions">
782
- <button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
783
- <button class="medos-btn medos-btn-primary" id="medos-btn-send-otp" ${canSendOtp ? "" : "disabled"}>${this.state.otpSending ? "Sending..." : "Send OTP"}</button>
657
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
658
+ <button class="medos-btn medos-btn-primary" id="medos-btn-send-otp" ${canSendOtp ? "" : "disabled"}>${this.state.otpSending ? "Sending..." : "Continue"}</button>
784
659
  </div>
785
660
  `;
786
661
  }
@@ -789,7 +664,7 @@ class AppointmentCalendarWidget {
789
664
  <div class="medos-section-card">
790
665
  <div class="medos-section-header">
791
666
  ${VanillaIcons.phone(14)}
792
- <span class="medos-section-title">Phone Verification</span>
667
+ <span class="medos-section-title">Search Patient</span>
793
668
  </div>
794
669
  <div class="medos-section-body">
795
670
  <div class="medos-verified-badge">
@@ -800,7 +675,7 @@ class AppointmentCalendarWidget {
800
675
  </div>
801
676
  </div>
802
677
  <div class="medos-actions">
803
- <button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
678
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
804
679
  <button class="medos-btn medos-btn-primary" id="medos-btn-next">Continue</button>
805
680
  </div>
806
681
  `;
@@ -834,108 +709,605 @@ class AppointmentCalendarWidget {
834
709
  </div>
835
710
  `;
836
711
  }
837
- renderStep4() {
838
- const canSubmit = this.state.patientName &&
839
- this.state.patientAddress &&
840
- this.state.patientCity &&
841
- this.state.patientState &&
842
- this.state.patientCountry &&
843
- this.state.patientZipcode &&
844
- this.state.otpVerified;
712
+ renderBookingOptionStep() {
713
+ const hasActivePacks = this.state.userSessionPacks.length > 0;
714
+ const activePack = this.state.userSessionPacks.find((p) => p.remainingSessions > 0);
845
715
  return `
846
716
  <div class="medos-section-card">
847
717
  <div class="medos-section-header">
848
- ${VanillaIcons.user(14)}
849
- <span class="medos-section-title">Patient Information</span>
718
+ ${VanillaIcons.calendar(14)}
719
+ <span class="medos-section-title">Choose Booking Option</span>
850
720
  </div>
851
721
  <div class="medos-section-body">
852
- <div class="medos-form-row">
853
- <div class="medos-form-group medos-form-group-flex">
854
- <label class="medos-label">Full Name <span class="medos-required">*</span></label>
855
- <input type="text" class="medos-input" id="medos-patient-name" placeholder="Enter full name" value="${this.escapeHtml(this.state.patientName)}" />
722
+ <p class="medos-section-description">Select a package to explore on offer</p>
723
+
724
+ ${hasActivePacks && activePack
725
+ ? `
726
+ <div class="medos-active-session-packs">
727
+ <label class="medos-form-label">YOUR ACTIVE SESSION PACKS</label>
728
+ <div class="medos-session-pack-card ${this.state.bookingOptionType === "session-pack"
729
+ ? "selected"
730
+ : ""}" data-pack-id="${activePack.id}">
731
+ <div class="medos-pack-header">
732
+ <span class="medos-pack-name">${this.escapeHtml(activePack.name)}</span>
733
+ <span class="medos-pack-badge">${activePack.remainingSessions} sessions</span>
734
+ </div>
735
+ <div class="medos-pack-details">
736
+ ${activePack.remainingSessions} of ${activePack.totalSessions} sessions • <a href="#" class="medos-link">view details</a>
737
+ </div>
738
+ </div>
856
739
  </div>
857
- <div class="medos-form-group medos-form-group-small">
858
- <label class="medos-label">Age</label>
859
- <input type="number" class="medos-input" id="medos-patient-age" placeholder="Age" value="${this.escapeHtml(this.state.patientAge)}" />
740
+ `
741
+ : ""}
742
+
743
+ <div class="medos-other-options">
744
+ <label class="medos-form-label">OTHER OPTIONS</label>
745
+
746
+ <div class="medos-option-cards">
747
+ <div class="medos-option-card ${this.state.bookingOptionType === "new-appointment"
748
+ ? "selected"
749
+ : ""}" data-option="new-appointment">
750
+ <div class="medos-option-icon">${VanillaIcons.calendar(24)}</div>
751
+ <div class="medos-option-content">
752
+ <span class="medos-option-title">Standard Consultation</span>
753
+ <span class="medos-option-subtitle">Pay per appointment</span>
754
+ </div>
755
+ </div>
756
+
757
+ <div class="medos-option-card ${this.state.bookingOptionType === "explore-packages"
758
+ ? "selected"
759
+ : ""}" data-option="explore-packages">
760
+ <div class="medos-option-icon">${VanillaIcons.giftBox(24)}</div>
761
+ <div class="medos-option-content">
762
+ <span class="medos-option-title">Session Packs</span>
763
+ <span class="medos-option-subtitle">Explore packs with discounts and offers</span>
764
+ </div>
765
+ </div>
860
766
  </div>
861
767
  </div>
862
- <div class="medos-form-row">
863
- <div class="medos-form-group medos-form-group-flex">
864
- <label class="medos-label">Email</label>
865
- <input type="email" class="medos-input" id="medos-patient-email" placeholder="patient@example.com" value="${this.escapeHtml(this.state.patientEmail)}" />
866
- </div>
867
- <div class="medos-form-group medos-form-group-small">
868
- <label class="medos-label">Gender</label>
869
- <div id="medos-gender-container"></div>
870
- </div>
768
+ </div>
769
+ </div>
770
+ <div class="medos-actions">
771
+ <button class="medos-btn medos-btn-back" id="medos-btn-back">${VanillaIcons.arrowLeft(14)} Back</button>
772
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
773
+ <button class="medos-btn medos-btn-primary" id="medos-btn-continue">Continue</button>
774
+ </div>
775
+ `;
776
+ }
777
+ renderPackageExplorerStep() {
778
+ const packages = this.state.availablePackages.length > 0
779
+ ? this.state.availablePackages
780
+ : [
781
+ {
782
+ id: 1,
783
+ name: "Silver Package",
784
+ description: "• 3 consultations (In clinic & Online appointments)\n• Can redeem for 6 months after\n purchase",
785
+ totalSessions: 3,
786
+ price: 5000,
787
+ validityDays: 180,
788
+ applicableOnline: true,
789
+ applicableOffline: true,
790
+ },
791
+ {
792
+ id: 2,
793
+ name: "Gold Package",
794
+ description: "• 5 consultations (In clinic & Online appointments)\n• Can redeem for 12 months after\n purchase",
795
+ totalSessions: 5,
796
+ price: 8000,
797
+ validityDays: 365,
798
+ applicableOnline: true,
799
+ applicableOffline: true,
800
+ },
801
+ ];
802
+ return `
803
+ <div class="medos-section-card">
804
+ <div class="medos-section-header">
805
+ ${VanillaIcons.giftBox(14)}
806
+ <span class="medos-section-title">Explore Session Packs</span>
807
+ </div>
808
+ <div class="medos-section-body">
809
+ <p class="medos-section-description">Select a package to explore on offer</p>
810
+
811
+ <div class="medos-available-packages">
812
+ <label class="medos-form-label">AVAILABLE PACKAGES</label>
813
+
814
+ ${packages
815
+ .map((pkg, index) => `
816
+ <div class="medos-package-card ${this.state.selectedNewPackage?.id === pkg.id ? "selected" : ""}" data-package-id="${pkg.id}">
817
+ <div class="medos-package-radio">
818
+ <input type="radio" name="package" value="${pkg.id}" ${this.state.selectedNewPackage?.id === pkg.id ? "checked" : ""} />
819
+ </div>
820
+ <div class="medos-package-content">
821
+ <div class="medos-package-name">${this.escapeHtml(pkg.name)}</div>
822
+ <div class="medos-package-description">${this.escapeHtml(pkg.description || "").replace(/\n/g, "<br>")}</div>
823
+ </div>
824
+ <div class="medos-package-price">₹ ${pkg.price.toLocaleString()}</div>
825
+ </div>
826
+ `)
827
+ .join("")}
828
+ </div>
829
+
830
+ <div class="medos-package-note">
831
+ <a href="#" class="medos-link">View full terms and conditions</a>
832
+ </div>
833
+ </div>
834
+ </div>
835
+ <div class="medos-actions">
836
+ <button class="medos-btn medos-btn-back" id="medos-btn-back">${VanillaIcons.arrowLeft(14)} Back</button>
837
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
838
+ <button class="medos-btn medos-btn-primary" id="medos-btn-continue" ${this.state.selectedNewPackage ? "" : "disabled"}>Continue</button>
839
+ </div>
840
+ `;
841
+ }
842
+ renderLocationDoctorStep() {
843
+ const canProceed = this.canProceedFromMergedStep();
844
+ return `
845
+ <div style="border:1px solid #e5e7eb;border-radius:12px;margin-bottom:24px;background:#fff;">
846
+ <div style="background:#F9FAFB;padding:16px 20px;display:flex;align-items:center;gap:12px;border-bottom:1px solid #E5E7EB;">
847
+ ${VanillaIcons.mapPin(18)}
848
+ <h3 style="font-size:18px;font-weight:600;margin:0;">Location & Doctor</h3>
849
+ </div>
850
+ <div style="padding:24px;">
851
+ <div style="margin-bottom:20px;">
852
+ <label style="display:block;font-size:13px;margin-bottom:6px;color:#374151;">
853
+ Preferred Location <span style="color:#EF4444">*</span>
854
+ </label>
855
+ <div id="medos-address-select-container"></div>
856
+ </div>
857
+ <div style="margin-bottom:20px;">
858
+ <label style="display:block;font-size:13px;margin-bottom:6px;color:#374151;">
859
+ Preferred Doctor <span style="color:#EF4444">*</span>
860
+ </label>
861
+ <div id="medos-doctor-select-container"></div>
862
+ </div>
863
+ <div style="margin-bottom:20px;">
864
+ <label style="display:block;font-size:13px;margin-bottom:6px;color:#374151;">
865
+ Chief Complaint <span style="color:#6B7280">(optional)</span>
866
+ </label>
867
+ <textarea
868
+ style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e6e9ef;font-size:14px;box-sizing:border-box;"
869
+ class="medos-textarea"
870
+ id="medos-chief-complaint"
871
+ placeholder="Enter Chief Complaint or Appointment Notes"
872
+ ></textarea>
873
+ </div>
874
+ </div>
875
+ </div>
876
+ <div style="display:flex;gap:8px;margin-top:16px;justify-content:flex-end;">
877
+ <button class="medos-btn medos-btn-back" id="medos-btn-back">${VanillaIcons.arrowLeft(14)} Back</button>
878
+ <button style="background:#218838;color:#fff;border:none;padding:10px 14px;border-radius:8px;cursor:pointer;font-weight:600;${canProceed ? "" : "opacity:0.6;"}" id="medos-btn-next" ${canProceed ? "" : "disabled"}>Continue</button>
879
+ </div>
880
+ `;
881
+ }
882
+ renderNewAppointmentStep() {
883
+ const dateStr = formatDateToISO(this.state.selectedDate);
884
+ const consultationCharge = this.state.consultationMode === "ONLINE" ? "500" : "300";
885
+ const dateDisplay = this.state.selectedDate
886
+ ? this.state.selectedDate.toLocaleDateString("en-US", {
887
+ year: "numeric",
888
+ month: "long",
889
+ day: "numeric",
890
+ })
891
+ : "";
892
+ const usingSessionPack = this.state.bookingOptionType === "session-pack" &&
893
+ this.state.selectedSessionPack;
894
+ const sessionInfo = usingSessionPack
895
+ ? `
896
+ <div class="medos-session-info">
897
+ <span class="medos-session-label">Sessions:</span>
898
+ <span class="medos-session-value">${this.state.selectedSessionPack?.remainingSessions} appointments now remaining</span>
899
+ </div>
900
+ `
901
+ : "";
902
+ return `
903
+ <div class="medos-section-card">
904
+ <div class="medos-section-header">
905
+ ${VanillaIcons.consultationType(14)}
906
+ <span class="medos-section-title">Consultation Type</span>
907
+ </div>
908
+ <div class="medos-section-body">
909
+ <label class="medos-form-label">Consultation Mode</label>
910
+ <div class="medos-consultation-options">
911
+ <label class="medos-radio-option ${this.state.consultationMode === "OFFLINE" ? "selected" : ""}">
912
+ <input
913
+ type="radio"
914
+ name="consultationMode"
915
+ value="OFFLINE"
916
+ ${this.state.consultationMode === "OFFLINE" ? "checked" : ""}
917
+ class="medos-radio-input"
918
+ />
919
+ <span class="medos-radio-label">Online</span>
920
+ </label>
921
+ <label class="medos-radio-option ${this.state.consultationMode === "ONLINE" ? "selected" : ""}">
922
+ <input
923
+ type="radio"
924
+ name="consultationMode"
925
+ value="ONLINE"
926
+ ${this.state.consultationMode === "ONLINE" ? "checked" : ""}
927
+ class="medos-radio-input"
928
+ />
929
+ <span class="medos-radio-label">Offline</span>
930
+ </label>
931
+ </div>
932
+ </div>
933
+ </div>
934
+
935
+ <div class="medos-section-card">
936
+ <div class="medos-section-header">
937
+ ${VanillaIcons.dateTime(14)}
938
+ <span class="medos-section-title">Date & Time</span>
939
+ </div>
940
+ <div class="medos-section-body medos-datetime-layout">
941
+ <div class="medos-calendar-section">
942
+ <label class="medos-form-label">Available Dates</label>
943
+ <div class="medos-date-display">${dateDisplay}</div>
944
+ <div id="medos-calendar-container"></div>
871
945
  </div>
872
- <div class="medos-form-group">
873
- <label class="medos-label">Blood Group <span class="medos-optional">(optional)</span></label>
874
- <div id="medos-blood-group-container"></div>
946
+ <div class="medos-slots-section">
947
+ <label class="medos-form-label">Available Slots</label>
948
+ ${this.state.slots.length === 0
949
+ ? '<div class="medos-empty-slots">Select a date to see available slots</div>'
950
+ : `
951
+ <div class="medos-slots-grid-compact">
952
+ ${this.state.slots
953
+ .map((s) => {
954
+ const start = new Date(s.start).toLocaleTimeString([], {
955
+ hour: "2-digit",
956
+ minute: "2-digit",
957
+ });
958
+ const end = new Date(s.end).toLocaleTimeString([], {
959
+ hour: "2-digit",
960
+ minute: "2-digit",
961
+ });
962
+ const selected = this.state.selectedSlot?.start === s.start &&
963
+ this.state.selectedSlot?.end === s.end;
964
+ return `
965
+ <div class="medos-slot-btn ${selected ? "selected" : ""}"
966
+ data-slot-id="${this.escapeHtml(s.id || `${s.start}-${s.end}`)}"
967
+ data-slot-start="${this.escapeHtml(s.start)}"
968
+ data-slot-end="${this.escapeHtml(s.end)}">
969
+ ${start}
970
+ </div>
971
+ `;
972
+ })
973
+ .join("")}
974
+ </div>
975
+ `}
875
976
  </div>
876
977
  </div>
877
978
  </div>
878
979
 
980
+ <div class="medos-actions">
981
+ <button class="medos-btn medos-btn-back" id="medos-btn-back">${VanillaIcons.arrowLeft(14)} Back</button>
982
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
983
+ <button class="medos-btn medos-btn-primary" id="medos-btn-continue" ${this.state.selectedSlot ? "" : "disabled"}>Continue</button>
984
+ </div>
985
+ `;
986
+ }
987
+ renderPatientSelectionStep() {
988
+ const patients = this.state.verifiedPatients.length > 0
989
+ ? this.state.verifiedPatients
990
+ : [
991
+ {
992
+ id: 1,
993
+ firstName: "Mumma",
994
+ lastName: "Bear",
995
+ email: "mumma@example.com",
996
+ countryCode: "+91",
997
+ phoneNumber: this.state.patientPhone,
998
+ dob: "1970-01-01",
999
+ age: 55,
1000
+ gender: "FEMALE",
1001
+ bloodGroup: "O+",
1002
+ mrn: "MRN001",
1003
+ address: {
1004
+ id: 1,
1005
+ completeAddress: "123 Main St",
1006
+ addressLine1: "123 Main St",
1007
+ addressLine2: "",
1008
+ city: "Mumbai",
1009
+ state: "Maharashtra",
1010
+ country: "India",
1011
+ zipcode: "400001",
1012
+ landmark: "",
1013
+ phoneNumber: this.state.patientPhone,
1014
+ latitude: 0,
1015
+ longitude: 0,
1016
+ },
1017
+ },
1018
+ {
1019
+ id: 2,
1020
+ firstName: "Papa",
1021
+ lastName: "Bear",
1022
+ email: "papa@example.com",
1023
+ countryCode: "+91",
1024
+ phoneNumber: this.state.patientPhone,
1025
+ dob: "1968-01-01",
1026
+ age: 57,
1027
+ gender: "MALE",
1028
+ bloodGroup: "B+",
1029
+ mrn: "MRN002",
1030
+ address: {
1031
+ id: 2,
1032
+ completeAddress: "123 Main St",
1033
+ addressLine1: "123 Main St",
1034
+ addressLine2: "",
1035
+ city: "Mumbai",
1036
+ state: "Maharashtra",
1037
+ country: "India",
1038
+ zipcode: "400001",
1039
+ landmark: "",
1040
+ phoneNumber: this.state.patientPhone,
1041
+ latitude: 0,
1042
+ longitude: 0,
1043
+ },
1044
+ },
1045
+ {
1046
+ id: 3,
1047
+ firstName: "Monty",
1048
+ lastName: "Bear",
1049
+ email: "monty@example.com",
1050
+ countryCode: "+91",
1051
+ phoneNumber: this.state.patientPhone,
1052
+ dob: "1990-01-01",
1053
+ age: 35,
1054
+ gender: "MALE",
1055
+ bloodGroup: "A+",
1056
+ mrn: "MRN003",
1057
+ address: {
1058
+ id: 3,
1059
+ completeAddress: "123 Main St",
1060
+ addressLine1: "123 Main St",
1061
+ addressLine2: "",
1062
+ city: "Mumbai",
1063
+ state: "Maharashtra",
1064
+ country: "India",
1065
+ zipcode: "400001",
1066
+ landmark: "",
1067
+ phoneNumber: this.state.patientPhone,
1068
+ latitude: 0,
1069
+ longitude: 0,
1070
+ },
1071
+ },
1072
+ ];
1073
+ return `
879
1074
  <div class="medos-section-card">
880
1075
  <div class="medos-section-header">
881
- ${VanillaIcons.mapPin(14)}
882
- <span class="medos-section-title">Address Details</span>
1076
+ ${VanillaIcons.users(14)}
1077
+ <span class="medos-section-title">Select Patient</span>
883
1078
  </div>
884
1079
  <div class="medos-section-body">
885
- <div class="medos-form-group">
886
- <label class="medos-label">Address Line 1 <span class="medos-required">*</span></label>
887
- <input type="text" class="medos-input" id="medos-patient-address" placeholder="Street address, building name, etc." value="${this.escapeHtml(this.state.patientAddress)}" />
1080
+ <div class="medos-patient-list">
1081
+ ${patients
1082
+ .map((patient) => `
1083
+ <div class="medos-patient-card ${this.state.selectedPatient?.id === patient.id ? "selected" : ""}" data-patient-id="${patient.id}">
1084
+ <div class="medos-patient-radio">
1085
+ <input type="radio" name="patient" value="${patient.id}" ${this.state.selectedPatient?.id === patient.id ? "checked" : ""} />
1086
+ </div>
1087
+ <div class="medos-patient-avatar">
1088
+ ${patient.firstName.charAt(0)}${patient.lastName.charAt(0)}
1089
+ </div>
1090
+ <div class="medos-patient-info">
1091
+ <div class="medos-patient-name">${this.escapeHtml(patient.firstName)} ${this.escapeHtml(patient.lastName)}</div>
1092
+ <div class="medos-patient-details">${this.escapeHtml(patient.countryCode)} ${this.escapeHtml(patient.phoneNumber)}</div>
1093
+ </div>
1094
+ <div class="medos-patient-select">select</div>
1095
+ </div>
1096
+ `)
1097
+ .join("")}
888
1098
  </div>
889
- <div class="medos-form-row">
890
- <div class="medos-form-group">
891
- <label class="medos-label">City <span class="medos-required">*</span></label>
892
- <input type="text" class="medos-input" id="medos-patient-city" placeholder="City" value="${this.escapeHtml(this.state.patientCity)}" />
1099
+
1100
+ <button class="medos-add-patient-btn" id="medos-btn-add-patient">
1101
+ ${VanillaIcons.plus(16)} New Patient
1102
+ </button>
1103
+ </div>
1104
+ </div>
1105
+ <div class="medos-actions">
1106
+ <button class="medos-btn medos-btn-back" id="medos-btn-back">${VanillaIcons.arrowLeft(14)} Back</button>
1107
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
1108
+ <button class="medos-btn medos-btn-primary" id="medos-btn-continue" ${this.state.selectedPatient ? "" : "disabled"}>Continue</button>
1109
+ </div>
1110
+ `;
1111
+ }
1112
+ renderAppointmentSummaryStep() {
1113
+ const selectedDoctor = this.doctors.find((d) => d.id === this.state.selectedDoctor);
1114
+ const selectedAddress = this.state.addresses.find((addr) => addr.id === this.state.selectedAddress);
1115
+ const appointmentDate = this.state.selectedDate
1116
+ ? this.state.selectedDate.toLocaleDateString("en-US", {
1117
+ weekday: "short",
1118
+ year: "numeric",
1119
+ month: "short",
1120
+ day: "numeric",
1121
+ })
1122
+ : "";
1123
+ const startTime = this.state.selectedSlot?.start
1124
+ ? new Date(this.state.selectedSlot.start).toLocaleTimeString([], {
1125
+ hour: "2-digit",
1126
+ minute: "2-digit",
1127
+ })
1128
+ : "";
1129
+ const usingSessionPack = this.state.bookingOptionType === "session-pack" &&
1130
+ this.state.selectedSessionPack;
1131
+ const usingNewPackage = this.state.bookingOptionType === "explore-packages" &&
1132
+ this.state.selectedNewPackage;
1133
+ const consultationCharge = this.state.consultationMode === "ONLINE" ? 500 : 300;
1134
+ let totalAmount = consultationCharge;
1135
+ let sessionInfo = "";
1136
+ let dateOfExpiry = "";
1137
+ if (usingSessionPack) {
1138
+ totalAmount = 0;
1139
+ sessionInfo = `${this.state.selectedSessionPack?.remainingSessions} appointments now remaining`;
1140
+ dateOfExpiry = this.state.selectedSessionPack?.expiryDate || "";
1141
+ }
1142
+ else if (usingNewPackage) {
1143
+ totalAmount = this.state.selectedNewPackage?.price || 0;
1144
+ sessionInfo = `${this.state.selectedNewPackage?.totalSessions} appointments after purchase`;
1145
+ const validityDays = this.state.selectedNewPackage?.validityDays || 365;
1146
+ const expiryDate = new Date();
1147
+ expiryDate.setDate(expiryDate.getDate() + validityDays);
1148
+ dateOfExpiry = expiryDate.toLocaleDateString("en-US", {
1149
+ day: "numeric",
1150
+ month: "long",
1151
+ year: "numeric",
1152
+ });
1153
+ }
1154
+ const patientName = this.state.selectedPatient
1155
+ ? `${this.state.selectedPatient.firstName} ${this.state.selectedPatient.lastName}`
1156
+ : this.state.patientName || "Patient";
1157
+ return `
1158
+ <div class="medos-appointment-summary">
1159
+ <div class="medos-summary-header">
1160
+ <h3>Appointment Summary</h3>
1161
+ <button class="medos-close-btn" id="medos-btn-close">&times;</button>
1162
+ </div>
1163
+
1164
+ <div class="medos-summary-section">
1165
+ <label class="medos-form-label">REVIEW APPOINTMENT DETAILS</label>
1166
+
1167
+ <div class="medos-summary-grid">
1168
+ <div class="medos-summary-row">
1169
+ <span class="medos-summary-label">Patient:</span>
1170
+ <span class="medos-summary-value">${this.escapeHtml(patientName)}</span>
1171
+ </div>
1172
+ ${this.state.patientAge
1173
+ ? `<div class="medos-summary-row">
1174
+ <span class="medos-summary-label">Age:</span>
1175
+ <span class="medos-summary-value">${this.escapeHtml(this.state.patientAge)} years</span>
1176
+ </div>`
1177
+ : ""}
1178
+ ${this.state.bloodGroup
1179
+ ? `<div class="medos-summary-row">
1180
+ <span class="medos-summary-label">Blood Group:</span>
1181
+ <span class="medos-summary-value">${this.escapeHtml(this.state.bloodGroup)}</span>
1182
+ </div>`
1183
+ : ""}
1184
+ <div class="medos-summary-row">
1185
+ <span class="medos-summary-label">Doctor:</span>
1186
+ <span class="medos-summary-value">${selectedDoctor
1187
+ ? this.escapeHtml(selectedDoctor.name)
1188
+ : "Not selected"}</span>
1189
+ </div>
1190
+ ${selectedAddress
1191
+ ? `<div class="medos-summary-row">
1192
+ <span class="medos-summary-label">Location:</span>
1193
+ <span class="medos-summary-value">${this.escapeHtml(selectedAddress.label || "Unknown Location")}</span>
1194
+ </div>`
1195
+ : ""}
1196
+ <div class="medos-summary-row">
1197
+ <span class="medos-summary-label">Date & Time:</span>
1198
+ <span class="medos-summary-value">${appointmentDate}${startTime ? `, ${startTime}` : ""}</span>
893
1199
  </div>
894
- <div class="medos-form-group">
895
- <label class="medos-label">State <span class="medos-required">*</span></label>
896
- <input type="text" class="medos-input" id="medos-patient-state" placeholder="State" value="${this.escapeHtml(this.state.patientState)}" />
1200
+ <div class="medos-summary-row">
1201
+ <span class="medos-summary-label">Appointment Type:</span>
1202
+ <span class="medos-summary-value">${this.state.consultationMode === "ONLINE"
1203
+ ? "In Clinic Consultation"
1204
+ : "Online Consultation"}</span>
897
1205
  </div>
898
- </div>
899
- <div class="medos-form-row">
900
- <div class="medos-form-group">
901
- <label class="medos-label">Country <span class="medos-required">*</span></label>
902
- <input type="text" class="medos-input" id="medos-patient-country" placeholder="Country" value="${this.escapeHtml(this.state.patientCountry)}" />
1206
+ <div class="medos-summary-row">
1207
+ <span class="medos-summary-label">Service:</span>
1208
+ <span class="medos-summary-value">${usingSessionPack
1209
+ ? this.escapeHtml(this.state.selectedSessionPack?.name || "Session Pack")
1210
+ : usingNewPackage
1211
+ ? this.escapeHtml(this.state.selectedNewPackage?.name || "Package")
1212
+ : "Standard Consultation"}</span>
903
1213
  </div>
904
- <div class="medos-form-group">
905
- <label class="medos-label">Zipcode <span class="medos-required">*</span></label>
906
- <input type="text" class="medos-input" id="medos-patient-zipcode" placeholder="Zipcode" value="${this.escapeHtml(this.state.patientZipcode)}" />
1214
+ <div class="medos-summary-row">
1215
+ <span class="medos-summary-label">Sessions:</span>
1216
+ <span class="medos-summary-value">${sessionInfo || "1 consultation"}</span>
907
1217
  </div>
1218
+ ${usingSessionPack || usingNewPackage
1219
+ ? `
1220
+ <div class="medos-summary-row">
1221
+ <span class="medos-summary-label">Date of Purchase:</span>
1222
+ <span class="medos-summary-value">${usingSessionPack
1223
+ ? this.state.selectedSessionPack?.purchaseDate ||
1224
+ "Previously"
1225
+ : "Today"}</span>
1226
+ </div>
1227
+ <div class="medos-summary-row">
1228
+ <span class="medos-summary-label">Date of Expiry:</span>
1229
+ <span class="medos-summary-value medos-expiry">${dateOfExpiry}</span>
1230
+ </div>
1231
+ `
1232
+ : ""}
908
1233
  </div>
909
- <div class="medos-form-group">
910
- <label class="medos-label">Landmark <span class="medos-optional">(optional)</span></label>
911
- <input type="text" class="medos-input" id="medos-patient-landmark" placeholder="Nearby landmark" value="${this.escapeHtml(this.state.patientLandmark)}" />
1234
+ </div>
1235
+
1236
+ <div class="medos-summary-total">
1237
+ <div class="medos-total-row">
1238
+ <span class="medos-total-label">Total Amount</span>
1239
+ <span class="medos-total-note">${usingSessionPack ? "Using credits from bundle sessions." : ""}</span>
912
1240
  </div>
1241
+ <div class="medos-total-amount">₹${totalAmount.toLocaleString()}</div>
1242
+ </div>
1243
+
1244
+ <div class="medos-actions">
1245
+ <button class="medos-btn medos-btn-back" id="medos-btn-back">${VanillaIcons.arrowLeft(14)} Back</button>
1246
+ <button class="medos-btn medos-btn-secondary" id="medos-btn-cancel">Cancel</button>
1247
+ <button class="medos-btn medos-btn-primary" id="medos-btn-confirm">Confirm Book</button>
913
1248
  </div>
914
- </div>
915
-
916
- <div class="medos-actions">
917
- <button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
918
- <button class="medos-btn medos-btn-primary" id="medos-btn-submit" ${canSubmit && !this.state.loading ? "" : "disabled"}>${this.state.loading ? "Booking..." : "Book Appointment"}</button>
919
1249
  </div>
920
1250
  `;
921
1251
  }
922
- renderSuccessIcon() {
1252
+ renderSuccessStep() {
1253
+ const duration = this.calculateDuration();
1254
+ const selectedDoctor = this.doctors.find((d) => d.id === this.state.selectedDoctor);
1255
+ const selectedAddress = this.state.addresses.find((addr) => addr.id === this.state.selectedAddress);
1256
+ const appointmentDate = this.state.selectedDate
1257
+ ? this.formatDate(formatDateToISO(this.state.selectedDate))
1258
+ : "";
1259
+ const startTime = this.state.selectedSlot?.start
1260
+ ? this.formatTime(new Date(this.state.selectedSlot.start).toTimeString().slice(0, 5))
1261
+ : "";
1262
+ const patientName = this.state.selectedPatient
1263
+ ? `${this.state.selectedPatient.firstName} ${this.state.selectedPatient.lastName}`
1264
+ : this.state.patientName || "Patient";
1265
+ const usingSessionPack = this.state.bookingOptionType === "session-pack" &&
1266
+ this.state.selectedSessionPack;
923
1267
  return `
924
- <div style="position: relative; display: inline-block;">
925
- <svg width="64" height="64" viewBox="0 0 41 41" fill="none">
926
- <path
927
- d="M31.1309 4.90254C32.388 4.98797 33.0166 5.03069 33.5247 5.25288C34.2598 5.57438 34.8467 6.16126 35.1682 6.8964C35.3904 7.40445 35.4331 8.03302 35.5185 9.29016L35.7135 12.159C35.748 12.6674 35.7653 12.9217 35.8206 13.1645C35.9004 13.5154 36.0391 13.8503 36.2308 14.1549C36.3634 14.3657 36.531 14.5576 36.8661 14.9416L38.7568 17.108C39.5853 18.0574 39.9996 18.532 40.2017 19.0484C40.4942 19.7955 40.4942 20.6255 40.2017 21.3727C39.9996 21.889 39.5853 22.3637 38.7568 23.313L36.8661 25.4795C36.531 25.8634 36.3634 26.0554 36.2308 26.2662C36.0391 26.5708 35.9004 26.9056 35.8206 27.2566C35.7653 27.4994 35.748 27.7536 35.7135 28.2621L35.5185 31.1309C35.4331 32.388 35.3904 33.0166 35.1682 33.5247C34.8467 34.2598 34.2598 34.8467 33.5247 35.1682C33.0166 35.3904 32.388 35.4331 31.1309 35.5185L28.2621 35.7135C27.7536 35.748 27.4994 35.7653 27.2566 35.8206C26.9056 35.9004 26.5708 36.0391 26.2662 36.2308C26.0554 36.3634 25.8634 36.531 25.4795 36.8661L23.313 38.7568C22.3637 39.5853 21.889 39.9996 21.3727 40.2017C20.6255 40.4942 19.7955 40.4942 19.0484 40.2017C18.532 39.9996 18.0574 39.5853 17.108 38.7568L14.9416 36.8661C14.5576 36.531 14.3657 36.3634 14.1549 36.2308C13.8503 36.0391 13.5154 35.9004 13.1645 35.8206C12.9217 35.7653 12.6674 35.748 12.159 35.7135L9.29016 35.5185C8.03302 35.4331 7.40445 35.3904 6.8964 35.1682C6.16126 34.8467 5.57438 34.2598 5.25288 33.5247C5.03069 33.0166 4.98797 32.388 4.90254 31.1309L4.70759 28.2621C4.67304 27.7536 4.65576 27.4994 4.60049 27.2566C4.52063 26.9056 4.38193 26.5708 4.19028 26.2662C4.05764 26.0554 3.89009 25.8634 3.555 25.4795L1.66428 23.313C0.83576 22.3637 0.421499 21.889 0.219363 21.3727C-0.073121 20.6255 -0.0731209 19.7955 0.219363 19.0484C0.421499 18.532 0.83576 18.0574 1.66428 17.108L3.555 14.9416C3.89009 14.5576 4.05764 14.3657 4.19027 14.1549C4.38193 13.8503 4.52063 13.5154 4.60049 13.1645C4.65576 12.9217 4.67304 12.6674 4.70759 12.159L4.90254 9.29016C4.98797 8.03302 5.03069 7.40445 5.25288 6.8964C5.57438 6.16126 6.16126 5.57438 6.8964 5.25288C7.40445 5.03069 8.03302 4.98797 9.29016 4.90254L12.159 4.70759C12.6674 4.67304 12.9217 4.65577 13.1645 4.6005C13.5154 4.52063 13.8503 4.38193 14.1549 4.19028C14.3657 4.05764 14.5576 3.89009 14.9416 3.555L17.108 1.66428C18.0574 0.83576 18.532 0.421499 19.0484 0.219363C19.7955 -0.073121 20.6255 -0.073121 21.3727 0.219363C21.889 0.421499 22.3637 0.83576 23.313 1.66428L25.4795 3.555C25.8634 3.89009 26.0554 4.05764 26.2662 4.19028C26.5708 4.38193 26.9056 4.52063 27.2566 4.6005C27.4994 4.65577 27.7536 4.67304 28.2621 4.70759L31.1309 4.90254Z"
928
- fill="#006E0F"
929
- />
930
- </svg>
931
- <svg width="16" height="12" viewBox="0 0 16 12" fill="none" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">
932
- <path
933
- d="M5.472 11.544L0 6.072L1.368 4.704L5.472 8.808L14.28 0L15.648 1.368L5.472 11.544Z"
934
- fill="white"
935
- />
936
- </svg>
937
- </div>
938
- `;
1268
+ <div class="medos-success-container">
1269
+ <div class="medos-success-header">
1270
+ <h2>Appointment Confirmed</h2>
1271
+ </div>
1272
+
1273
+ <div class="medos-success-content">
1274
+ <div class="medos-success-badge">
1275
+ ${VanillaIcons.successBadge(64)}
1276
+ </div>
1277
+
1278
+ <h3 class="medos-success-title">Appointment Confirmed</h3>
1279
+
1280
+ <div class="medos-success-details">
1281
+ <h4>Appointment Details</h4>
1282
+ <div class="medos-details-text">
1283
+ <p><strong>Patient:</strong> ${this.escapeHtml(patientName)}</p>
1284
+ <p><strong>Type:</strong> ${this.state.consultationMode === "ONLINE"
1285
+ ? "In Clinic Consultation"
1286
+ : "Online"}</p>
1287
+ <p><strong>Date:</strong> ${appointmentDate}</p>
1288
+ <p><strong>Time:</strong> ${startTime}</p>
1289
+ <p><strong>Duration:</strong> ~${duration} minutes</p>
1290
+ ${selectedAddress?.label
1291
+ ? `<p><strong>Location:</strong> ${this.escapeHtml(selectedAddress.label)}</p>`
1292
+ : ""}
1293
+ </div>
1294
+ </div>
1295
+
1296
+ <p class="medos-confirmation-message">
1297
+ A confirmation message has been sent to the registered Phone Number.
1298
+ </p>
1299
+
1300
+ ${usingSessionPack
1301
+ ? `
1302
+ <div class="medos-session-remaining">
1303
+ <span class="medos-remaining-label">Sessions:</span>
1304
+ <span class="medos-remaining-value">${(this.state.selectedSessionPack?.remainingSessions || 1) - 1} appointments now remaining</span>
1305
+ </div>
1306
+ `
1307
+ : ""}
1308
+ </div>
1309
+ </div>
1310
+ `;
939
1311
  }
940
1312
  formatDate(dateStr) {
941
1313
  try {
@@ -973,66 +1345,6 @@ class AppointmentCalendarWidget {
973
1345
  }
974
1346
  return 60;
975
1347
  }
976
- renderStep5() {
977
- const duration = this.calculateDuration();
978
- const selectedAddress = this.state.addresses.find((addr) => addr.id === this.state.selectedAddress);
979
- const appointmentDate = this.state.selectedDate
980
- ? this.formatDate(formatDateToISO(this.state.selectedDate))
981
- : "";
982
- const startTime = this.state.selectedSlot?.start
983
- ? this.formatTime(new Date(this.state.selectedSlot.start).toTimeString().slice(0, 5))
984
- : "";
985
- return `
986
- <div style="display: flex; flex-direction: column; padding: 0; font-family: Arial, sans-serif; background: #f8f9fa; min-height: 500px;">
987
- <!-- Header with border -->
988
- <div style="padding: 20px 24px; font-size: 24px; font-weight: bold; color: #1a365d; border-bottom: 2px solid #e2e8f0; background: white;">
989
- Appointment Confirmed
990
- </div>
991
-
992
- <!-- Main content with border -->
993
- <div style="flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 24px; border: 2px solid #e2e8f0; border-top: none; background: white; text-align: center;">
994
- <!-- Success Title -->
995
- <h2 style="font-size: 20px; font-weight: 600; color: #006E0F; margin: 0 0 24px 0;">
996
- Appointment Confirmed
997
- </h2>
998
-
999
- <!-- Success Icon -->
1000
- <div style="margin-bottom: 32px;">
1001
- ${this.renderSuccessIcon()}
1002
- </div>
1003
-
1004
- <!-- Appointment Details -->
1005
- <div style="width: 100%; max-width: 500px; margin-bottom: 32px;">
1006
- <h3 style="font-size: 18px; font-weight: 600; color: #006E0F; margin-bottom: 24px;">
1007
- Appointment Details
1008
- </h3>
1009
-
1010
- <div style="display: flex; flex-direction: column; gap: 12px; font-size: 16px; line-height: 1.6; color: #4a5568;">
1011
- <div><strong style="color: #006E0F;">Patient:</strong> ${this.escapeHtml(this.state.patientName || "Patient")}</div>
1012
- <div><strong style="color: #006E0F;">Visitation Type:</strong> ${this.state.consultationMode === "ONLINE"
1013
- ? "Online Consultation"
1014
- : "General"}</div>
1015
- ${appointmentDate
1016
- ? `<div><strong style="color: #006E0F;">Date:</strong> ${appointmentDate}</div>`
1017
- : ""}
1018
- ${startTime
1019
- ? `<div><strong style="color: #006E0F;">Time:</strong> ${startTime}</div>`
1020
- : ""}
1021
- <div><strong style="color: #006E0F;">Duration:</strong> ~${duration} minutes</div>
1022
- ${selectedAddress?.label
1023
- ? `<div><strong style="color: #006E0F;">Location:</strong> ${this.escapeHtml(selectedAddress.label)}</div>`
1024
- : ""}
1025
- </div>
1026
- </div>
1027
-
1028
- <!-- Confirmation Message -->
1029
- <div style="font-size: 16px; font-style: italic; color: #718096; text-align: center; max-width: 600px; line-height: 1.5;">
1030
- A confirmation email has been sent to the Patient's Email address.
1031
- </div>
1032
- </div>
1033
- </div>
1034
- `;
1035
- }
1036
1348
  attachEventListeners() {
1037
1349
  const consultationRadios = this.container.querySelectorAll('input[name="consultationMode"]');
1038
1350
  consultationRadios.forEach((radio) => {
@@ -1042,7 +1354,7 @@ class AppointmentCalendarWidget {
1042
1354
  this.render();
1043
1355
  });
1044
1356
  });
1045
- const slotCards = this.container.querySelectorAll(".medos-slot-card");
1357
+ const slotCards = this.container.querySelectorAll(".medos-slot-card, .medos-slot-btn");
1046
1358
  slotCards.forEach((card) => {
1047
1359
  card.addEventListener("click", () => {
1048
1360
  const slotId = card.dataset.slotId;
@@ -1124,13 +1436,6 @@ class AppointmentCalendarWidget {
1124
1436
  this.updateSubmitButtonState();
1125
1437
  });
1126
1438
  }
1127
- const patientGenderSelect = this.container.querySelector("#medos-patient-gender");
1128
- if (patientGenderSelect) {
1129
- patientGenderSelect.addEventListener("change", (e) => {
1130
- const target = e.target;
1131
- this.state.patientGender = target.value;
1132
- });
1133
- }
1134
1439
  const patientAddressInput = this.container.querySelector("#medos-patient-address");
1135
1440
  if (patientAddressInput) {
1136
1441
  patientAddressInput.addEventListener("input", (e) => {
@@ -1178,6 +1483,65 @@ class AppointmentCalendarWidget {
1178
1483
  this.state.patientLandmark = target.value;
1179
1484
  });
1180
1485
  }
1486
+ const optionCards = this.container.querySelectorAll(".medos-option-card");
1487
+ optionCards.forEach((card) => {
1488
+ card.addEventListener("click", () => {
1489
+ const option = card.dataset.option;
1490
+ if (option === "new-appointment" ||
1491
+ option === "session-pack" ||
1492
+ option === "explore-packages") {
1493
+ this.state.bookingOptionType = option;
1494
+ this.render();
1495
+ }
1496
+ });
1497
+ });
1498
+ const packCards = this.container.querySelectorAll(".medos-session-pack-card");
1499
+ packCards.forEach((card) => {
1500
+ card.addEventListener("click", () => {
1501
+ const packId = Number.parseInt(card.dataset.packId || "0", 10);
1502
+ const pack = this.state.userSessionPacks.find((p) => p.id === packId);
1503
+ if (pack) {
1504
+ this.state.selectedSessionPack = pack;
1505
+ this.state.bookingOptionType = "session-pack";
1506
+ this.render();
1507
+ }
1508
+ });
1509
+ });
1510
+ const packageCards = this.container.querySelectorAll(".medos-package-card");
1511
+ packageCards.forEach((card) => {
1512
+ card.addEventListener("click", () => {
1513
+ const packageId = parseInt(card.dataset.packageId || "0", 10);
1514
+ const pkg = this.state.availablePackages.length > 0
1515
+ ? this.state.availablePackages.find((p) => p.id === packageId)
1516
+ : {
1517
+ id: packageId,
1518
+ name: packageId === 1 ? "Silver Package" : "Gold Package",
1519
+ totalSessions: packageId === 1 ? 3 : 5,
1520
+ price: packageId === 1 ? 5000 : 8000,
1521
+ validityDays: packageId === 1 ? 180 : 365,
1522
+ applicableOnline: true,
1523
+ applicableOffline: true,
1524
+ };
1525
+ if (pkg) {
1526
+ this.state.selectedNewPackage = pkg;
1527
+ this.render();
1528
+ }
1529
+ });
1530
+ });
1531
+ const patientCards = this.container.querySelectorAll(".medos-patient-card");
1532
+ patientCards.forEach((card) => {
1533
+ card.addEventListener("click", () => {
1534
+ const patientId = parseInt(card.dataset.patientId || "0", 10);
1535
+ const patients = this.state.verifiedPatients.length > 0
1536
+ ? this.state.verifiedPatients
1537
+ : this.getPlaceholderPatients();
1538
+ const patient = patients.find((p) => p.id === patientId);
1539
+ if (patient) {
1540
+ this.state.selectedPatient = patient;
1541
+ this.render();
1542
+ }
1543
+ });
1544
+ });
1181
1545
  const nextBtn = this.container.querySelector("#medos-btn-next");
1182
1546
  if (nextBtn) {
1183
1547
  nextBtn.addEventListener("click", () => {
@@ -1186,10 +1550,22 @@ class AppointmentCalendarWidget {
1186
1550
  }
1187
1551
  });
1188
1552
  }
1553
+ const continueBtn = this.container.querySelector("#medos-btn-continue");
1554
+ if (continueBtn) {
1555
+ continueBtn.addEventListener("click", () => {
1556
+ if (!continueBtn.disabled) {
1557
+ this.goToNext();
1558
+ }
1559
+ });
1560
+ }
1189
1561
  const backBtn = this.container.querySelector("#medos-btn-back");
1190
1562
  if (backBtn) {
1191
1563
  backBtn.addEventListener("click", () => this.goBack());
1192
1564
  }
1565
+ const cancelBtn = this.container.querySelector("#medos-btn-cancel");
1566
+ if (cancelBtn) {
1567
+ cancelBtn.addEventListener("click", () => this.reset());
1568
+ }
1193
1569
  const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
1194
1570
  if (sendOtpBtn) {
1195
1571
  sendOtpBtn.addEventListener("click", () => {
@@ -1219,6 +1595,14 @@ class AppointmentCalendarWidget {
1219
1595
  this.sendOtp();
1220
1596
  });
1221
1597
  }
1598
+ const confirmBtn = this.container.querySelector("#medos-btn-confirm");
1599
+ if (confirmBtn) {
1600
+ confirmBtn.addEventListener("click", () => {
1601
+ if (!confirmBtn.disabled) {
1602
+ this.submitAppointment();
1603
+ }
1604
+ });
1605
+ }
1222
1606
  const submitBtn = this.container.querySelector("#medos-btn-submit");
1223
1607
  if (submitBtn) {
1224
1608
  submitBtn.addEventListener("click", () => {
@@ -1231,6 +1615,72 @@ class AppointmentCalendarWidget {
1231
1615
  if (bookAnotherBtn) {
1232
1616
  bookAnotherBtn.addEventListener("click", () => this.reset());
1233
1617
  }
1618
+ const addPatientBtn = this.container.querySelector("#medos-btn-add-patient");
1619
+ if (addPatientBtn) {
1620
+ addPatientBtn.addEventListener("click", () => {
1621
+ this.state.selectedPatient = null;
1622
+ this.state.useExistingPatient = false;
1623
+ this.goToNext();
1624
+ });
1625
+ }
1626
+ }
1627
+ getPlaceholderPatients() {
1628
+ return [
1629
+ {
1630
+ id: 1,
1631
+ firstName: "Mumma",
1632
+ lastName: "Bear",
1633
+ email: "mumma@example.com",
1634
+ countryCode: "+91",
1635
+ phoneNumber: this.state.patientPhone,
1636
+ dob: "1970-01-01",
1637
+ age: 55,
1638
+ gender: "FEMALE",
1639
+ bloodGroup: "O+",
1640
+ mrn: "MRN001",
1641
+ address: {
1642
+ id: 1,
1643
+ completeAddress: "123 Main St",
1644
+ addressLine1: "123 Main St",
1645
+ addressLine2: "",
1646
+ city: "Mumbai",
1647
+ state: "Maharashtra",
1648
+ country: "India",
1649
+ zipcode: "400001",
1650
+ landmark: "",
1651
+ phoneNumber: this.state.patientPhone,
1652
+ latitude: 0,
1653
+ longitude: 0,
1654
+ },
1655
+ },
1656
+ {
1657
+ id: 2,
1658
+ firstName: "Papa",
1659
+ lastName: "Bear",
1660
+ email: "papa@example.com",
1661
+ countryCode: "+91",
1662
+ phoneNumber: this.state.patientPhone,
1663
+ dob: "1968-01-01",
1664
+ age: 57,
1665
+ gender: "MALE",
1666
+ bloodGroup: "B+",
1667
+ mrn: "MRN002",
1668
+ address: {
1669
+ id: 2,
1670
+ completeAddress: "123 Main St",
1671
+ addressLine1: "123 Main St",
1672
+ addressLine2: "",
1673
+ city: "Mumbai",
1674
+ state: "Maharashtra",
1675
+ country: "India",
1676
+ zipcode: "400001",
1677
+ landmark: "",
1678
+ phoneNumber: this.state.patientPhone,
1679
+ latitude: 0,
1680
+ longitude: 0,
1681
+ },
1682
+ },
1683
+ ];
1234
1684
  }
1235
1685
  escapeHtml(text) {
1236
1686
  const div = document.createElement("div");