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
@@ -7,6 +7,7 @@ import { InquiryDetailsStep } from "./InquiryDetailsStep";
7
7
  import { ContactPreferenceStep } from "./ContactPreferenceStep";
8
8
  import { SuccessStep } from "./SuccessStep";
9
9
  import { useTheme } from "../react/hooks/useTheme";
10
+ import { useBreakpoint } from "../core/theme/responsive";
10
11
  import MedosLogo from "./Icons/MedosLogo";
11
12
  const INITIAL_STATE = {
12
13
  step: 0,
@@ -153,76 +154,87 @@ export const EnquiryForm = ({ onSuccess, onError, }) => {
153
154
  }
154
155
  }, [state, validateContactStep, validateInquiryStep]);
155
156
  const theme = useTheme();
156
- const styles = React.useMemo(() => getStyles(theme), [theme]);
157
- return (_jsx("div", { style: styles.container, children: _jsxs("div", { style: styles.card, children: [_jsxs("div", { style: styles.header, children: [_jsx("h2", { style: styles.title, children: "Submit Inquiry" }), _jsxs("p", { style: styles.stepIndicator, children: ["Step ", state.step + 1, " of 4"] })] }), _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(ContactInformationStep, { patientName: state.patientName, patientEmail: state.patientEmail, countryCode: state.countryCode, patientPhone: state.patientPhone, onNameChange: (value) => dispatch({ type: "SET_PATIENT_NAME", payload: value }), onEmailChange: (value) => dispatch({ type: "SET_PATIENT_EMAIL", payload: value }), onCountryCodeChange: (value) => dispatch({ type: "SET_COUNTRY_CODE", payload: value }), onPhoneChange: (value) => dispatch({ type: "SET_PATIENT_PHONE", payload: value }), onNext: goToNext })), state.step === 1 && (_jsx(InquiryDetailsStep, { inquirySubject: state.inquirySubject, inquiryMessage: state.inquiryMessage, onSubjectChange: (value) => dispatch({ type: "SET_INQUIRY_SUBJECT", payload: value }), onMessageChange: (value) => dispatch({ type: "SET_INQUIRY_MESSAGE", payload: value }), onBack: goBack, onNext: goToNext })), state.step === 2 && (_jsx(ContactPreferenceStep, { preferredContactMethod: state.preferredContactMethod, onContactMethodChange: (method) => dispatch({
157
+ const breakpoint = useBreakpoint(theme);
158
+ const styles = React.useMemo(() => getStyles(theme, breakpoint), [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: "Submit Inquiry" }) }), _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(ContactInformationStep, { patientName: state.patientName, patientEmail: state.patientEmail, countryCode: state.countryCode, patientPhone: state.patientPhone, onNameChange: (value) => dispatch({ type: "SET_PATIENT_NAME", payload: value }), onEmailChange: (value) => dispatch({ type: "SET_PATIENT_EMAIL", payload: value }), onCountryCodeChange: (value) => dispatch({ type: "SET_COUNTRY_CODE", payload: value }), onPhoneChange: (value) => dispatch({ type: "SET_PATIENT_PHONE", payload: value }), onNext: goToNext })), state.step === 1 && (_jsx(InquiryDetailsStep, { inquirySubject: state.inquirySubject, inquiryMessage: state.inquiryMessage, onSubjectChange: (value) => dispatch({ type: "SET_INQUIRY_SUBJECT", payload: value }), onMessageChange: (value) => dispatch({ type: "SET_INQUIRY_MESSAGE", payload: value }), onBack: goBack, onNext: goToNext })), state.step === 2 && (_jsx(ContactPreferenceStep, { preferredContactMethod: state.preferredContactMethod, onContactMethodChange: (method) => dispatch({
158
160
  type: "SET_PREFERRED_CONTACT_METHOD",
159
161
  payload: method,
160
162
  }), onBack: goBack, onSubmit: submitEnquiry, isLoading: state.loading })), state.step === 3 && _jsx(SuccessStep, { onReset: 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" } }) })] })] })] }) }));
161
163
  };
162
- const getStyles = (theme) => ({
163
- container: {
164
- display: "flex",
165
- justifyContent: "center",
166
- padding: 20,
167
- fontFamily: theme.typography.fontFamily,
168
- background: theme.colors.background,
169
- },
170
- card: {
171
- width: "100%",
172
- maxWidth: 600,
173
- background: theme.colors.surface,
174
- borderRadius: theme.radii.lg,
175
- boxShadow: theme.shadows.lg,
176
- overflow: "hidden",
177
- boxSizing: "border-box",
178
- },
179
- header: {
180
- background: theme.colors.primary,
181
- padding: "20px 24px",
182
- borderBottom: `1px solid ${theme.colors.border}`,
183
- display: "flex",
184
- justifyContent: "space-between",
185
- alignItems: "center",
186
- },
187
- title: {
188
- margin: 0,
189
- fontSize: theme.typography.fontSizeXl,
190
- fontWeight: theme.typography.fontWeightSemibold,
191
- color: theme.colors.textOnPrimary,
192
- },
193
- stepIndicator: {
194
- fontSize: theme.typography.fontSizeSm,
195
- color: theme.colors.textOnPrimary,
196
- opacity: 0.9,
197
- margin: 0,
198
- fontWeight: 500,
199
- },
200
- content: {
201
- padding: 24,
202
- },
203
- errorMessage: {
204
- marginBottom: 12,
205
- color: theme.colors.error,
206
- fontWeight: 600,
207
- padding: "12px",
208
- background: theme.colors.errorBackground,
209
- borderRadius: theme.radii.md,
210
- border: `1px solid ${theme.colors.errorBorder}`,
211
- fontSize: theme.typography.fontSizeSm,
212
- },
213
- branding: {
214
- display: "flex",
215
- alignItems: "center",
216
- justifyContent: "center",
217
- gap: 8,
218
- marginTop: 24,
219
- paddingTop: 16,
220
- borderTop: `1px solid ${theme.colors.border}`,
221
- opacity: 0.8,
222
- },
223
- poweredBy: {
224
- fontSize: 12,
225
- color: theme.colors.textSecondary,
226
- fontWeight: 500,
227
- },
228
- });
164
+ const getStyles = (theme, breakpoint) => {
165
+ const isMobile = breakpoint === "mobile";
166
+ const isTablet = breakpoint === "tablet";
167
+ return {
168
+ container: {
169
+ display: "flex",
170
+ justifyContent: "center",
171
+ padding: isMobile ? 12 : 20,
172
+ fontFamily: theme.typography.fontFamily,
173
+ background: theme.colors.background,
174
+ },
175
+ card: {
176
+ width: "100%",
177
+ maxWidth: isMobile || isTablet ? "100%" : 600,
178
+ background: theme.colors.surface,
179
+ borderRadius: isMobile ? theme.radii.md : theme.radii.lg,
180
+ boxShadow: isMobile ? theme.shadows.md : theme.shadows.lg,
181
+ overflow: "hidden",
182
+ boxSizing: "border-box",
183
+ },
184
+ header: {
185
+ background: theme.colors.primary,
186
+ padding: isMobile ? "16px 16px" : "20px 24px",
187
+ borderBottom: `1px solid ${theme.colors.border}`,
188
+ display: "flex",
189
+ justifyContent: "space-between",
190
+ alignItems: "center",
191
+ flexWrap: (isMobile ? "wrap" : "nowrap"),
192
+ gap: isMobile ? 8 : 0,
193
+ },
194
+ title: {
195
+ margin: 0,
196
+ fontSize: isMobile
197
+ ? theme.typography.fontSizeLg
198
+ : theme.typography.fontSizeXl,
199
+ fontWeight: theme.typography.fontWeightSemibold,
200
+ color: theme.colors.textOnPrimary,
201
+ },
202
+ stepIndicator: {
203
+ fontSize: isMobile
204
+ ? theme.typography.fontSizeXs
205
+ : theme.typography.fontSizeSm,
206
+ color: theme.colors.textOnPrimary,
207
+ opacity: 0.9,
208
+ margin: 0,
209
+ fontWeight: 500,
210
+ },
211
+ content: {
212
+ padding: isMobile ? 16 : 24,
213
+ },
214
+ errorMessage: {
215
+ marginBottom: 12,
216
+ color: theme.colors.error,
217
+ fontWeight: 600,
218
+ padding: isMobile ? "10px" : "12px",
219
+ background: theme.colors.errorBackground,
220
+ borderRadius: theme.radii.md,
221
+ border: `1px solid ${theme.colors.errorBorder}`,
222
+ fontSize: theme.typography.fontSizeSm,
223
+ },
224
+ branding: {
225
+ display: "flex",
226
+ alignItems: "center",
227
+ justifyContent: "center",
228
+ gap: 8,
229
+ marginTop: isMobile ? 16 : 24,
230
+ paddingTop: isMobile ? 12 : 16,
231
+ borderTop: `1px solid ${theme.colors.border}`,
232
+ opacity: 0.8,
233
+ },
234
+ poweredBy: {
235
+ fontSize: 12,
236
+ color: theme.colors.textSecondary,
237
+ fontWeight: 500,
238
+ },
239
+ };
240
+ };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface CloseIconProps {
3
+ size?: number;
4
+ color?: string;
5
+ className?: string;
6
+ style?: React.CSSProperties;
7
+ }
8
+ export declare const CloseIcon: React.FC<CloseIconProps>;
9
+ export default CloseIcon;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const CloseIcon = ({ size = 12, color = "black", className, style, }) => {
3
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 12 12", fill: "none", className: className, style: style, children: _jsx("path", { d: "M0.878125 11.0896L0 10.2115L4.66667 5.54479L0 0.878126L0.878125 0L5.54479 4.66667L10.2115 0L11.0896 0.878126L6.42292 5.54479L11.0896 10.2115L10.2115 11.0896L5.54479 6.42292L0.878125 11.0896Z", fill: color }) }));
4
+ };
5
+ export default CloseIcon;
@@ -7,10 +7,14 @@ export const InquiryDetailsStep = React.memo(({ inquirySubject, inquiryMessage,
7
7
  const PHONE_VERIFY_STYLES = React.useMemo(() => getPhoneVerifyStyles(theme), [theme]);
8
8
  const BUTTON_STYLES = React.useMemo(() => getButtonStyles(theme), [theme]);
9
9
  const CONTAINER_STYLES = React.useMemo(() => getContainerStyles(theme), [theme]);
10
- return (_jsxs("div", { children: [_jsxs("div", { style: { marginBottom: "16px" }, children: [_jsx("label", { style: PHONE_VERIFY_STYLES.label, children: "Subject" }), _jsx("input", { type: "text", value: inquirySubject, onChange: (e) => onSubjectChange(e.target.value), placeholder: "Enter inquiry subject", style: PHONE_VERIFY_STYLES.phoneInput })] }), _jsxs("div", { style: { marginBottom: "16px" }, children: [_jsx("label", { style: PHONE_VERIFY_STYLES.label, children: "Message" }), _jsx("textarea", { value: inquiryMessage, onChange: (e) => onMessageChange(e.target.value), placeholder: "Enter your inquiry message", rows: 5, style: {
10
+ const styles = getStyles(theme);
11
+ return (_jsxs("div", { children: [_jsxs("div", { style: { marginBottom: "16px" }, children: [_jsxs("label", { style: PHONE_VERIFY_STYLES.label, children: ["Subject", _jsx("span", { style: styles.mandatory, children: "*" })] }), _jsx("input", { type: "text", value: inquirySubject, onChange: (e) => onSubjectChange(e.target.value), placeholder: "Enter inquiry subject", style: PHONE_VERIFY_STYLES.phoneInput })] }), _jsxs("div", { style: { marginBottom: "16px" }, children: [_jsxs("label", { style: PHONE_VERIFY_STYLES.label, children: ["Message", _jsx("span", { style: styles.mandatory, children: "*" })] }), _jsx("textarea", { value: inquiryMessage, onChange: (e) => onMessageChange(e.target.value), placeholder: "Enter your inquiry message", rows: 5, style: {
11
12
  ...PHONE_VERIFY_STYLES.otpInput,
12
13
  minHeight: "120px",
13
14
  resize: "vertical",
14
15
  fontFamily: "inherit",
15
16
  } })] }), _jsxs("div", { style: CONTAINER_STYLES.actions, children: [_jsx("button", { onClick: onBack, style: BUTTON_STYLES.secondary, children: "Back" }), _jsx("button", { onClick: onNext, style: BUTTON_STYLES.primary, children: "Next" })] })] }));
16
17
  });
18
+ const getStyles = (theme) => ({
19
+ mandatory: { color: theme.colors.error, marginLeft: 4 },
20
+ });
@@ -1,33 +1,37 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { GENDER_OPTIONS, BLOOD_GROUP_OPTIONS, } from "./types";
3
3
  import { useTheme } from "../react/hooks/useTheme";
4
+ import { useBreakpoint } from "../core/theme/responsive";
4
5
  import { getButtonStyles, getPatientDetailsStyles, getContainerStyles, } from "./theme-styles";
5
6
  import { UserIcon } from "./Icons/UserIcon";
6
7
  import { MapPinIcon } from "./Icons/MapIcon";
7
8
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from "./uiComponents/SelectDropdown";
8
- export const PatientDetailsStep = ({ state, dispatch, onBack, onSubmit, }) => {
9
+ export const PatientDetailsStep = ({ state, dispatch, onBack, onSubmit, isFirstStep = false, }) => {
9
10
  const theme = useTheme();
10
- const CONTAINER_STYLES = getContainerStyles(theme);
11
- const BUTTON_STYLES = getButtonStyles(theme);
11
+ const breakpoint = useBreakpoint(theme);
12
+ const CONTAINER_STYLES = getContainerStyles(theme, "medos", breakpoint);
13
+ const BUTTON_STYLES = getButtonStyles(theme, "medos", breakpoint);
12
14
  const isFormValid = state.patientName &&
13
15
  state.patientAge &&
14
- state.patientEmail &&
15
16
  state.patientGender &&
16
- state.bloodGroup &&
17
17
  state.patientAddress &&
18
18
  state.patientCity &&
19
19
  state.patientState &&
20
20
  state.patientCountry &&
21
21
  state.patientZipcode &&
22
22
  state.otpVerified;
23
- return (_jsxs("div", { style: CONTAINER_STYLES.section, children: [_jsx(PatientInfoSection, { state: state, dispatch: dispatch }), _jsx(AddressInfoSection, { state: state, dispatch: dispatch }), _jsxs("div", { style: CONTAINER_STYLES.actions, children: [_jsx("button", { style: BUTTON_STYLES.secondary, onClick: onBack, children: "Back" }), _jsx("button", { style: {
23
+ return (_jsxs("div", { style: CONTAINER_STYLES.section, children: [_jsx(PatientInfoSection, { state: state, dispatch: dispatch }), _jsx(AddressInfoSection, { state: state, dispatch: dispatch }), _jsxs("div", { style: {
24
+ ...CONTAINER_STYLES.actions,
25
+ justifyContent: isFirstStep ? "flex-end" : "space-between",
26
+ }, children: [!isFirstStep && (_jsx("button", { style: BUTTON_STYLES.secondary, onClick: onBack, children: "Back" })), _jsx("button", { style: {
24
27
  ...BUTTON_STYLES.primary,
25
28
  opacity: isFormValid ? 1 : 0.6,
26
29
  }, disabled: !isFormValid || state.loading, onClick: onSubmit, children: state.loading ? "Booking..." : "Continue" })] })] }));
27
30
  };
28
31
  const PatientInfoSection = ({ state, dispatch }) => {
29
32
  const theme = useTheme();
30
- const PATIENT_DETAILS_STYLES = getPatientDetailsStyles(theme);
33
+ const breakpoint = useBreakpoint(theme);
34
+ const PATIENT_DETAILS_STYLES = getPatientDetailsStyles(theme, "medos", breakpoint);
31
35
  const firstName = state.patientName.split(" ")[0] || "";
32
36
  const lastName = state.patientName.split(" ").slice(1).join(" ") || "";
33
37
  return (_jsxs("div", { style: PATIENT_DETAILS_STYLES.sectionCard, children: [_jsxs("div", { style: PATIENT_DETAILS_STYLES.sectionHeader, children: [_jsx(UserIcon, {}), _jsx("h3", { style: PATIENT_DETAILS_STYLES.sectionTitle, children: "Patient Information" })] }), _jsxs("div", { style: PATIENT_DETAILS_STYLES.sectionBody, children: [_jsxs("div", { style: PATIENT_DETAILS_STYLES.gridRow, children: [_jsxs("div", { children: [_jsxs("label", { style: PATIENT_DETAILS_STYLES.label, children: ["First Name ", _jsx("span", { style: { color: "#EF4444" }, children: "*" })] }), _jsx("input", { style: PATIENT_DETAILS_STYLES.input, placeholder: "Jane", value: firstName, onChange: (e) => {
@@ -40,7 +44,7 @@ const PatientInfoSection = ({ state, dispatch }) => {
40
44
  type: "SET_PATIENT_NAME",
41
45
  payload: `${firstName} ${e.target.value}`,
42
46
  });
43
- } })] })] }), _jsxs("div", { style: PATIENT_DETAILS_STYLES.gridRow, children: [_jsxs("div", { children: [_jsx("label", { style: PATIENT_DETAILS_STYLES.label, children: "Age" }), _jsx("input", { style: PATIENT_DETAILS_STYLES.input, type: "number", placeholder: "25", value: state.patientAge || "", min: "0", max: "120", onChange: (e) => {
47
+ } })] })] }), _jsxs("div", { style: PATIENT_DETAILS_STYLES.gridRow, children: [_jsxs("div", { children: [_jsxs("label", { style: PATIENT_DETAILS_STYLES.label, children: ["Age ", _jsx("span", { style: { color: "#EF4444" }, children: "*" })] }), _jsx("input", { style: PATIENT_DETAILS_STYLES.input, type: "number", placeholder: "25", value: state.patientAge || "", min: "0", max: "120", onChange: (e) => {
44
48
  const val = e.target.value;
45
49
  if (val === "") {
46
50
  dispatch({
@@ -56,20 +60,21 @@ const PatientInfoSection = ({ state, dispatch }) => {
56
60
  payload: val,
57
61
  });
58
62
  }
59
- } })] }), _jsxs("div", { children: [_jsxs("label", { style: PATIENT_DETAILS_STYLES.label, children: ["Email ", _jsx("span", { style: { color: "#EF4444" }, children: "*" })] }), _jsx("input", { style: PATIENT_DETAILS_STYLES.input, type: "email", placeholder: "jane@example.com", value: state.patientEmail, onChange: (e) => dispatch({
63
+ } })] }), _jsxs("div", { children: [_jsx("label", { style: PATIENT_DETAILS_STYLES.label, children: "Email" }), _jsx("input", { style: PATIENT_DETAILS_STYLES.input, type: "email", placeholder: "jane@example.com (optional)", value: state.patientEmail, onChange: (e) => dispatch({
60
64
  type: "SET_PATIENT_EMAIL",
61
65
  payload: e.target.value,
62
66
  }) })] })] }), _jsxs("div", { style: PATIENT_DETAILS_STYLES.gridRow, children: [_jsxs("div", { children: [_jsxs("label", { style: PATIENT_DETAILS_STYLES.label, children: ["Gender ", _jsx("span", { style: { color: "#EF4444" }, children: "*" })] }), _jsxs(Select, { value: state.patientGender, onValueChange: (value) => dispatch({
63
67
  type: "SET_PATIENT_GENDER",
64
68
  payload: value,
65
- }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Select gender" }) }), _jsx(SelectContent, { children: GENDER_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] }), _jsxs("div", { children: [_jsxs("label", { style: PATIENT_DETAILS_STYLES.label, children: ["Blood Group ", _jsx("span", { style: { color: "#EF4444" }, children: "*" })] }), _jsxs(Select, { value: state.bloodGroup, onValueChange: (value) => dispatch({
69
+ }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Select gender" }) }), _jsx(SelectContent, { children: GENDER_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] }), _jsxs("div", { children: [_jsx("label", { style: PATIENT_DETAILS_STYLES.label, children: "Blood Group" }), _jsxs(Select, { value: state.bloodGroup, onValueChange: (value) => dispatch({
66
70
  type: "SET_BLOOD_GROUP",
67
71
  payload: value,
68
- }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Select blood group" }) }), _jsx(SelectContent, { children: BLOOD_GROUP_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] })] })] })] }));
72
+ }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Select blood group (optional)" }) }), _jsx(SelectContent, { children: BLOOD_GROUP_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] })] })] })] }));
69
73
  };
70
74
  const AddressInfoSection = ({ state, dispatch }) => {
71
75
  const theme = useTheme();
72
- const PATIENT_DETAILS_STYLES = getPatientDetailsStyles(theme);
76
+ const breakpoint = useBreakpoint(theme);
77
+ const PATIENT_DETAILS_STYLES = getPatientDetailsStyles(theme, "medos", breakpoint);
73
78
  return (_jsxs("div", { style: PATIENT_DETAILS_STYLES.sectionCard, children: [_jsxs("div", { style: PATIENT_DETAILS_STYLES.sectionHeader, children: [_jsx(MapPinIcon, {}), _jsx("h3", { style: PATIENT_DETAILS_STYLES.sectionTitle, children: "Address Information" })] }), _jsxs("div", { style: PATIENT_DETAILS_STYLES.sectionBody, children: [_jsxs("div", { style: { marginBottom: 20 }, children: [_jsxs("label", { style: PATIENT_DETAILS_STYLES.label, children: ["Address ", _jsx("span", { style: { color: "#EF4444" }, children: "*" })] }), _jsx("input", { style: PATIENT_DETAILS_STYLES.input, placeholder: "123 Main Street", value: state.patientAddress, onChange: (e) => dispatch({
74
79
  type: "SET_PATIENT_ADDRESS",
75
80
  payload: e.target.value,
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { Patient } from "./appointment-booking/types";
3
+ interface PatientSelectionStepProps {
4
+ verifiedPatients: Patient[];
5
+ selectedPatient: Patient | null;
6
+ onSelectPatient: (patient: Patient) => void;
7
+ onProceedAsNewPatient: () => void;
8
+ onBack: () => void;
9
+ isFirstStep?: boolean;
10
+ }
11
+ export declare const PatientSelectionStep: React.FC<PatientSelectionStepProps>;
12
+ export {};
@@ -0,0 +1,254 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { useTheme } from "../react/hooks/useTheme";
4
+ import { getButtonStyles } from "./theme-styles";
5
+ export const PatientSelectionStep = ({ verifiedPatients, selectedPatient, onSelectPatient, onProceedAsNewPatient, onBack, isFirstStep = false, }) => {
6
+ const theme = useTheme();
7
+ const BUTTON_STYLES = getButtonStyles(theme);
8
+ const styles = getPatientSelectionStyles(theme);
9
+ const [tempSelection, setTempSelection] = React.useState(null);
10
+ const handlePatientSelect = (patient) => {
11
+ setTempSelection({ type: "existing", patient });
12
+ };
13
+ const handleNewPatientSelect = () => {
14
+ setTempSelection({ type: "new" });
15
+ };
16
+ const handleNext = () => {
17
+ if (tempSelection) {
18
+ if (tempSelection.type === "existing" && tempSelection.patient) {
19
+ onSelectPatient(tempSelection.patient);
20
+ }
21
+ else if (tempSelection.type === "new") {
22
+ onProceedAsNewPatient();
23
+ }
24
+ }
25
+ };
26
+ return (_jsxs("div", { style: styles.container, children: [_jsxs("div", { style: styles.header, children: [_jsx("h3", { style: styles.title, children: "Select Patient" }), verifiedPatients.length > 0 ? (_jsxs("p", { style: styles.subtitle, children: ["We found ", verifiedPatients.length, " registered patient", verifiedPatients.length > 1 ? "s" : "", " with this number"] })) : (_jsx("p", { style: styles.subtitle, children: "No registered patients found with this number" }))] }), _jsxs("div", { style: styles.content, children: [verifiedPatients.length > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { style: styles.patientList, children: verifiedPatients.map((patient) => (_jsx(PatientCard, { patient: patient, isSelected: tempSelection?.type === "existing" &&
27
+ tempSelection?.patient?.id === patient.id, onSelect: () => handlePatientSelect(patient), theme: theme }, patient.id))) }), _jsx("div", { style: styles.divider, children: _jsx("span", { style: styles.dividerText, children: "OR" }) })] })), _jsxs("button", { style: {
28
+ ...styles.newPatientButton,
29
+ ...(tempSelection?.type === "new"
30
+ ? styles.newPatientButtonSelected
31
+ : {}),
32
+ }, onClick: handleNewPatientSelect, children: [_jsx("div", { style: styles.newPatientIcon, children: "+" }), _jsxs("div", { style: styles.newPatientContent, children: [_jsx("div", { style: styles.newPatientTitle, children: "Register as New Patient" }), _jsx("div", { style: styles.newPatientSubtitle, children: "Fill out the form to create a new patient profile" })] })] })] }), _jsxs("div", { style: {
33
+ ...styles.footer,
34
+ justifyContent: "flex-end",
35
+ }, children: [!isFirstStep && (_jsx("button", { style: BUTTON_STYLES.secondary, onClick: onBack, children: "Back" })), _jsx("button", { style: {
36
+ ...BUTTON_STYLES.primary,
37
+ opacity: tempSelection ? 1 : 0.6,
38
+ }, onClick: handleNext, disabled: !tempSelection, children: "Next" })] })] }));
39
+ };
40
+ const PatientCard = ({ patient, isSelected, onSelect, theme }) => {
41
+ const styles = getPatientCardStyles(theme, isSelected);
42
+ const formatDate = (dateStr) => {
43
+ const date = new Date(dateStr);
44
+ return date.toLocaleDateString("en-US", {
45
+ year: "numeric",
46
+ month: "short",
47
+ day: "numeric",
48
+ });
49
+ };
50
+ return (_jsxs("button", { style: styles.card, onClick: onSelect, type: "button", children: [_jsx("div", { style: styles.radioContainer, children: _jsx("div", { style: styles.radio, children: isSelected && _jsx("div", { style: styles.radioInner }) }) }), _jsxs("div", { style: styles.content, children: [_jsxs("div", { style: styles.header, children: [_jsxs("div", { style: styles.name, children: [patient.firstName, " ", patient.lastName] }), _jsxs("div", { style: styles.mrn, children: ["MRN: ", patient.mrn] })] }), _jsxs("div", { style: styles.details, children: [_jsxs("div", { style: styles.detailRow, children: [_jsx("span", { style: styles.detailLabel, children: "Email:" }), _jsx("span", { style: styles.detailValue, children: patient.email })] }), _jsxs("div", { style: styles.detailRow, children: [_jsx("span", { style: styles.detailLabel, children: "Phone:" }), _jsxs("span", { style: styles.detailValue, children: [patient.countryCode, " ", patient.phoneNumber] })] }), _jsxs("div", { style: styles.detailRow, children: [_jsx("span", { style: styles.detailLabel, children: "DOB:" }), _jsx("span", { style: styles.detailValue, children: formatDate(patient.dob) })] }), _jsxs("div", { style: styles.detailRow, children: [_jsx("span", { style: styles.detailLabel, children: "Gender:" }), _jsx("span", { style: styles.detailValue, children: patient.gender })] }), _jsxs("div", { style: styles.detailRow, children: [_jsx("span", { style: styles.detailLabel, children: "Blood Group:" }), _jsx("span", { style: styles.detailValue, children: patient.bloodGroup })] }), patient.address && (_jsxs("div", { style: styles.detailRow, children: [_jsx("span", { style: styles.detailLabel, children: "Address:" }), _jsxs("span", { style: styles.detailValue, children: [patient.address.city, ", ", patient.address.state] })] }))] })] })] }));
51
+ };
52
+ const getPatientSelectionStyles = (theme) => ({
53
+ container: {
54
+ display: "flex",
55
+ flexDirection: "column",
56
+ height: "100%",
57
+ gap: "20px",
58
+ },
59
+ header: {
60
+ textAlign: "center",
61
+ marginBottom: "4px",
62
+ },
63
+ title: {
64
+ fontSize: "24px",
65
+ fontWeight: "600",
66
+ color: theme.colors.text,
67
+ marginBottom: "8px",
68
+ },
69
+ subtitle: {
70
+ fontSize: "14px",
71
+ color: theme.colors.textSecondary,
72
+ margin: 0,
73
+ },
74
+ content: {
75
+ flex: 1,
76
+ overflowY: "auto",
77
+ display: "flex",
78
+ flexDirection: "column",
79
+ gap: "20px",
80
+ },
81
+ patientList: {
82
+ display: "flex",
83
+ flexDirection: "column",
84
+ gap: "12px",
85
+ },
86
+ divider: {
87
+ display: "flex",
88
+ alignItems: "center",
89
+ textAlign: "center",
90
+ margin: "16px 0",
91
+ position: "relative",
92
+ "&::before": {
93
+ content: '""',
94
+ flex: 1,
95
+ borderBottom: `1px solid ${theme.colors.border}`,
96
+ },
97
+ "&::after": {
98
+ content: '""',
99
+ flex: 1,
100
+ borderBottom: `1px solid ${theme.colors.border}`,
101
+ },
102
+ },
103
+ dividerText: {
104
+ padding: "0 16px",
105
+ color: theme.colors.textSecondary,
106
+ fontSize: "14px",
107
+ fontWeight: "500",
108
+ backgroundColor: theme.colors.background,
109
+ },
110
+ newPatientButton: {
111
+ display: "flex",
112
+ alignItems: "center",
113
+ justifyContent: "center",
114
+ gap: "16px",
115
+ padding: "14px",
116
+ border: `2px dashed ${theme.colors.border}`,
117
+ borderRadius: theme.radii.md,
118
+ background: theme.colors.background,
119
+ cursor: "pointer",
120
+ transition: "all 0.2s ease",
121
+ textAlign: "center",
122
+ "&:hover": {
123
+ borderColor: theme.colors.primary,
124
+ background: `${theme.colors.primary}10`,
125
+ },
126
+ },
127
+ newPatientIcon: {
128
+ width: "48px",
129
+ height: "48px",
130
+ borderRadius: "50%",
131
+ background: theme.colors.primary,
132
+ color: "white",
133
+ display: "flex",
134
+ alignItems: "center",
135
+ justifyContent: "center",
136
+ fontSize: "24px",
137
+ fontWeight: "400",
138
+ flexShrink: 0,
139
+ lineHeight: "1",
140
+ },
141
+ newPatientContent: {
142
+ display: "flex",
143
+ flexDirection: "column",
144
+ alignItems: "center",
145
+ justifyContent: "center",
146
+ textAlign: "center",
147
+ },
148
+ newPatientTitle: {
149
+ fontSize: "16px",
150
+ fontWeight: "600",
151
+ color: theme.colors.text,
152
+ marginBottom: "4px",
153
+ textAlign: "center",
154
+ },
155
+ newPatientSubtitle: {
156
+ fontSize: "14px",
157
+ color: theme.colors.textSecondary,
158
+ textAlign: "center",
159
+ },
160
+ newPatientButtonSelected: {
161
+ borderColor: theme.colors.primary,
162
+ background: `${theme.colors.primary}08`,
163
+ },
164
+ footer: {
165
+ display: "flex",
166
+ justifyContent: "space-between",
167
+ gap: "12px",
168
+ paddingTop: "16px",
169
+ borderTop: `1px solid ${theme.colors.border}`,
170
+ },
171
+ nextBtnDisabled: {
172
+ backgroundColor: theme.colors.textSecondary || "#9ca3af",
173
+ cursor: "not-allowed",
174
+ opacity: 0.6,
175
+ color: "white",
176
+ },
177
+ });
178
+ const getPatientCardStyles = (theme, isSelected) => ({
179
+ card: {
180
+ display: "flex",
181
+ gap: "16px",
182
+ padding: "16px",
183
+ border: `2px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
184
+ borderRadius: theme.radii.md,
185
+ background: isSelected
186
+ ? `${theme.colors.primary}08`
187
+ : theme.colors.background,
188
+ cursor: "pointer",
189
+ transition: "all 0.2s ease",
190
+ "&:hover": {
191
+ borderColor: theme.colors.primary,
192
+ background: `${theme.colors.primary}05`,
193
+ },
194
+ },
195
+ radioContainer: {
196
+ paddingTop: "2px",
197
+ },
198
+ radio: {
199
+ width: "20px",
200
+ height: "20px",
201
+ borderRadius: "50%",
202
+ border: `2px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
203
+ display: "flex",
204
+ alignItems: "center",
205
+ justifyContent: "center",
206
+ transition: "all 0.2s ease",
207
+ },
208
+ radioInner: {
209
+ width: "10px",
210
+ height: "10px",
211
+ borderRadius: "50%",
212
+ background: theme.colors.primary,
213
+ },
214
+ content: {
215
+ flex: 1,
216
+ },
217
+ header: {
218
+ display: "flex",
219
+ justifyContent: "space-between",
220
+ alignItems: "center",
221
+ marginBottom: "12px",
222
+ },
223
+ name: {
224
+ fontSize: "18px",
225
+ fontWeight: "600",
226
+ color: theme.colors.text,
227
+ },
228
+ mrn: {
229
+ fontSize: "13px",
230
+ color: theme.colors.textSecondary,
231
+ fontWeight: "500",
232
+ padding: "4px 8px",
233
+ background: theme.colors.border,
234
+ borderRadius: theme.radii.sm,
235
+ },
236
+ details: {
237
+ display: "flex",
238
+ flexDirection: "column",
239
+ gap: "6px",
240
+ },
241
+ detailRow: {
242
+ display: "flex",
243
+ fontSize: "14px",
244
+ gap: "8px",
245
+ },
246
+ detailLabel: {
247
+ color: theme.colors.textSecondary,
248
+ fontWeight: "500",
249
+ minWidth: "100px",
250
+ },
251
+ detailValue: {
252
+ color: theme.colors.text,
253
+ },
254
+ });
@@ -21,7 +21,7 @@ export const PhoneVerificationStep = ({ state, dispatch, onSendOtp, onVerifyOtp,
21
21
  }, children: "Change Number" }), _jsx("button", { style: {
22
22
  ...BUTTON_STYLES.primary,
23
23
  opacity: state.otpCode.length === 6 ? 1 : 0.6,
24
- }, disabled: state.otpCode.length !== 6 || state.otpVerifying, onClick: onVerifyOtp, children: state.otpVerifying ? "Verifying..." : "Verify OTP" })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { style: BUTTON_STYLES.secondary, onClick: onBack, children: "Back" }), _jsx("button", { style: BUTTON_STYLES.primary, onClick: onContinue, children: "Continue to Details" })] })) })] }));
24
+ }, disabled: state.otpCode.length !== 6 || state.otpVerifying, onClick: onVerifyOtp, children: state.otpVerifying ? "Verifying..." : "Verify OTP" })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { style: BUTTON_STYLES.secondary, onClick: onBack, children: "Back" }), _jsx("button", { style: BUTTON_STYLES.primary, onClick: onContinue, children: "Continue" })] })) })] }));
25
25
  };
26
26
  const PhoneInputSection = ({ countryCode, patientPhone, onCountryCodeChange, onPhoneChange }) => {
27
27
  const theme = useTheme();
@@ -5,5 +5,5 @@ export const SuccessStep = ({ onReset }) => {
5
5
  const theme = useTheme();
6
6
  const SUCCESS_STYLES = getSuccessStyles(theme);
7
7
  const BUTTON_STYLES = getButtonStyles(theme);
8
- return (_jsxs("div", { style: SUCCESS_STYLES.container, children: [_jsx("div", { style: SUCCESS_STYLES.iconContainer, children: _jsx("div", { style: { fontSize: "48px", color: theme.colors.success }, children: "\u2713" }) }), _jsxs("div", { style: SUCCESS_STYLES.detailsContainer, children: [_jsx("h3", { style: SUCCESS_STYLES.detailsTitle, children: "Inquiry Submitted Successfully" }), _jsx("p", { style: SUCCESS_STYLES.confirmationNote, children: "Thank you for your inquiry. We will get back to you soon." })] }), _jsx("div", { style: { ...SUCCESS_STYLES.actionContainer, textAlign: "center" }, children: _jsx("button", { onClick: onReset, style: BUTTON_STYLES.primary, children: "Submit Another Inquiry" }) })] }));
8
+ return (_jsxs("div", { style: SUCCESS_STYLES.container, children: [_jsx("div", { style: SUCCESS_STYLES.iconContainer, children: _jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: theme.colors.success, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "20 6 9 17 4 12" }) }) }), _jsxs("div", { style: SUCCESS_STYLES.detailsContainer, children: [_jsx("h3", { style: SUCCESS_STYLES.detailsTitle, children: "Inquiry Submitted Successfully" }), _jsx("p", { style: SUCCESS_STYLES.confirmationNote, children: "Thank you for your inquiry. We will get back to you soon." })] }), _jsx("div", { style: SUCCESS_STYLES.actionContainer, children: _jsx("button", { onClick: onReset, style: BUTTON_STYLES.primary, children: "Submit Another Inquiry" }) })] }));
9
9
  };