medos-sdk 1.1.10 → 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 (97) 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 +19 -22
  4. package/dist/components/AppointmentConfirmationStep.d.ts +1 -0
  5. package/dist/components/AppointmentConfirmationStep.js +34 -42
  6. package/dist/components/AppointmentDateTimeModal.d.ts +1 -0
  7. package/dist/components/AppointmentDateTimeModal.js +201 -168
  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 +10 -4
  13. package/dist/components/ContactPreferenceStep.js +10 -1
  14. package/dist/components/DoctorSelectModal.js +105 -59
  15. package/dist/components/EnquiryForm.js +81 -69
  16. package/dist/components/Icons/CloseIcon.d.ts +9 -0
  17. package/dist/components/Icons/CloseIcon.js +5 -0
  18. package/dist/components/InquiryDetailsStep.js +5 -1
  19. package/dist/components/PatientDetailsStep.js +17 -12
  20. package/dist/components/PatientSelectionStep.d.ts +12 -0
  21. package/dist/components/PatientSelectionStep.js +254 -0
  22. package/dist/components/PhoneVerificationStep.js +1 -1
  23. package/dist/components/SuccessStep.js +1 -1
  24. package/dist/components/appointment-booking/AppointmentCalender.js +200 -60
  25. package/dist/components/appointment-booking/hooks/useAppointmentFlow.d.ts +0 -1
  26. package/dist/components/appointment-booking/hooks/useAppointmentFlow.js +110 -25
  27. package/dist/components/appointment-booking/hooks/useAppointmentState.js +32 -0
  28. package/dist/components/appointment-booking/hooks/useInitializeAddresses.js +0 -1
  29. package/dist/components/appointment-booking/types.d.ts +163 -0
  30. package/dist/components/appointment-booking/types.js +16 -0
  31. package/dist/components/appointment-modal-styles.d.ts +259 -0
  32. package/dist/components/appointment-modal-styles.js +395 -0
  33. package/dist/components/constant.d.ts +2 -0
  34. package/dist/components/constant.js +15 -0
  35. package/dist/components/custom-calendar.js +20 -11
  36. package/dist/components/styles.js +93 -52
  37. package/dist/components/theme-styles.d.ts +5 -4
  38. package/dist/components/theme-styles.js +221 -125
  39. package/dist/components/types.d.ts +3 -1
  40. package/dist/components/types.js +15 -0
  41. package/dist/components/utils.d.ts +3 -0
  42. package/dist/components/utils.js +59 -0
  43. package/dist/components/validation.d.ts +2 -0
  44. package/dist/components/validation.js +41 -0
  45. package/dist/core/theme/index.d.ts +1 -0
  46. package/dist/core/theme/index.js +1 -0
  47. package/dist/core/theme/responsive.d.ts +15 -0
  48. package/dist/core/theme/responsive.js +113 -0
  49. package/dist/core/theme/themes.js +16 -4
  50. package/dist/core/theme/types.d.ts +8 -0
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.js +1 -0
  53. package/dist/react/ThemeProvider.d.ts +2 -1
  54. package/dist/react/ThemeProvider.js +49 -10
  55. package/dist/services/AppointmentService.d.ts +80 -2
  56. package/dist/services/AppointmentService.js +114 -5
  57. package/dist/services/WorkspaceService.d.ts +58 -3
  58. package/dist/services/WorkspaceService.js +10 -1
  59. package/dist/vanilla/AppointmentCalendarWidget.d.ts +9 -7
  60. package/dist/vanilla/AppointmentCalendarWidget.js +820 -377
  61. package/dist/vanilla/EnquiryFormWidget.d.ts +1 -0
  62. package/dist/vanilla/EnquiryFormWidget.js +25 -43
  63. package/dist/vanilla/client/MedosClient.d.ts +1 -0
  64. package/dist/vanilla/components/AppointmentConfirmationStep.d.ts +1 -0
  65. package/dist/vanilla/components/AppointmentDateTimeModal.d.ts +1 -0
  66. package/dist/vanilla/components/AppointmentSummaryStep.d.ts +12 -0
  67. package/dist/vanilla/components/BookingOptionStep.d.ts +14 -0
  68. package/dist/vanilla/components/Icons/CloseIcon.d.ts +9 -0
  69. package/dist/vanilla/components/PatientSelectionStep.d.ts +12 -0
  70. package/dist/vanilla/components/VanillaCalendar.js +33 -18
  71. package/dist/vanilla/components/VanillaIcons.d.ts +5 -0
  72. package/dist/vanilla/components/VanillaIcons.js +92 -0
  73. package/dist/vanilla/components/VanillaSelect.d.ts +3 -0
  74. package/dist/vanilla/components/VanillaSelect.js +93 -5
  75. package/dist/vanilla/components/appointment-booking/hooks/useAppointmentFlow.d.ts +0 -1
  76. package/dist/vanilla/components/appointment-booking/types.d.ts +163 -0
  77. package/dist/vanilla/components/appointment-modal-styles.d.ts +259 -0
  78. package/dist/vanilla/components/constant.d.ts +2 -0
  79. package/dist/vanilla/components/theme-styles.d.ts +5 -4
  80. package/dist/vanilla/components/types.d.ts +3 -1
  81. package/dist/vanilla/components/utils.d.ts +3 -0
  82. package/dist/vanilla/components/validation.d.ts +2 -0
  83. package/dist/vanilla/core/theme/index.d.ts +1 -0
  84. package/dist/vanilla/core/theme/responsive.d.ts +15 -0
  85. package/dist/vanilla/core/theme/types.d.ts +8 -0
  86. package/dist/vanilla/enquiry-widget.js +373 -52
  87. package/dist/vanilla/index.d.ts +2 -0
  88. package/dist/vanilla/react/ThemeProvider.d.ts +2 -1
  89. package/dist/vanilla/services/AppointmentService.d.ts +80 -2
  90. package/dist/vanilla/services/WorkspaceService.d.ts +58 -3
  91. package/dist/vanilla/vanilla/AppointmentCalendarWidget.d.ts +9 -7
  92. package/dist/vanilla/vanilla/EnquiryFormWidget.d.ts +1 -0
  93. package/dist/vanilla/vanilla/components/VanillaIcons.d.ts +5 -0
  94. package/dist/vanilla/vanilla/components/VanillaSelect.d.ts +3 -0
  95. package/dist/vanilla/widget.css +833 -207
  96. package/dist/vanilla/widget.js +6444 -5676
  97. package/package.json +1 -1
