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
@@ -0,0 +1,318 @@
1
+ import { useCallback } from "react";
2
+ import { AppointmentService } from "../../../services/AppointmentService";
3
+ import { PatientService } from "../../../services/PatientService";
4
+ import { validatePhoneNumber, validateCountryCode, } from "../../../components/validation";
5
+ import { formatDateToISO, parsePatientName } from "../../../components/utils";
6
+ export const useAppointmentFlow = (state, dispatch, onError) => {
7
+ const goBack = useCallback(() => {
8
+ if (state.step === 2) {
9
+ dispatch({ type: "SET_OTP_SENT", payload: false });
10
+ dispatch({ type: "SET_OTP_CODE", payload: "" });
11
+ dispatch({ type: "SET_OTP_VERIFIED", payload: false });
12
+ dispatch({ type: "SET_STEP", payload: 1 });
13
+ }
14
+ else if (state.step === 3) {
15
+ dispatch({ type: "SET_STEP", payload: 2 });
16
+ }
17
+ else if (state.step === 4) {
18
+ if (state.verifiedPatients && state.verifiedPatients.length > 0) {
19
+ dispatch({ type: "SET_STEP", payload: 3 });
20
+ }
21
+ else {
22
+ dispatch({ type: "SET_STEP", payload: 2 });
23
+ }
24
+ }
25
+ else {
26
+ dispatch({ type: "SET_STEP", payload: Math.max(0, state.step - 1) });
27
+ }
28
+ }, [state.step, state.verifiedPatients, dispatch]);
29
+ const handleDateChange = useCallback(async (date) => {
30
+ dispatch({ type: "SET_SELECTED_DATE", payload: date });
31
+ if (!state.workspaceId ||
32
+ !state.selectedAddress ||
33
+ !state.selectedDoctor) {
34
+ dispatch({ type: "SET_SLOTS", payload: [] });
35
+ return;
36
+ }
37
+ let mounted = true;
38
+ dispatch({ type: "SET_LOADING", payload: true });
39
+ dispatch({ type: "SET_ERROR", payload: null });
40
+ try {
41
+ const dateStr = formatDateToISO(date);
42
+ const fetchedSlots = await AppointmentService.fetchSlots(state.workspaceId, state.selectedAddress, state.selectedDoctor, dateStr);
43
+ if (mounted) {
44
+ dispatch({ type: "SET_SLOTS", payload: fetchedSlots || [] });
45
+ }
46
+ }
47
+ catch (e) {
48
+ if (mounted) {
49
+ const msg = e.message || "Failed to load slots";
50
+ dispatch({ type: "SET_ERROR", payload: msg });
51
+ onError?.(e);
52
+ }
53
+ }
54
+ finally {
55
+ if (mounted)
56
+ dispatch({ type: "SET_LOADING", payload: false });
57
+ }
58
+ return () => {
59
+ mounted = false;
60
+ };
61
+ }, [
62
+ state.workspaceId,
63
+ state.selectedAddress,
64
+ state.selectedDoctor,
65
+ dispatch,
66
+ onError,
67
+ ]);
68
+ const sendOtp = useCallback(async () => {
69
+ dispatch({ type: "SET_ERROR", payload: null });
70
+ if (!state.countryCode) {
71
+ dispatch({ type: "SET_ERROR", payload: "Please enter country code." });
72
+ return;
73
+ }
74
+ if (!validateCountryCode(state.countryCode)) {
75
+ dispatch({
76
+ type: "SET_ERROR",
77
+ payload: "Please enter a valid country code (e.g., +91, +1).",
78
+ });
79
+ return;
80
+ }
81
+ if (!state.patientPhone) {
82
+ dispatch({ type: "SET_ERROR", payload: "Please enter phone number." });
83
+ return;
84
+ }
85
+ if (!validatePhoneNumber(state.patientPhone)) {
86
+ dispatch({
87
+ type: "SET_ERROR",
88
+ payload: "Please enter a valid phone number (7-15 digits).",
89
+ });
90
+ return;
91
+ }
92
+ dispatch({ type: "SET_OTP_SENDING", payload: true });
93
+ try {
94
+ await PatientService.sendPhoneVerificationOtp({
95
+ countryCode: state.countryCode,
96
+ phoneNumber: state.patientPhone,
97
+ });
98
+ dispatch({ type: "SET_OTP_SENT", payload: true });
99
+ dispatch({ type: "SET_ERROR", payload: null });
100
+ }
101
+ catch (e) {
102
+ const msg = e.message || "Failed to send OTP";
103
+ dispatch({ type: "SET_ERROR", payload: msg });
104
+ onError?.(e);
105
+ }
106
+ finally {
107
+ dispatch({ type: "SET_OTP_SENDING", payload: false });
108
+ }
109
+ }, [state.countryCode, state.patientPhone, dispatch, onError]);
110
+ const verifyOtp = useCallback(async () => {
111
+ dispatch({ type: "SET_ERROR", payload: null });
112
+ if (!state.countryCode || !state.patientPhone || !state.otpCode) {
113
+ dispatch({
114
+ type: "SET_ERROR",
115
+ payload: "Please enter all required fields.",
116
+ });
117
+ return;
118
+ }
119
+ if (state.otpCode.length !== 6) {
120
+ dispatch({
121
+ type: "SET_ERROR",
122
+ payload: "Please enter a 6-digit OTP code.",
123
+ });
124
+ return;
125
+ }
126
+ dispatch({ type: "SET_OTP_VERIFYING", payload: true });
127
+ try {
128
+ const response = await PatientService.verifyPhoneVerificationOtp({
129
+ countryCode: state.countryCode,
130
+ phoneNumber: state.patientPhone,
131
+ otpCode: state.otpCode,
132
+ });
133
+ dispatch({ type: "SET_OTP_VERIFIED", payload: true });
134
+ dispatch({ type: "SET_ERROR", payload: null });
135
+ const sessionPacksDetails = response.sessionPacksDetails;
136
+ if (sessionPacksDetails?.associatedPatients &&
137
+ sessionPacksDetails.associatedPatients.length > 0) {
138
+ dispatch({
139
+ type: "SET_VERIFIED_PATIENTS",
140
+ payload: sessionPacksDetails.associatedPatients,
141
+ });
142
+ }
143
+ else if (response.patients && response.patients.length > 0) {
144
+ dispatch({ type: "SET_VERIFIED_PATIENTS", payload: response.patients });
145
+ }
146
+ else {
147
+ dispatch({ type: "SET_VERIFIED_PATIENTS", payload: [] });
148
+ }
149
+ if (sessionPacksDetails?.activeSessionPackResponses &&
150
+ sessionPacksDetails.activeSessionPackResponses.length > 0) {
151
+ const userSessionPacks = sessionPacksDetails.activeSessionPackResponses.map((pack) => ({
152
+ id: pack.id,
153
+ name: pack.packageName || pack.name,
154
+ description: pack.description,
155
+ totalSessions: pack.totalSessions,
156
+ remainingSessions: pack.remainingSessions,
157
+ expiryDate: pack.expiryDate,
158
+ purchaseDate: pack.purchaseDate,
159
+ doctorId: pack.doctorId,
160
+ doctorName: pack.doctorName,
161
+ allowedConsultationModes: pack.allowedConsultationModes,
162
+ }));
163
+ dispatch({ type: "SET_USER_SESSION_PACKS", payload: userSessionPacks });
164
+ }
165
+ else {
166
+ dispatch({ type: "SET_USER_SESSION_PACKS", payload: [] });
167
+ }
168
+ if (sessionPacksDetails?.allSessionPackResponses &&
169
+ sessionPacksDetails.allSessionPackResponses.length > 0) {
170
+ const availablePackages = sessionPacksDetails.allSessionPackResponses.map((pack) => ({
171
+ id: pack.id,
172
+ name: pack.packageName,
173
+ description: pack.description,
174
+ totalSessions: pack.totalSessions,
175
+ sessions: pack.totalSessions,
176
+ price: pack.packagePrice,
177
+ discountedPrice: pack.discountedPrice,
178
+ discount: pack.discount,
179
+ discountType: pack.discountType,
180
+ currency: "INR",
181
+ validityDays: pack.validityDays,
182
+ allowedConsultationModes: pack.allowedConsultationModes,
183
+ allowedDoctors: pack.allowedDoctors,
184
+ applicableOnline: pack.allowedConsultationModes?.includes("ONLINE"),
185
+ applicableOffline: pack.allowedConsultationModes?.includes("OFFLINE"),
186
+ }));
187
+ dispatch({
188
+ type: "SET_AVAILABLE_PACKAGES",
189
+ payload: availablePackages,
190
+ });
191
+ }
192
+ else {
193
+ dispatch({ type: "SET_AVAILABLE_PACKAGES", payload: [] });
194
+ }
195
+ }
196
+ catch (e) {
197
+ const msg = e.message || "Invalid OTP code";
198
+ dispatch({ type: "SET_ERROR", payload: msg });
199
+ onError?.(e);
200
+ }
201
+ finally {
202
+ dispatch({ type: "SET_OTP_VERIFYING", payload: false });
203
+ }
204
+ }, [state.countryCode, state.patientPhone, state.otpCode, dispatch, onError]);
205
+ const submitAppointment = useCallback(async () => {
206
+ dispatch({ type: "SET_ERROR", payload: null });
207
+ if (!state.selectedDoctor ||
208
+ !state.selectedSlot ||
209
+ !state.workspaceId ||
210
+ !state.selectedAddress) {
211
+ dispatch({
212
+ type: "SET_ERROR",
213
+ payload: "Please ensure all required fields are complete.",
214
+ });
215
+ return;
216
+ }
217
+ if (!state.otpVerified) {
218
+ dispatch({
219
+ type: "SET_ERROR",
220
+ payload: "Please verify your phone number first.",
221
+ });
222
+ return;
223
+ }
224
+ if (!state.patientName || !state.patientAge || !state.patientGender) {
225
+ dispatch({
226
+ type: "SET_ERROR",
227
+ payload: "Please fill in all patient details.",
228
+ });
229
+ return;
230
+ }
231
+ if (!state.patientAddress ||
232
+ !state.patientCity ||
233
+ !state.patientState ||
234
+ !state.patientCountry ||
235
+ !state.patientZipcode) {
236
+ dispatch({
237
+ type: "SET_ERROR",
238
+ payload: "Please fill in all address fields.",
239
+ });
240
+ return;
241
+ }
242
+ dispatch({ type: "SET_LOADING", payload: true });
243
+ try {
244
+ const { firstName, lastName } = parsePatientName(state.patientName);
245
+ const appointmentDate = formatDateToISO(state.selectedDate);
246
+ const patientPayload = {
247
+ firstName,
248
+ lastName,
249
+ countryCode: state.countryCode,
250
+ phoneNumber: state.patientPhone,
251
+ age: Number.parseInt(state.patientAge, 10),
252
+ gender: state.patientGender.toUpperCase(),
253
+ };
254
+ if (state.patientEmail) {
255
+ patientPayload.email = state.patientEmail;
256
+ }
257
+ if (state.bloodGroup) {
258
+ patientPayload.bloodGroup = state.bloodGroup;
259
+ }
260
+ if (state.useExistingPatient && state.selectedPatient) {
261
+ patientPayload.id = state.selectedPatient.id;
262
+ }
263
+ const appointmentPayload = {
264
+ workspaceId: state.workspaceId,
265
+ workspaceAddressId: state.selectedAddress,
266
+ doctorId: state.selectedDoctor,
267
+ mode: state.consultationMode,
268
+ appointmentDate: appointmentDate,
269
+ fromDateTimeTs: state.selectedSlot.start,
270
+ toDateTimeTs: state.selectedSlot.end,
271
+ consultationCharge: state.consultationCharge || "0",
272
+ type: "CONSULTATION",
273
+ source: "SDK_POWERED_WEBSITE",
274
+ bookingType: state.bookingType,
275
+ paymentMode: state.paymentMode,
276
+ patientPayload,
277
+ patientAddress: {
278
+ addressLine1: state.patientAddress,
279
+ addressLine2: "",
280
+ city: state.patientCity,
281
+ state: state.patientState,
282
+ country: state.patientCountry,
283
+ zipcode: state.patientZipcode,
284
+ landmark: state.patientLandmark || undefined,
285
+ countryCode: state.countryCode,
286
+ phoneNumber: state.patientPhone,
287
+ patientId: state.selectedPatient?.id || 0,
288
+ },
289
+ };
290
+ if (state.packageConfigId) {
291
+ appointmentPayload.packageConfigId = state.packageConfigId;
292
+ }
293
+ if (state.patientPackageId) {
294
+ appointmentPayload.patientPackageId = state.patientPackageId;
295
+ }
296
+ if (state.packageAmount) {
297
+ appointmentPayload.packageAmount = state.packageAmount;
298
+ }
299
+ await AppointmentService.createAppointment(appointmentPayload);
300
+ dispatch({ type: "SET_STEP", payload: 7 });
301
+ }
302
+ catch (e) {
303
+ const msg = e.message || "Failed to create appointment";
304
+ dispatch({ type: "SET_ERROR", payload: msg });
305
+ onError?.(e);
306
+ }
307
+ finally {
308
+ dispatch({ type: "SET_LOADING", payload: false });
309
+ }
310
+ }, [state, dispatch, onError]);
311
+ return {
312
+ goBack,
313
+ handleDateChange,
314
+ sendOtp,
315
+ verifyOtp,
316
+ submitAppointment,
317
+ };
318
+ };
@@ -0,0 +1,9 @@
1
+ import { AppointmentState, AppointmentAction } from "../types";
2
+ export declare const useAppointmentState: () => {
3
+ state: AppointmentState;
4
+ dispatch: import("react").Dispatch<AppointmentAction>;
5
+ setStep: (step: number) => void;
6
+ setError: (error: string | null) => void;
7
+ setLoading: (loading: boolean) => void;
8
+ resetForm: () => void;
9
+ };
@@ -0,0 +1,125 @@
1
+ import { useReducer, useCallback } from "react";
2
+ import { INITIAL_STATE } from "../types";
3
+ const appointmentReducer = (state, action) => {
4
+ switch (action.type) {
5
+ case "SET_STEP":
6
+ return { ...state, step: action.payload };
7
+ case "SET_LOADING":
8
+ return { ...state, loading: action.payload };
9
+ case "SET_ERROR":
10
+ return { ...state, error: action.payload };
11
+ case "SET_WORKSPACE": {
12
+ const doctorMap = {};
13
+ action.payload.addresses.forEach((addr) => {
14
+ doctorMap[addr.id] = addr.doctors || [];
15
+ });
16
+ return {
17
+ ...state,
18
+ workspaceId: action.payload.id,
19
+ addresses: action.payload.addresses,
20
+ addressDoctorsMap: doctorMap,
21
+ };
22
+ }
23
+ case "SET_SELECTED_ADDRESS":
24
+ return { ...state, selectedAddress: action.payload };
25
+ case "SET_SELECTED_DOCTOR":
26
+ return { ...state, selectedDoctor: action.payload };
27
+ case "SET_SELECTED_DATE":
28
+ return { ...state, selectedDate: action.payload, selectedSlot: null };
29
+ case "SET_SLOTS":
30
+ return { ...state, slots: action.payload };
31
+ case "SET_SELECTED_SLOT":
32
+ return { ...state, selectedSlot: action.payload };
33
+ case "SET_CONSULTATION_MODE":
34
+ return { ...state, consultationMode: action.payload };
35
+ case "SET_CONSULTATION_CHARGE":
36
+ return { ...state, consultationCharge: action.payload };
37
+ case "SET_PATIENT_NAME":
38
+ return { ...state, patientName: action.payload };
39
+ case "SET_PATIENT_AGE":
40
+ return { ...state, patientAge: action.payload };
41
+ case "SET_PATIENT_EMAIL":
42
+ return { ...state, patientEmail: action.payload };
43
+ case "SET_PATIENT_GENDER":
44
+ return { ...state, patientGender: action.payload };
45
+ case "SET_BLOOD_GROUP":
46
+ return { ...state, bloodGroup: action.payload };
47
+ case "SET_PATIENT_ADDRESS":
48
+ return { ...state, patientAddress: action.payload };
49
+ case "SET_PATIENT_CITY":
50
+ return { ...state, patientCity: action.payload };
51
+ case "SET_PATIENT_STATE":
52
+ return { ...state, patientState: action.payload };
53
+ case "SET_PATIENT_COUNTRY":
54
+ return { ...state, patientCountry: action.payload };
55
+ case "SET_PATIENT_ZIPCODE":
56
+ return { ...state, patientZipcode: action.payload };
57
+ case "SET_PATIENT_LANDMARK":
58
+ return { ...state, patientLandmark: action.payload };
59
+ case "SET_COUNTRY_CODE":
60
+ return { ...state, countryCode: action.payload };
61
+ case "SET_PATIENT_PHONE":
62
+ return { ...state, patientPhone: action.payload };
63
+ case "SET_OTP_CODE":
64
+ return { ...state, otpCode: action.payload };
65
+ case "SET_OTP_SENT":
66
+ return { ...state, otpSent: action.payload };
67
+ case "SET_OTP_VERIFIED":
68
+ return { ...state, otpVerified: action.payload };
69
+ case "SET_OTP_SENDING":
70
+ return { ...state, otpSending: action.payload };
71
+ case "SET_OTP_VERIFYING":
72
+ return { ...state, otpVerifying: action.payload };
73
+ case "SET_VERIFIED_PATIENTS":
74
+ return { ...state, verifiedPatients: action.payload };
75
+ case "SET_SELECTED_PATIENT":
76
+ return { ...state, selectedPatient: action.payload };
77
+ case "SET_USE_EXISTING_PATIENT":
78
+ return { ...state, useExistingPatient: action.payload };
79
+ case "SET_USER_SESSION_PACKS":
80
+ return { ...state, userSessionPacks: action.payload };
81
+ case "SET_AVAILABLE_PACKAGES":
82
+ return { ...state, availablePackages: action.payload };
83
+ case "SET_SELECTED_SESSION_PACK":
84
+ return { ...state, selectedSessionPack: action.payload };
85
+ case "SET_SELECTED_NEW_PACKAGE":
86
+ return { ...state, selectedNewPackage: action.payload };
87
+ case "SET_BOOKING_OPTION_TYPE":
88
+ return { ...state, bookingOptionType: action.payload };
89
+ case "SET_SHOW_PACKAGE_EXPLORER":
90
+ return { ...state, showPackageExplorer: action.payload };
91
+ case "SET_PACKAGES_LOADING":
92
+ return { ...state, packagesLoading: action.payload };
93
+ case "SET_BOOKING_TYPE":
94
+ return { ...state, bookingType: action.payload };
95
+ case "SET_PAYMENT_MODE":
96
+ return { ...state, paymentMode: action.payload };
97
+ case "SET_PACKAGE_CONFIG_ID":
98
+ return { ...state, packageConfigId: action.payload };
99
+ case "SET_PATIENT_PACKAGE_ID":
100
+ return { ...state, patientPackageId: action.payload };
101
+ case "SET_PACKAGE_AMOUNT":
102
+ return { ...state, packageAmount: action.payload };
103
+ case "SET_PATIENT_DOB":
104
+ return { ...state, patientDob: action.payload };
105
+ case "RESET_FORM":
106
+ return INITIAL_STATE;
107
+ default:
108
+ return state;
109
+ }
110
+ };
111
+ export const useAppointmentState = () => {
112
+ const [state, dispatch] = useReducer(appointmentReducer, INITIAL_STATE);
113
+ const setStep = useCallback((step) => dispatch({ type: "SET_STEP", payload: step }), []);
114
+ const setError = useCallback((error) => dispatch({ type: "SET_ERROR", payload: error }), []);
115
+ const setLoading = useCallback((loading) => dispatch({ type: "SET_LOADING", payload: loading }), []);
116
+ const resetForm = useCallback(() => dispatch({ type: "RESET_FORM" }), []);
117
+ return {
118
+ state,
119
+ dispatch,
120
+ setStep,
121
+ setError,
122
+ setLoading,
123
+ resetForm,
124
+ };
125
+ };
@@ -0,0 +1 @@
1
+ export declare const useInitializeAddresses: (dispatch: React.Dispatch<any>, onError?: (error: Error) => void) => void;
@@ -0,0 +1,55 @@
1
+ import { useEffect } from "react";
2
+ import { AppointmentService } from "../../../services/AppointmentService";
3
+ export const useInitializeAddresses = (dispatch, onError) => {
4
+ useEffect(() => {
5
+ let mounted = true;
6
+ (async () => {
7
+ dispatch({ type: "SET_LOADING", payload: true });
8
+ dispatch({ type: "SET_ERROR", payload: null });
9
+ try {
10
+ const response = await AppointmentService.getAddresses();
11
+ if (!mounted)
12
+ return;
13
+ if (response.workspaceId && response.addresses?.length > 0) {
14
+ dispatch({
15
+ type: "SET_WORKSPACE",
16
+ payload: {
17
+ id: response.workspaceId,
18
+ addresses: response.addresses,
19
+ },
20
+ });
21
+ if (response.addresses.length === 1) {
22
+ const address = response.addresses[0];
23
+ dispatch({ type: "SET_SELECTED_ADDRESS", payload: address.id });
24
+ if (address.doctors?.length === 1) {
25
+ dispatch({
26
+ type: "SET_SELECTED_DOCTOR",
27
+ payload: address.doctors[0].id,
28
+ });
29
+ }
30
+ }
31
+ }
32
+ else {
33
+ dispatch({
34
+ type: "SET_ERROR",
35
+ payload: "No addresses or doctors available.",
36
+ });
37
+ }
38
+ }
39
+ catch (e) {
40
+ if (!mounted)
41
+ return;
42
+ const msg = e.message || "Failed to load addresses";
43
+ dispatch({ type: "SET_ERROR", payload: msg });
44
+ onError?.(e);
45
+ }
46
+ finally {
47
+ if (mounted)
48
+ dispatch({ type: "SET_LOADING", payload: false });
49
+ }
50
+ })();
51
+ return () => {
52
+ mounted = false;
53
+ };
54
+ }, [dispatch, onError]);
55
+ };
@@ -0,0 +1,5 @@
1
+ export { AppointmentCalender } from "./AppointmentCalender";
2
+ export type { AppointmentCalenderProps } from "./AppointmentCalender";
3
+ export { useAppointmentState, useAppointmentFlow, useInitializeAddresses, } from "./hooks";
4
+ export type { AppointmentState, AppointmentAction } from "./types";
5
+ export { INITIAL_STATE } from "./types";
@@ -0,0 +1,3 @@
1
+ export { AppointmentCalender } from "./AppointmentCalender";
2
+ export { useAppointmentState, useAppointmentFlow, useInitializeAddresses, } from "./hooks";
3
+ export { INITIAL_STATE } from "./types";