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
@@ -2,31 +2,165 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { AppointmentDateTimeModal } from "../AppointmentDateTimeModal";
3
3
  import { DoctorSelectModal } from "../DoctorSelectModal";
4
4
  import { PhoneVerificationStep } from "../PhoneVerificationStep";
5
+ import { PatientSelectionStep } from "../PatientSelectionStep";
5
6
  import { PatientDetailsStep } from "../PatientDetailsStep";
6
7
  import AppointmentConfirmationStep from "../AppointmentConfirmationStep";
8
+ import { BookingOptionStep } from "../BookingOptionStep";
9
+ import { AppointmentSummaryStep } from "../AppointmentSummaryStep";
7
10
  import { useTheme } from "../../react/hooks/useTheme";
11
+ import { useBreakpoint } from "../../core/theme/responsive";
8
12
  import MedosLogo from "../Icons/MedosLogo";
9
13
  import { useAppointmentState, useAppointmentFlow, useInitializeAddresses, } from "./hooks";
10
14
  import { formatDateToISO } from "../utils";
11
15
  export const AppointmentCalender = ({ onError, }) => {
12
16
  const { state, dispatch, setStep, resetForm } = useAppointmentState();
13
- const { goBack, goToNext, handleDateChange, sendOtp, verifyOtp, submitAppointment, } = useAppointmentFlow(state, dispatch, onError);
17
+ const { goBack, handleDateChange, sendOtp, verifyOtp, submitAppointment } = useAppointmentFlow(state, dispatch, onError);
14
18
  useInitializeAddresses(dispatch, onError);
19
+ const handlePhoneVerificationContinue = () => {
20
+ if (state.otpVerified) {
21
+ const activePack = state.userSessionPacks?.find((pack) => pack.remainingSessions > 0);
22
+ const hasAvailablePackages = (state.availablePackages || []).length > 0;
23
+ if (!activePack && !hasAvailablePackages) {
24
+ dispatch({
25
+ type: "SET_BOOKING_OPTION_TYPE",
26
+ payload: "new-appointment",
27
+ });
28
+ dispatch({ type: "SET_BOOKING_TYPE", payload: "ONE_TIME_APPOINTMENT" });
29
+ setStep(2);
30
+ }
31
+ else {
32
+ setStep(1);
33
+ }
34
+ }
35
+ };
36
+ const handleBookingOptionSelect = (optionType, sessionPack, newPackage) => {
37
+ dispatch({ type: "SET_BOOKING_OPTION_TYPE", payload: optionType });
38
+ if (optionType === "session-pack" && sessionPack) {
39
+ dispatch({ type: "SET_SELECTED_SESSION_PACK", payload: sessionPack });
40
+ dispatch({ type: "SET_BOOKING_TYPE", payload: "USE_ACTIVE_PACKAGE" });
41
+ setStep(2);
42
+ }
43
+ else if (optionType === "explore-packages") {
44
+ dispatch({ type: "SET_BOOKING_TYPE", payload: "PACKAGE_PURCHASE" });
45
+ dispatch({ type: "SET_SHOW_PACKAGE_EXPLORER", payload: true });
46
+ }
47
+ else if (optionType === "new-appointment") {
48
+ dispatch({ type: "SET_BOOKING_TYPE", payload: "ONE_TIME_APPOINTMENT" });
49
+ setStep(2);
50
+ }
51
+ };
52
+ const handlePackageSelect = (pkg) => {
53
+ dispatch({ type: "SET_SELECTED_NEW_PACKAGE", payload: pkg });
54
+ dispatch({ type: "SET_BOOKING_TYPE", payload: "PACKAGE_PURCHASE" });
55
+ dispatch({ type: "SET_SHOW_PACKAGE_EXPLORER", payload: false });
56
+ setStep(2);
57
+ };
15
58
  const handleDoctorSelect = (addrId, docId) => {
16
59
  dispatch({ type: "SET_SELECTED_ADDRESS", payload: addrId });
17
60
  dispatch({ type: "SET_SELECTED_DOCTOR", payload: docId });
18
- setStep(1);
61
+ setStep(3);
19
62
  };
20
63
  const handleDateTimeModalContinue = (mode, date, slot, charge) => {
21
64
  dispatch({ type: "SET_CONSULTATION_MODE", payload: mode });
22
65
  dispatch({ type: "SET_SELECTED_DATE", payload: date });
23
66
  dispatch({ type: "SET_SELECTED_SLOT", payload: slot });
24
67
  dispatch({ type: "SET_CONSULTATION_CHARGE", payload: charge });
25
- setStep(3);
68
+ setStep(4);
69
+ };
70
+ const handleSelectExistingPatient = (patient) => {
71
+ dispatch({ type: "SET_SELECTED_PATIENT", payload: patient });
72
+ dispatch({ type: "SET_USE_EXISTING_PATIENT", payload: true });
73
+ dispatch({
74
+ type: "SET_PATIENT_NAME",
75
+ payload: `${patient.firstName} ${patient.lastName}`,
76
+ });
77
+ dispatch({ type: "SET_PATIENT_EMAIL", payload: patient.email });
78
+ dispatch({ type: "SET_PATIENT_AGE", payload: patient.age.toString() });
79
+ dispatch({ type: "SET_PATIENT_GENDER", payload: patient.gender });
80
+ dispatch({ type: "SET_BLOOD_GROUP", payload: patient.bloodGroup });
81
+ if (patient.address) {
82
+ dispatch({
83
+ type: "SET_PATIENT_ADDRESS",
84
+ payload: patient.address.addressLine1,
85
+ });
86
+ dispatch({ type: "SET_PATIENT_CITY", payload: patient.address.city });
87
+ dispatch({ type: "SET_PATIENT_STATE", payload: patient.address.state });
88
+ dispatch({
89
+ type: "SET_PATIENT_COUNTRY",
90
+ payload: patient.address.country,
91
+ });
92
+ dispatch({
93
+ type: "SET_PATIENT_ZIPCODE",
94
+ payload: patient.address.zipcode,
95
+ });
96
+ dispatch({
97
+ type: "SET_PATIENT_LANDMARK",
98
+ payload: patient.address.landmark || "",
99
+ });
100
+ }
101
+ setStep(6);
102
+ };
103
+ const handleProceedAsNewPatient = () => {
104
+ dispatch({ type: "SET_SELECTED_PATIENT", payload: null });
105
+ dispatch({ type: "SET_USE_EXISTING_PATIENT", payload: false });
106
+ dispatch({ type: "SET_PATIENT_NAME", payload: "" });
107
+ dispatch({ type: "SET_PATIENT_EMAIL", payload: "" });
108
+ dispatch({ type: "SET_PATIENT_AGE", payload: "" });
109
+ dispatch({ type: "SET_PATIENT_GENDER", payload: "" });
110
+ dispatch({ type: "SET_BLOOD_GROUP", payload: "" });
111
+ dispatch({ type: "SET_PATIENT_ADDRESS", payload: "" });
112
+ dispatch({ type: "SET_PATIENT_CITY", payload: "" });
113
+ dispatch({ type: "SET_PATIENT_STATE", payload: "" });
114
+ dispatch({ type: "SET_PATIENT_COUNTRY", payload: "" });
115
+ dispatch({ type: "SET_PATIENT_ZIPCODE", payload: "" });
116
+ dispatch({ type: "SET_PATIENT_LANDMARK", payload: "" });
117
+ setStep(5);
118
+ };
119
+ const handlePatientDetailsSubmit = async () => {
120
+ setStep(6);
121
+ };
122
+ const handleSummaryConfirm = async () => {
123
+ await submitAppointment();
124
+ };
125
+ const handleGoBack = () => {
126
+ if (state.showPackageExplorer) {
127
+ dispatch({ type: "SET_SHOW_PACKAGE_EXPLORER", payload: false });
128
+ return;
129
+ }
130
+ const currentStep = state.step;
131
+ if (currentStep > 0) {
132
+ if (currentStep === 6 && state.useExistingPatient) {
133
+ dispatch({ type: "SET_SELECTED_PATIENT", payload: null });
134
+ dispatch({ type: "SET_USE_EXISTING_PATIENT", payload: false });
135
+ setStep(4);
136
+ return;
137
+ }
138
+ if (currentStep === 2) {
139
+ dispatch({ type: "SET_BOOKING_OPTION_TYPE", payload: null });
140
+ dispatch({ type: "SET_SELECTED_SESSION_PACK", payload: null });
141
+ dispatch({ type: "SET_SELECTED_NEW_PACKAGE", payload: null });
142
+ const activePack = state.userSessionPacks?.find((pack) => pack.remainingSessions > 0);
143
+ const hasAvailablePackages = (state.availablePackages || []).length > 0;
144
+ if (!activePack && !hasAvailablePackages) {
145
+ setStep(0);
146
+ }
147
+ else {
148
+ setStep(1);
149
+ }
150
+ }
151
+ else {
152
+ setStep(currentStep - 1);
153
+ }
154
+ }
26
155
  };
27
156
  const theme = useTheme();
28
- const styles = getStyles(theme);
29
- return (_jsx("div", { style: styles.container, children: _jsxs("div", { style: styles.card, children: [_jsx("div", { style: styles.header, children: _jsx("h2", { style: styles.title, children: "Book Appointment" }) }), _jsx("hr", {}), _jsxs("div", { style: styles.content, children: [state.loading && _jsx("div", { style: { marginBottom: 12 }, children: "Loading..." }), state.error && _jsx("div", { style: styles.errorMessage, children: state.error }), state.step === 0 && (_jsx(DoctorSelectModal, { addresses: state.addresses, addressDoctorsMap: state.addressDoctorsMap, selectedAddressId: state.selectedAddress, selectedDoctorId: state.selectedDoctor, onCancel: () => setStep(0), onContinue: handleDoctorSelect })), state.step === 1 && (_jsx(AppointmentDateTimeModal, { onlineFee: 500, offlineFee: 300, slots: state.slots, selectedDate: state.selectedDate, selectedSlot: state.selectedSlot, consultationMode: state.consultationMode, onCancel: goBack, onDateChange: handleDateChange, onContinue: handleDateTimeModalContinue })), state.step === 3 && (_jsx(PhoneVerificationStep, { state: state, dispatch: dispatch, onSendOtp: sendOtp, onVerifyOtp: verifyOtp, onBack: goBack, onContinue: goToNext })), state.step === 4 && (_jsx(PatientDetailsStep, { state: state, dispatch: dispatch, onBack: goBack, onSubmit: submitAppointment })), state.step === 5 && (_jsx(AppointmentConfirmationStep, { appointment: {
157
+ const breakpoint = useBreakpoint(theme);
158
+ const styles = getStyles(theme, breakpoint);
159
+ return (_jsx("div", { style: styles.container, children: _jsxs("div", { style: styles.card, children: [_jsx("div", { style: styles.header, children: _jsx("h2", { style: styles.title, children: "Book Appointment" }) }), _jsx("hr", {}), _jsxs("div", { style: styles.content, children: [state.loading && _jsx("div", { style: { marginBottom: 12 }, children: "Loading..." }), state.error && _jsx("div", { style: styles.errorMessage, children: state.error }), state.step === 0 && (_jsx(PhoneVerificationStep, { state: state, dispatch: dispatch, onSendOtp: sendOtp, onVerifyOtp: verifyOtp, onBack: () => { }, onContinue: handlePhoneVerificationContinue })), state.step === 1 && (_jsx(BookingOptionStep, { userSessionPacks: state.userSessionPacks || [], availablePackages: state.availablePackages || [], showPackageExplorer: state.showPackageExplorer || false, selectedSessionPack: state.selectedSessionPack, selectedNewPackage: state.selectedNewPackage, onSelectOption: handleBookingOptionSelect, onSelectPackage: handlePackageSelect, onBack: handleGoBack })), state.step === 2 && (_jsx(DoctorSelectModal, { addresses: state.addresses, addressDoctorsMap: state.addressDoctorsMap, selectedAddressId: state.selectedAddress, selectedDoctorId: state.selectedDoctor, onCancel: handleGoBack, onContinue: handleDoctorSelect })), state.step === 3 && (_jsx(AppointmentDateTimeModal, { onlineFee: 500, offlineFee: 300, slots: state.slots, selectedDate: state.selectedDate, selectedSlot: state.selectedSlot, consultationMode: state.consultationMode, onCancel: handleGoBack, onDateChange: handleDateChange, onContinue: handleDateTimeModalContinue, initialStep: "consultation" })), state.step === 4 && (_jsx(PatientSelectionStep, { verifiedPatients: state.verifiedPatients, selectedPatient: state.selectedPatient, onSelectPatient: handleSelectExistingPatient, onProceedAsNewPatient: handleProceedAsNewPatient, onBack: handleGoBack })), state.step === 5 && (_jsx(PatientDetailsStep, { state: state, dispatch: dispatch, onBack: handleGoBack, onSubmit: handlePatientDetailsSubmit })), state.step === 6 && (_jsx(AppointmentSummaryStep, { state: state, selectedDoctor: state.selectedAddress && state.selectedDoctor
160
+ ? state.addressDoctorsMap[state.selectedAddress]?.find((doc) => doc.id === state.selectedDoctor) || null
161
+ : null, selectedAddress: state.selectedAddress
162
+ ? state.addresses.find((addr) => addr.id === state.selectedAddress) || null
163
+ : null, onBack: handleGoBack, onConfirm: handleSummaryConfirm })), state.step === 7 && (_jsx(AppointmentConfirmationStep, { appointment: {
30
164
  patientName: state.patientName,
31
165
  visitationType: state.consultationMode === "ONLINE"
32
166
  ? "Online Consultation"
@@ -49,59 +183,65 @@ export const AppointmentCalender = ({ onError, }) => {
49
183
  ? state.addressDoctorsMap[state.selectedAddress]?.find((doc) => doc.id === state.selectedDoctor) || null
50
184
  : null, selectedAddress: state.selectedAddress
51
185
  ? state.addresses.find((addr) => addr.id === state.selectedAddress) || null
52
- : null, onClose: resetForm })), _jsxs("div", { style: styles.branding, children: [_jsx("span", { style: styles.poweredBy, children: "Powered by" }), _jsx("a", { href: "https://medos.one", target: "_blank", rel: "noopener noreferrer", children: _jsx(MedosLogo, { style: { height: 50, width: "auto" } }) })] })] })] }) }));
186
+ : null, onClose: resetForm, onGoBackToSlots: () => setStep(3) })), _jsxs("div", { style: styles.branding, children: [_jsx("span", { style: styles.poweredBy, children: "Powered by" }), _jsx("a", { href: "https://medos.one", target: "_blank", rel: "noopener noreferrer", children: _jsx(MedosLogo, { style: { height: 50, width: "auto" } }) })] })] })] }) }));
187
+ };
188
+ const getStyles = (theme, breakpoint) => {
189
+ const isMobile = breakpoint === "mobile";
190
+ const isTablet = breakpoint === "tablet";
191
+ return {
192
+ container: {
193
+ display: "flex",
194
+ justifyContent: "center",
195
+ padding: isMobile ? 12 : 20,
196
+ fontFamily: theme.typography.fontFamily,
197
+ background: theme.colors.background,
198
+ },
199
+ card: {
200
+ width: "100%",
201
+ maxWidth: isMobile || isTablet ? "100%" : 840,
202
+ background: theme.colors.surface,
203
+ borderRadius: isMobile ? theme.radii.md : theme.radii.lg,
204
+ boxShadow: isMobile ? theme.shadows.md : theme.shadows.lg,
205
+ overflow: "hidden",
206
+ boxSizing: "border-box",
207
+ },
208
+ header: {
209
+ padding: isMobile ? "16px 16px" : "20px 24px",
210
+ },
211
+ title: {
212
+ margin: 0,
213
+ fontSize: isMobile
214
+ ? theme.typography.fontSizeLg
215
+ : theme.typography.fontSizeXl,
216
+ fontWeight: theme.typography.fontWeightSemibold,
217
+ },
218
+ content: {
219
+ padding: isMobile ? 16 : 24,
220
+ },
221
+ errorMessage: {
222
+ marginBottom: 12,
223
+ color: theme.colors.error,
224
+ fontWeight: 600,
225
+ padding: isMobile ? "10px" : "12px",
226
+ background: theme.colors.errorBackground,
227
+ borderRadius: theme.radii.md,
228
+ border: `1px solid ${theme.colors.errorBorder}`,
229
+ fontSize: theme.typography.fontSizeSm,
230
+ },
231
+ branding: {
232
+ display: "flex",
233
+ alignItems: "center",
234
+ justifyContent: "center",
235
+ gap: 8,
236
+ marginTop: isMobile ? 16 : 24,
237
+ paddingTop: isMobile ? 12 : 16,
238
+ borderTop: `1px solid ${theme.colors.border}`,
239
+ opacity: 0.8,
240
+ },
241
+ poweredBy: {
242
+ fontSize: 12,
243
+ color: theme.colors.textSecondary,
244
+ fontWeight: 500,
245
+ },
246
+ };
53
247
  };
54
- const getStyles = (theme) => ({
55
- container: {
56
- display: "flex",
57
- justifyContent: "center",
58
- padding: 20,
59
- fontFamily: theme.typography.fontFamily,
60
- background: theme.colors.background,
61
- },
62
- card: {
63
- width: "100%",
64
- maxWidth: 840,
65
- background: theme.colors.surface,
66
- borderRadius: theme.radii.lg,
67
- boxShadow: theme.shadows.lg,
68
- overflow: "hidden",
69
- boxSizing: "border-box",
70
- },
71
- header: {
72
- padding: "20px 24px",
73
- },
74
- title: {
75
- margin: 0,
76
- fontSize: theme.typography.fontSizeXl,
77
- fontWeight: theme.typography.fontWeightSemibold,
78
- },
79
- content: {
80
- padding: 24,
81
- },
82
- errorMessage: {
83
- marginBottom: 12,
84
- color: theme.colors.error,
85
- fontWeight: 600,
86
- padding: "12px",
87
- background: theme.colors.errorBackground,
88
- borderRadius: theme.radii.md,
89
- border: `1px solid ${theme.colors.errorBorder}`,
90
- fontSize: theme.typography.fontSizeSm,
91
- },
92
- branding: {
93
- display: "flex",
94
- alignItems: "center",
95
- justifyContent: "center",
96
- gap: 8,
97
- marginTop: 24,
98
- paddingTop: 16,
99
- borderTop: `1px solid ${theme.colors.border}`,
100
- opacity: 0.8,
101
- },
102
- poweredBy: {
103
- fontSize: 12,
104
- color: theme.colors.textSecondary,
105
- fontWeight: 500,
106
- },
107
- });
@@ -1,7 +1,6 @@
1
1
  import { AppointmentState } from "../types";
2
2
  export declare const useAppointmentFlow: (state: AppointmentState, dispatch: React.Dispatch<any>, onError?: (error: Error) => void) => {
3
3
  goBack: () => void;
4
- goToNext: () => void;
5
4
  handleDateChange: (date: Date) => Promise<(() => void) | undefined>;
6
5
  sendOtp: () => Promise<void>;
7
6
  verifyOtp: () => Promise<void>;
@@ -5,22 +5,27 @@ import { validatePhoneNumber, validateCountryCode, } from "../../../components/v
5
5
  import { formatDateToISO, parsePatientName } from "../../../components/utils";
6
6
  export const useAppointmentFlow = (state, dispatch, onError) => {
7
7
  const goBack = useCallback(() => {
8
- if (state.step === 3) {
8
+ if (state.step === 2) {
9
9
  dispatch({ type: "SET_OTP_SENT", payload: false });
10
10
  dispatch({ type: "SET_OTP_CODE", payload: "" });
11
11
  dispatch({ type: "SET_OTP_VERIFIED", payload: false });
12
12
  dispatch({ type: "SET_STEP", payload: 1 });
13
13
  }
14
+ else if (state.step === 3) {
15
+ dispatch({ type: "SET_STEP", payload: 2 });
16
+ }
14
17
  else if (state.step === 4) {
15
- dispatch({ type: "SET_STEP", payload: 3 });
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
+ }
16
24
  }
17
25
  else {
18
26
  dispatch({ type: "SET_STEP", payload: Math.max(0, state.step - 1) });
19
27
  }
20
- }, [state.step, dispatch]);
21
- const goToNext = useCallback(() => {
22
- dispatch({ type: "SET_STEP", payload: Math.min(5, state.step + 1) });
23
- }, [state.step, dispatch]);
28
+ }, [state.step, state.verifiedPatients, dispatch]);
24
29
  const handleDateChange = useCallback(async (date) => {
25
30
  dispatch({ type: "SET_SELECTED_DATE", payload: date });
26
31
  if (!state.workspaceId ||
@@ -120,13 +125,73 @@ export const useAppointmentFlow = (state, dispatch, onError) => {
120
125
  }
121
126
  dispatch({ type: "SET_OTP_VERIFYING", payload: true });
122
127
  try {
123
- await PatientService.verifyPhoneVerificationOtp({
128
+ const response = await PatientService.verifyPhoneVerificationOtp({
124
129
  countryCode: state.countryCode,
125
130
  phoneNumber: state.patientPhone,
126
131
  otpCode: state.otpCode,
127
132
  });
128
133
  dispatch({ type: "SET_OTP_VERIFIED", payload: true });
129
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
+ }
130
195
  }
131
196
  catch (e) {
132
197
  const msg = e.message || "Invalid OTP code";
@@ -156,11 +221,7 @@ export const useAppointmentFlow = (state, dispatch, onError) => {
156
221
  });
157
222
  return;
158
223
  }
159
- if (!state.patientName ||
160
- !state.patientAge ||
161
- !state.patientEmail ||
162
- !state.patientGender ||
163
- !state.bloodGroup) {
224
+ if (!state.patientName || !state.patientAge || !state.patientGender) {
164
225
  dispatch({
165
226
  type: "SET_ERROR",
166
227
  payload: "Please fill in all patient details.",
@@ -182,7 +243,24 @@ export const useAppointmentFlow = (state, dispatch, onError) => {
182
243
  try {
183
244
  const { firstName, lastName } = parsePatientName(state.patientName);
184
245
  const appointmentDate = formatDateToISO(state.selectedDate);
185
- await AppointmentService.createAppointment({
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 = {
186
264
  workspaceId: state.workspaceId,
187
265
  workspaceAddressId: state.selectedAddress,
188
266
  doctorId: state.selectedDoctor,
@@ -193,25 +271,33 @@ export const useAppointmentFlow = (state, dispatch, onError) => {
193
271
  consultationCharge: state.consultationCharge || "0",
194
272
  type: "CONSULTATION",
195
273
  source: "SDK_POWERED_WEBSITE",
196
- patientPayload: {
197
- firstName,
198
- lastName,
199
- email: state.patientEmail,
200
- countryCode: state.countryCode,
201
- phoneNumber: state.patientPhone,
202
- age: parseInt(state.patientAge, 10),
203
- gender: state.patientGender.toUpperCase(),
204
- },
274
+ bookingType: state.bookingType,
275
+ paymentMode: state.paymentMode,
276
+ patientPayload,
205
277
  patientAddress: {
206
278
  addressLine1: state.patientAddress,
279
+ addressLine2: "",
207
280
  city: state.patientCity,
208
281
  state: state.patientState,
209
282
  country: state.patientCountry,
210
283
  zipcode: state.patientZipcode,
211
284
  landmark: state.patientLandmark || undefined,
285
+ countryCode: state.countryCode,
286
+ phoneNumber: state.patientPhone,
287
+ patientId: state.selectedPatient?.id || 0,
212
288
  },
213
- });
214
- dispatch({ type: "SET_STEP", payload: 5 });
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 });
215
301
  }
216
302
  catch (e) {
217
303
  const msg = e.message || "Failed to create appointment";
@@ -224,7 +310,6 @@ export const useAppointmentFlow = (state, dispatch, onError) => {
224
310
  }, [state, dispatch, onError]);
225
311
  return {
226
312
  goBack,
227
- goToNext,
228
313
  handleDateChange,
229
314
  sendOtp,
230
315
  verifyOtp,
@@ -70,6 +70,38 @@ const appointmentReducer = (state, action) => {
70
70
  return { ...state, otpSending: action.payload };
71
71
  case "SET_OTP_VERIFYING":
72
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 };
73
105
  case "RESET_FORM":
74
106
  return INITIAL_STATE;
75
107
  default:
@@ -26,7 +26,6 @@ export const useInitializeAddresses = (dispatch, onError) => {
26
26
  type: "SET_SELECTED_DOCTOR",
27
27
  payload: address.doctors[0].id,
28
28
  });
29
- dispatch({ type: "SET_STEP", payload: 1 });
30
29
  }
31
30
  }
32
31
  }