@@ -3873,7 +3873,62 @@
3873
3873
  },
3874
3874
  };
3875
3875
 
3876
+ const mapBloodGroupToApi = (uiBloodGroup) => {
3877
+ const bloodGroupMap = {
3878
+ "A+": "A_POSITIVE",
3879
+ "A-": "A_NEGATIVE",
3880
+ "B+": "B_POSITIVE",
3881
+ "B-": "B_NEGATIVE",
3882
+ "AB+": "AB_POSITIVE",
3883
+ "AB-": "AB_NEGATIVE",
3884
+ "O+": "O_POSITIVE",
3885
+ "O-": "O_NEGATIVE",
3886
+ UNKNOWN: "UNKNOWN",
3887
+ };
3888
+ return bloodGroupMap[uiBloodGroup] || "UNKNOWN";
3889
+ };
3890
+
3891
+ const WorkspaceService = {
3892
+ async fetchWorkspace() {
3893
+ try {
3894
+ const client = await MedosClient.ensureInitialized();
3895
+ const res = await client.get("/workspaces");
3896
+ if (!res.data || typeof res.data.workspaceId !== "number") {
3897
+ throw new Error("Invalid workspace response");
3898
+ }
3899
+ return res.data;
3900
+ }
3901
+ catch (error) {
3902
+ throw new Error(`Failed to fetch workspace: ${error.message}`);
3903
+ }
3904
+ },
3905
+ async fetchTheme() {
3906
+ try {
3907
+ const workspace = await this.fetchWorkspace();
3908
+ return workspace.theme;
3909
+ }
3910
+ catch (error) {
3911
+ throw new Error(`Failed to fetch workspace theme: ${error.message}`);
3912
+ }
3913
+ },
3914
+ };
3915
+
3916
+ var WorkspaceService$1 = /*#__PURE__*/Object.freeze({
3917
+ __proto__: null,
3918
+ WorkspaceService: WorkspaceService
3919
+ });
3920
+
3876
3921
  const AppointmentService = {
3922
+ async arePackagesConfigured() {
3923
+ try {
3924
+ const workspace = await WorkspaceService.fetchWorkspace();
3925
+ return workspace.arePackagesConfigured === true;
3926
+ }
3927
+ catch (error) {
3928
+ console.warn("Failed to check package configuration, defaulting to legacy endpoint:", error);
3929
+ return false;
3930
+ }
3931
+ },
3877
3932
  async getAddresses() {
3878
3933
  const client = await MedosClient.ensureInitialized();
3879
3934
  const res = await client.get("/workspaces");
@@ -3947,16 +4002,82 @@
3947
4002
  }
3948
4003
  return [];
3949
4004
  },
3950
- async createAppointment(payload) {
4005
+ transformToUnifiedPayload(payload) {
4006
+ const consultationCharge = typeof payload.consultationCharge === "string"
4007
+ ? Number.parseFloat(payload.consultationCharge) || 0
4008
+ : payload.consultationCharge || 0;
4009
+ const completeAddress = [
4010
+ payload.patientAddress.addressLine1,
4011
+ payload.patientAddress.addressLine2,
4012
+ payload.patientAddress.city,
4013
+ payload.patientAddress.state,
4014
+ payload.patientAddress.country,
4015
+ payload.patientAddress.zipcode,
4016
+ ]
4017
+ .filter(Boolean)
4018
+ .join(", ");
4019
+ const unifiedPayload = {
4020
+ workspaceId: Number(payload.workspaceId || 0),
4021
+ workspaceAddressId: Number(payload.workspaceAddressId),
4022
+ doctorId: Number(payload.doctorId),
4023
+ mode: (payload.mode || "OFFLINE"),
4024
+ appointmentDate: payload.appointmentDate,
4025
+ fromDateTimeTs: payload.fromDateTimeTs,
4026
+ toDateTimeTs: payload.toDateTimeTs,
4027
+ bookingType: payload.bookingType || "ONE_TIME_APPOINTMENT",
4028
+ consultationCharge,
4029
+ paymentMode: payload.paymentMode || "CASH",
4030
+ type: payload.type || "CONSULTATION",
4031
+ source: payload.source || "SDK_POWERED_WEBSITE",
4032
+ patientPayload: {
4033
+ id: payload.patientPayload.id,
4034
+ firstName: payload.patientPayload.firstName,
4035
+ lastName: payload.patientPayload.lastName,
4036
+ email: payload.patientPayload.email || "",
4037
+ countryCode: payload.patientPayload.countryCode,
4038
+ phoneNumber: payload.patientPayload.phoneNumber,
4039
+ dob: payload.patientPayload.dob || "",
4040
+ age: payload.patientPayload.age || 0,
4041
+ gender: (payload.patientPayload.gender || "OTHER"),
4042
+ bloodGroup: payload.patientPayload.bloodGroup
4043
+ ? mapBloodGroupToApi(payload.patientPayload.bloodGroup)
4044
+ : "UNKNOWN",
4045
+ },
4046
+ patientAddress: {
4047
+ completeAddress,
4048
+ addressLine1: payload.patientAddress.addressLine1,
4049
+ addressLine2: payload.patientAddress.addressLine2,
4050
+ city: payload.patientAddress.city,
4051
+ state: payload.patientAddress.state,
4052
+ country: payload.patientAddress.country,
4053
+ zipcode: payload.patientAddress.zipcode,
4054
+ landmark: payload.patientAddress.landmark,
4055
+ countryCode: payload.patientAddress.countryCode || "",
4056
+ phoneNumber: payload.patientAddress.phoneNumber || "",
4057
+ patientId: payload.patientAddress.patientId || 0,
4058
+ },
4059
+ };
4060
+ if (payload.packageConfigId) {
4061
+ unifiedPayload.packageConfigId = payload.packageConfigId;
4062
+ }
4063
+ if (payload.patientPackageId) {
4064
+ unifiedPayload.patientPackageId = payload.patientPackageId;
4065
+ }
4066
+ if (payload.packageAmount) {
4067
+ unifiedPayload.packageAmount = payload.packageAmount;
4068
+ }
4069
+ return unifiedPayload;
4070
+ },
4071
+ async createLegacyAppointment(payload) {
3951
4072
  const client = await MedosClient.ensureInitialized();
3952
- const appointmentData = {
4073
+ const legacyPayload = {
3953
4074
  workspaceAddressId: payload.workspaceAddressId,
3954
4075
  doctorId: payload.doctorId,
3955
4076
  mode: payload.mode || "OFFLINE",
3956
4077
  appointmentDate: payload.appointmentDate,
3957
4078
  fromDateTimeTs: payload.fromDateTimeTs,
3958
4079
  toDateTimeTs: payload.toDateTimeTs,
3959
- consultationCharge: payload.consultationCharge || "0",
4080
+ consultationCharge: payload.consultationCharge,
3960
4081
  type: payload.type || "CONSULTATION",
3961
4082
  source: payload.source || "SDK_POWERED_WEBSITE",
3962
4083
  patientPayload: payload.patientPayload,
@@ -3964,7 +4085,7 @@
3964
4085
  };
3965
4086
  if (payload.attachments && payload.attachments.length > 0) {
3966
4087
  const formData = new FormData();
3967
- const payloadString = JSON.stringify(appointmentData);
4088
+ const payloadString = JSON.stringify(legacyPayload);
3968
4089
  formData.append("payload", payloadString);
3969
4090
  payload.attachments.forEach((file) => {
3970
4091
  formData.append("attachments", file);
@@ -3973,7 +4094,38 @@
3973
4094
  return res.data;
3974
4095
  }
3975
4096
  else {
3976
- const res = await client.post("/appointments/book-appointment", appointmentData, {
4097
+ const res = await client.post("/appointments/book-appointment", legacyPayload, {
4098
+ headers: {
4099
+ "Content-Type": "application/json",
4100
+ },
4101
+ });
4102
+ return res.data;
4103
+ }
4104
+ },
4105
+ async createAppointment(payload) {
4106
+ const packagesConfigured = await this.arePackagesConfigured();
4107
+ if (packagesConfigured) {
4108
+ return this.createUnifiedAppointment(payload);
4109
+ }
4110
+ else {
4111
+ return this.createLegacyAppointment(payload);
4112
+ }
4113
+ },
4114
+ async createUnifiedAppointment(payload) {
4115
+ const client = await MedosClient.ensureInitialized();
4116
+ const unifiedPayload = this.transformToUnifiedPayload(payload);
4117
+ if (payload.attachments && payload.attachments.length > 0) {
4118
+ const formData = new FormData();
4119
+ const payloadString = JSON.stringify(unifiedPayload);
4120
+ formData.append("payload", payloadString);
4121
+ payload.attachments.forEach((file) => {
4122
+ formData.append("attachments", file);
4123
+ });
4124
+ const res = await client.post("/appointments/book-appointment-unified", formData);
4125
+ return res.data;
4126
+ }
4127
+ else {
4128
+ const res = await client.post("/appointments/book-appointment-unified", unifiedPayload, {
3977
4129
  headers: {
3978
4130
  "Content-Type": "application/json",
3979
4131
  },
@@ -4127,6 +4279,13 @@
4127
4279
  }
4128
4280
  return PatientService.verifyPhoneVerificationOtp(payload);
4129
4281
  }
4282
+ static async fetchTheme() {
4283
+ if (!this.instance) {
4284
+ throw new Error("MedosClient not initialized. Call MedosClient.init() first.");
4285
+ }
4286
+ const { WorkspaceService } = await Promise.resolve().then(function () { return WorkspaceService$1; });
4287
+ return WorkspaceService.fetchTheme();
4288
+ }
4130
4289
  static get client() {
4131
4290
  if (!this.instance && !this.initPromise) {
4132
4291
  throw new Error("MedosClient not initialized. Call MedosClient.init() or MedosClient.initWithSession() first.");
@@ -4429,6 +4588,98 @@
4429
4588
  <circle cx="12" cy="12" r="10"></circle>
4430
4589
  <polyline points="12 6 12 12 16 14"></polyline>
4431
4590
  </svg>
4591
+ `,
4592
+ calendar: (size = 20) => `
4593
+ <svg
4594
+ xmlns="http://www.w3.org/2000/svg"
4595
+ width="${size}"
4596
+ height="${size}"
4597
+ viewBox="0 0 24 24"
4598
+ fill="none"
4599
+ stroke="currentColor"
4600
+ stroke-width="2"
4601
+ stroke-linecap="round"
4602
+ stroke-linejoin="round"
4603
+ class="medos-icon medos-icon-calendar"
4604
+ >
4605
+ <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
4606
+ <line x1="16" y1="2" x2="16" y2="6"></line>
4607
+ <line x1="8" y1="2" x2="8" y2="6"></line>
4608
+ <line x1="3" y1="10" x2="21" y2="10"></line>
4609
+ </svg>
4610
+ `,
4611
+ giftBox: (size = 20) => `
4612
+ <svg
4613
+ xmlns="http://www.w3.org/2000/svg"
4614
+ width="${size}"
4615
+ height="${size}"
4616
+ viewBox="0 0 24 24"
4617
+ fill="none"
4618
+ stroke="currentColor"
4619
+ stroke-width="2"
4620
+ stroke-linecap="round"
4621
+ stroke-linejoin="round"
4622
+ class="medos-icon medos-icon-gift"
4623
+ >
4624
+ <polyline points="20 12 20 22 4 22 4 12"></polyline>
4625
+ <rect x="2" y="7" width="20" height="5"></rect>
4626
+ <line x1="12" y1="22" x2="12" y2="7"></line>
4627
+ <path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"></path>
4628
+ <path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"></path>
4629
+ </svg>
4630
+ `,
4631
+ arrowLeft: (size = 20) => `
4632
+ <svg
4633
+ xmlns="http://www.w3.org/2000/svg"
4634
+ width="${size}"
4635
+ height="${size}"
4636
+ viewBox="0 0 24 24"
4637
+ fill="none"
4638
+ stroke="currentColor"
4639
+ stroke-width="2"
4640
+ stroke-linecap="round"
4641
+ stroke-linejoin="round"
4642
+ class="medos-icon medos-icon-arrow-left"
4643
+ >
4644
+ <line x1="19" y1="12" x2="5" y2="12"></line>
4645
+ <polyline points="12 19 5 12 12 5"></polyline>
4646
+ </svg>
4647
+ `,
4648
+ users: (size = 20) => `
4649
+ <svg
4650
+ xmlns="http://www.w3.org/2000/svg"
4651
+ width="${size}"
4652
+ height="${size}"
4653
+ viewBox="0 0 24 24"
4654
+ fill="none"
4655
+ stroke="currentColor"
4656
+ stroke-width="2"
4657
+ stroke-linecap="round"
4658
+ stroke-linejoin="round"
4659
+ class="medos-icon medos-icon-users"
4660
+ >
4661
+ <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
4662
+ <circle cx="9" cy="7" r="4"></circle>
4663
+ <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
4664
+ <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
4665
+ </svg>
4666
+ `,
4667
+ plus: (size = 20) => `
4668
+ <svg
4669
+ xmlns="http://www.w3.org/2000/svg"
4670
+ width="${size}"
4671
+ height="${size}"
4672
+ viewBox="0 0 24 24"
4673
+ fill="none"
4674
+ stroke="currentColor"
4675
+ stroke-width="2"
4676
+ stroke-linecap="round"
4677
+ stroke-linejoin="round"
4678
+ class="medos-icon medos-icon-plus"
4679
+ >
4680
+ <line x1="12" y1="5" x2="12" y2="19"></line>
4681
+ <line x1="5" y1="12" x2="19" y2="12"></line>
4682
+ </svg>
4432
4683
  `,
4433
4684
  medosLogo: (width = 120, height = 114) => `
4434
4685
  <svg
@@ -4529,10 +4780,12 @@
4529
4780
  text-align: left;
4530
4781
  box-sizing: border-box;
4531
4782
  color: var(--medos-color-text, #111827);
4783
+ min-height: 40px;
4532
4784
  }
4533
4785
 
4534
4786
  .medos-select-trigger:hover:not(:disabled) {
4535
4787
  border-color: var(--medos-color-border-hover, #d1d5db);
4788
+ background-color: #f8fafc;
4536
4789
  }
4537
4790
 
4538
4791
  .medos-select-trigger:focus:not(:disabled) {
@@ -4566,6 +4819,8 @@
4566
4819
  overflow: hidden;
4567
4820
  text-overflow: ellipsis;
4568
4821
  white-space: nowrap;
4822
+ display: flex;
4823
+ align-items: center;
4569
4824
  }
4570
4825
 
4571
4826
  .medos-select-placeholder {
@@ -4605,6 +4860,7 @@
4605
4860
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
4606
4861
  animation: medos-select-show 0.15s ease-out;
4607
4862
  box-sizing: border-box;
4863
+ min-width: 180px;
4608
4864
  }
4609
4865
 
4610
4866
  @keyframes medos-select-show {
@@ -4640,6 +4896,7 @@
4640
4896
  transition: background-color 0.1s ease;
4641
4897
  box-sizing: border-box;
4642
4898
  color: #1e293b;
4899
+ min-height: 36px;
4643
4900
  }
4644
4901
 
4645
4902
  .medos-select-item:hover:not(.medos-select-item-disabled) {
@@ -4652,6 +4909,7 @@
4652
4909
 
4653
4910
  .medos-select-item-selected {
4654
4911
  background-color: #f3f4f6;
4912
+ font-weight: 500;
4655
4913
  }
4656
4914
 
4657
4915
  .medos-select-item-disabled {
@@ -4675,6 +4933,8 @@
4675
4933
  /* Item Text */
4676
4934
  .medos-select-item-text {
4677
4935
  flex: 1;
4936
+ display: flex;
4937
+ align-items: center;
4678
4938
  }
4679
4939
 
4680
4940
  /* Scrollbar styling */
@@ -4695,6 +4955,24 @@
4695
4955
  .medos-select-viewport::-webkit-scrollbar-thumb:hover {
4696
4956
  background: #94a3b8;
4697
4957
  }
4958
+
4959
+ /* Label styling for forms */
4960
+ .medos-form-label {
4961
+ display: block;
4962
+ font-size: 14px;
4963
+ font-weight: 500;
4964
+ margin-bottom: 6px;
4965
+ color: #374151;
4966
+ }
4967
+
4968
+ .medos-form-group {
4969
+ margin-bottom: 16px;
4970
+ }
4971
+
4972
+ /* Contact method specific styling */
4973
+ .medos-contact-method-container {
4974
+ margin-top: 8px;
4975
+ }
4698
4976
  `;
4699
4977
  document.head.appendChild(styleElement);
4700
4978
  }
@@ -4738,6 +5016,7 @@
4738
5016
  button.className = `medos-select-trigger ${this.config.error ? "medos-select-trigger-error" : ""}`;
4739
5017
  button.setAttribute("aria-expanded", this.isOpen.toString());
4740
5018
  button.setAttribute("aria-haspopup", "listbox");
5019
+ button.setAttribute("aria-label", "Select option");
4741
5020
  if (this.config.disabled) {
4742
5021
  button.disabled = true;
4743
5022
  }
@@ -4769,6 +5048,10 @@
4769
5048
  e.preventDefault();
4770
5049
  this.open();
4771
5050
  }
5051
+ else if (e.key === "ArrowUp") {
5052
+ e.preventDefault();
5053
+ this.open();
5054
+ }
4772
5055
  });
4773
5056
  }
4774
5057
  toggleOpen() {
@@ -4816,9 +5099,17 @@
4816
5099
  this.contentElement = document.createElement("div");
4817
5100
  this.contentElement.className = "medos-select-content";
4818
5101
  this.contentElement.setAttribute("role", "listbox");
4819
- this.contentElement.style.top = `${rect.bottom + scrollTop + 4}px`;
5102
+ this.contentElement.setAttribute("aria-label", "Options");
5103
+ const spaceBelow = window.innerHeight - rect.bottom;
5104
+ const spaceAbove = rect.top;
5105
+ const dropdownHeight = Math.min(256, this.options.length * 36 + 8);
5106
+ let top = rect.bottom + scrollTop + 4;
5107
+ if (spaceBelow < dropdownHeight && spaceAbove > dropdownHeight) {
5108
+ top = rect.top + scrollTop - dropdownHeight - 4;
5109
+ }
5110
+ this.contentElement.style.top = `${top}px`;
4820
5111
  this.contentElement.style.left = `${rect.left + scrollLeft}px`;
4821
- this.contentElement.style.width = `${rect.width}px`;
5112
+ this.contentElement.style.width = `${Math.max(rect.width, 180)}px`;
4822
5113
  this.contentElement.innerHTML = `
4823
5114
  <div class="medos-select-viewport">
4824
5115
  ${this.options
@@ -4833,6 +5124,7 @@
4833
5124
  data-label="${this.escapeHtml(option.label)}"
4834
5125
  ${option.disabled ? 'data-disabled="true"' : ""}
4835
5126
  tabindex="${option.disabled ? "-1" : "0"}"
5127
+ aria-label="${this.escapeHtml(option.label)}"
4836
5128
  >
4837
5129
  ${this.selectedValue === option.value
4838
5130
  ? `
@@ -4859,9 +5151,16 @@
4859
5151
  const rect = this.triggerElement.getBoundingClientRect();
4860
5152
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
4861
5153
  const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
4862
- this.contentElement.style.top = `${rect.bottom + scrollTop + 4}px`;
5154
+ const spaceBelow = window.innerHeight - rect.bottom;
5155
+ const spaceAbove = rect.top;
5156
+ const dropdownHeight = Math.min(256, this.options.length * 36 + 8);
5157
+ let top = rect.bottom + scrollTop + 4;
5158
+ if (spaceBelow < dropdownHeight && spaceAbove > dropdownHeight) {
5159
+ top = rect.top + scrollTop - dropdownHeight - 4;
5160
+ }
5161
+ this.contentElement.style.top = `${top}px`;
4863
5162
  this.contentElement.style.left = `${rect.left + scrollLeft}px`;
4864
- this.contentElement.style.width = `${rect.width}px`;
5163
+ this.contentElement.style.width = `${Math.max(rect.width, 180)}px`;
4865
5164
  }
4866
5165
  attachPortalEvents() {
4867
5166
  this.handleDocumentClick = (e) => {
@@ -4912,6 +5211,14 @@
4912
5211
  this.selectValue(value, label);
4913
5212
  }
4914
5213
  }
5214
+ else if (e.key === "Home") {
5215
+ e.preventDefault();
5216
+ this.focusFirstItem();
5217
+ }
5218
+ else if (e.key === "End") {
5219
+ e.preventDefault();
5220
+ this.focusLastItem();
5221
+ }
4915
5222
  });
4916
5223
  }
4917
5224
  }
@@ -4937,6 +5244,11 @@
4937
5244
  return;
4938
5245
  const currentFocused = document.activeElement;
4939
5246
  let currentIndex = items.indexOf(currentFocused);
5247
+ if (currentIndex === -1) {
5248
+ const targetIndex = direction > 0 ? 0 : items.length - 1;
5249
+ items[targetIndex]?.focus();
5250
+ return;
5251
+ }
4940
5252
  let nextIndex = currentIndex + direction;
4941
5253
  if (nextIndex < 0)
4942
5254
  nextIndex = items.length - 1;
@@ -4944,6 +5256,19 @@
4944
5256
  nextIndex = 0;
4945
5257
  items[nextIndex]?.focus();
4946
5258
  }
5259
+ focusFirstItem() {
5260
+ if (!this.contentElement)
5261
+ return;
5262
+ const firstItem = this.contentElement.querySelector(".medos-select-item:not(.medos-select-item-disabled)");
5263
+ firstItem?.focus();
5264
+ }
5265
+ focusLastItem() {
5266
+ if (!this.contentElement)
5267
+ return;
5268
+ const items = this.contentElement.querySelectorAll(".medos-select-item:not(.medos-select-item-disabled)");
5269
+ const lastItem = items[items.length - 1];
5270
+ lastItem?.focus();
5271
+ }
4947
5272
  selectValue(value, label) {
4948
5273
  this.selectedValue = value;
4949
5274
  this.selectedLabel = label;
@@ -4973,7 +5298,6 @@
4973
5298
  setDisabled(disabled) {
4974
5299
  this.config.disabled = disabled;
4975
5300
  this.renderTrigger();
4976
- this.attachTriggerEvents();
4977
5301
  }
4978
5302
  setError(error) {
4979
5303
  this.config.error = error;
@@ -4989,6 +5313,21 @@
4989
5313
  return div.innerHTML;
4990
5314
  }
4991
5315
  }
5316
+ function createContactMethodSelect(container, currentValue = "PHONE", onValueChange) {
5317
+ const contactOptions = [
5318
+ { value: "PHONE", label: "Phone" },
5319
+ { value: "EMAIL", label: "Email" },
5320
+ { value: "BOTH", label: "Both" },
5321
+ ];
5322
+ const select = new VanillaSelect(container, contactOptions, {
5323
+ placeholder: "Select contact method",
5324
+ onValueChange: (value) => {
5325
+ onValueChange?.(value);
5326
+ },
5327
+ });
5328
+ select.setValue(currentValue);
5329
+ return select;
5330
+ }
4992
5331
 
4993
5332
  function injectThemedStyles() {
4994
5333
  if (typeof document === "undefined")
@@ -5449,6 +5788,7 @@
5449
5788
  constructor(container, options) {
5450
5789
  this.mounted = true;
5451
5790
  this.countryCodeSelect = null;
5791
+ this.contactMethodSelect = null;
5452
5792
  injectThemedStyles();
5453
5793
  if (typeof container === "string") {
5454
5794
  const el = document.getElementById(container);
@@ -5498,7 +5838,7 @@
5498
5838
  this.setState({ error: "Please enter a valid name." });
5499
5839
  return false;
5500
5840
  }
5501
- if (!validateEmail(this.state.patientEmail)) {
5841
+ if (this.state.patientEmail && !validateEmail(this.state.patientEmail)) {
5502
5842
  this.setState({ error: "Please enter a valid email address." });
5503
5843
  return false;
5504
5844
  }
@@ -5614,7 +5954,7 @@
5614
5954
  ? `
5615
5955
  <div class="medos-enquiry-header">
5616
5956
  <h2 class="medos-enquiry-title">Submit Inquiry</h2>
5617
- <p class="medos-enquiry-step-indicator">Step ${this.state.step + 1} of 4</p>
5957
+ <p class="medos-enquiry-step-indicator">Step ${this.state.step + 1} of 3</p>
5618
5958
  </div>
5619
5959
 
5620
5960
  ${this.state.loading
@@ -5648,6 +5988,14 @@
5648
5988
  }
5649
5989
  }
5650
5990
  }
5991
+ if (this.state.step === 2) {
5992
+ const contactMethodContainer = this.container.querySelector("#medos-enquiry-contact-method-container");
5993
+ if (contactMethodContainer) {
5994
+ this.contactMethodSelect = createContactMethodSelect(contactMethodContainer, this.state.preferredContactMethod, (value) => {
5995
+ this.state.preferredContactMethod = value;
5996
+ });
5997
+ }
5998
+ }
5651
5999
  }
5652
6000
  renderStep() {
5653
6001
  switch (this.state.step) {
@@ -5683,7 +6031,7 @@
5683
6031
  </div>
5684
6032
 
5685
6033
  <div class="medos-form-group">
5686
- <label class="medos-label">Email Address <span class="medos-required">*</span></label>
6034
+ <label class="medos-label">Email Address</label>
5687
6035
  <input
5688
6036
  type="email"
5689
6037
  class="medos-input"
@@ -5767,37 +6115,9 @@
5767
6115
  </div>
5768
6116
  <div class="medos-section-body">
5769
6117
  <p class="medos-section-description">How would you prefer to be contacted?</p>
5770
- <div class="medos-contact-options">
5771
- <label class="medos-radio-option ${this.state.preferredContactMethod === "PHONE" ? "selected" : ""}">
5772
- <input
5773
- type="radio"
5774
- name="contact-method"
5775
- value="PHONE"
5776
- ${this.state.preferredContactMethod === "PHONE" ? "checked" : ""}
5777
- class="medos-radio-input"
5778
- />
5779
- <span class="medos-radio-label">Phone</span>
5780
- </label>
5781
- <label class="medos-radio-option ${this.state.preferredContactMethod === "EMAIL" ? "selected" : ""}">
5782
- <input
5783
- type="radio"
5784
- name="contact-method"
5785
- value="EMAIL"
5786
- ${this.state.preferredContactMethod === "EMAIL" ? "checked" : ""}
5787
- class="medos-radio-input"
5788
- />
5789
- <span class="medos-radio-label">Email</span>
5790
- </label>
5791
- <label class="medos-radio-option ${this.state.preferredContactMethod === "BOTH" ? "selected" : ""}">
5792
- <input
5793
- type="radio"
5794
- name="contact-method"
5795
- value="BOTH"
5796
- ${this.state.preferredContactMethod === "BOTH" ? "checked" : ""}
5797
- class="medos-radio-input"
5798
- />
5799
- <span class="medos-radio-label">Both</span>
5800
- </label>
6118
+ <div class="medos-form-group">
6119
+ <label class="medos-label">Preferred Contact Method</label>
6120
+ <div class="medos-contact-method-container" id="medos-enquiry-contact-method-container"></div>
5801
6121
  </div>
5802
6122
  </div>
5803
6123
  </div>
@@ -5860,7 +6180,7 @@
5860
6180
  <div style="position: relative; display: inline-block;">
5861
6181
  <svg width="64" height="64" viewBox="0 0 41 41" fill="none">
5862
6182
  <path
5863
- 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"
6183
+ d="M31.1309 4.90254C32.388 4.98797 33.0166 5.03069 33.5247 5.25288 C34.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"
5864
6184
  fill="#006E0F"
5865
6185
  />
5866
6186
  </svg>
@@ -5924,13 +6244,6 @@
5924
6244
  this.render();
5925
6245
  });
5926
6246
  }
5927
- const contactMethodRadios = this.container.querySelectorAll('input[name="contact-method"]');
5928
- contactMethodRadios.forEach((radio) => {
5929
- radio.addEventListener("change", (e) => {
5930
- const target = e.target;
5931
- this.state.preferredContactMethod = target.value;
5932
- });
5933
- });
5934
6247
  const nextBtn = this.container.querySelector("#medos-enquiry-btn-next");
5935
6248
  if (nextBtn) {
5936
6249
  nextBtn.addEventListener("click", () => this.goToNext());
@@ -5955,6 +6268,14 @@
5955
6268
  }
5956
6269
  destroy() {
5957
6270
  this.mounted = false;
6271
+ if (this.countryCodeSelect) {
6272
+ this.countryCodeSelect.destroy();
6273
+ this.countryCodeSelect = null;
6274
+ }
6275
+ if (this.contactMethodSelect) {
6276
+ this.contactMethodSelect.destroy();
6277
+ this.contactMethodSelect = null;
6278
+ }
5958
6279
  this.container.innerHTML = "";
5959
6280
  }
5960
6281
  }
@@ -14,3 +14,5 @@ export * from "./appointment-calendar/types";
14
14
  export * from "./enquiry-form/provider";
15
15
  export * from "./enquiry-form/types";
16
16
  export { PatientService, SendPhoneVerificationOtpPayload, VerifyPhoneVerificationOtpPayload, } from "./services/PatientService";
17
+ export { WorkspaceService } from "./services/WorkspaceService";
18
+ export type { WorkspaceResponse, Address, ConsultationType, User, Doctor, AddressDoctor, } from "./services/WorkspaceService";
@@ -10,8 +10,9 @@ export interface MedosThemeProviderProps {
10
10
  children: React.ReactNode;
11
11
  theme?: ThemeName | MedosTheme | PartialTheme;
12
12
  cssVariablePrefix?: string;
13
+ onThemeError?: (error: Error) => void;
13
14
  }
14
- export declare function MedosThemeProvider({ children, theme, cssVariablePrefix, }: MedosThemeProviderProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function MedosThemeProvider({ children, theme, cssVariablePrefix, onThemeError, }: Readonly<MedosThemeProviderProps>): import("react/jsx-runtime").JSX.Element;
15
16
  export declare function useThemeContext(): ThemeContextValue;
16
17
  export declare function useTheme(): MedosTheme;
17
18
  export declare function useCssVar(category: string, key: string, fallback?: string): string;