medos-sdk 1.1.9 → 1.1.10

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 (52) hide show
  1. package/dist/components/AppointmentCalender.js +44 -27
  2. package/dist/components/AppointmentConfirmationStep.d.ts +3 -0
  3. package/dist/components/AppointmentConfirmationStep.js +26 -20
  4. package/dist/components/AppointmentDateTimeModal.d.ts +3 -0
  5. package/dist/components/AppointmentDateTimeModal.js +24 -6
  6. package/dist/components/ContactInformationStep.js +6 -5
  7. package/dist/components/ContactPreferenceStep.js +6 -5
  8. package/dist/components/DoctorSelectModal.d.ts +5 -0
  9. package/dist/components/DoctorSelectModal.js +65 -16
  10. package/dist/components/EnquiryForm.js +4 -4
  11. package/dist/components/InquiryDetailsStep.js +7 -6
  12. package/dist/components/appointment-booking/AppointmentCalender.d.ts +5 -0
  13. package/dist/components/appointment-booking/AppointmentCalender.js +107 -0
  14. package/dist/components/appointment-booking/hooks/index.d.ts +3 -0
  15. package/dist/components/appointment-booking/hooks/index.js +3 -0
  16. package/dist/components/appointment-booking/hooks/useAppointmentFlow.d.ts +9 -0
  17. package/dist/components/appointment-booking/hooks/useAppointmentFlow.js +233 -0
  18. package/dist/components/appointment-booking/hooks/useAppointmentState.d.ts +9 -0
  19. package/dist/components/appointment-booking/hooks/useAppointmentState.js +93 -0
  20. package/dist/components/appointment-booking/hooks/useInitializeAddresses.d.ts +1 -0
  21. package/dist/components/appointment-booking/hooks/useInitializeAddresses.js +56 -0
  22. package/dist/components/appointment-booking/index.d.ts +5 -0
  23. package/dist/components/appointment-booking/index.js +3 -0
  24. package/dist/components/appointment-booking/types.d.ts +128 -0
  25. package/dist/components/appointment-booking/types.js +33 -0
  26. package/dist/components/types.d.ts +10 -139
  27. package/dist/components/types.js +1 -33
  28. package/dist/components/uiComponents/SelectDropdown.d.ts +1 -1
  29. package/dist/components/uiComponents/SelectDropdown.js +24 -24
  30. package/dist/enquiry-form/validation.js +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/react/index.d.ts +2 -1
  34. package/dist/react/index.js +1 -1
  35. package/dist/vanilla/AppointmentCalendarWidget.js +20 -13
  36. package/dist/vanilla/components/AppointmentConfirmationStep.d.ts +3 -0
  37. package/dist/vanilla/components/AppointmentDateTimeModal.d.ts +3 -0
  38. package/dist/vanilla/components/DoctorSelectModal.d.ts +5 -0
  39. package/dist/vanilla/components/appointment-booking/AppointmentCalender.d.ts +5 -0
  40. package/dist/vanilla/components/appointment-booking/hooks/index.d.ts +3 -0
  41. package/dist/vanilla/components/appointment-booking/hooks/useAppointmentFlow.d.ts +9 -0
  42. package/dist/vanilla/components/appointment-booking/hooks/useAppointmentState.d.ts +9 -0
  43. package/dist/vanilla/components/appointment-booking/hooks/useInitializeAddresses.d.ts +1 -0
  44. package/dist/vanilla/components/appointment-booking/index.d.ts +5 -0
  45. package/dist/vanilla/components/appointment-booking/types.d.ts +128 -0
  46. package/dist/vanilla/components/types.d.ts +10 -139
  47. package/dist/vanilla/components/uiComponents/SelectDropdown.d.ts +1 -1
  48. package/dist/vanilla/enquiry-widget.js +1 -1
  49. package/dist/vanilla/index.d.ts +1 -1
  50. package/dist/vanilla/react/index.d.ts +2 -1
  51. package/dist/vanilla/widget.js +44 -36
  52. package/package.json +1 -1
@@ -0,0 +1,33 @@
1
+ export const INITIAL_STATE = {
2
+ step: 0,
3
+ loading: false,
4
+ error: null,
5
+ workspaceId: null,
6
+ addresses: [],
7
+ addressDoctorsMap: {},
8
+ selectedAddress: null,
9
+ selectedDoctor: null,
10
+ selectedDate: new Date(),
11
+ slots: [],
12
+ selectedSlot: null,
13
+ consultationMode: "OFFLINE",
14
+ consultationCharge: "",
15
+ patientName: "",
16
+ patientAge: "",
17
+ patientEmail: "",
18
+ patientGender: "",
19
+ bloodGroup: "",
20
+ patientAddress: "",
21
+ patientCity: "",
22
+ patientState: "",
23
+ patientCountry: "",
24
+ patientZipcode: "",
25
+ patientLandmark: "",
26
+ countryCode: "+91",
27
+ patientPhone: "",
28
+ otpCode: "",
29
+ otpSent: false,
30
+ otpVerified: false,
31
+ otpSending: false,
32
+ otpVerifying: false,
33
+ };
@@ -1,18 +1,16 @@
1
- import { Doctor, Slot, AddressItem } from "../services/AppointmentService";
2
- export type AppointmentCalenderProps = {
3
- onError?: (err: Error) => void;
4
- };
1
+ export type { AppointmentState, AppointmentAction, } from "./appointment-booking/types";
2
+ export { INITIAL_STATE } from "./appointment-booking/types";
5
3
  export type PhoneVerificationStepProps = {
6
- state: AppointmentState;
7
- dispatch: React.Dispatch<AppointmentAction>;
4
+ state: any;
5
+ dispatch: React.Dispatch<any>;
8
6
  onSendOtp: () => Promise<void>;
9
7
  onVerifyOtp: () => Promise<void>;
10
8
  onBack: () => void;
11
9
  onContinue: () => void;
12
10
  };
13
11
  export type PatientDetailsStepProps = {
14
- state: AppointmentState;
15
- dispatch: React.Dispatch<AppointmentAction>;
12
+ state: any;
13
+ dispatch: React.Dispatch<any>;
16
14
  onBack: () => void;
17
15
  onSubmit: () => Promise<void>;
18
16
  };
@@ -33,138 +31,12 @@ export type OtpInputSectionProps = {
33
31
  onOtpChange: (code: string) => void;
34
32
  };
35
33
  export type PatientInfoSectionProps = {
36
- state: AppointmentState;
37
- dispatch: React.Dispatch<AppointmentAction>;
34
+ state: any;
35
+ dispatch: React.Dispatch<any>;
38
36
  };
39
37
  export type AddressInfoSectionProps = {
40
- state: AppointmentState;
41
- dispatch: React.Dispatch<AppointmentAction>;
42
- };
43
- export interface AppointmentState {
44
- step: number;
45
- loading: boolean;
46
- error: string | null;
47
- workspaceId: number | null;
48
- addresses: AddressItem[];
49
- addressDoctorsMap: Record<number, Doctor[]>;
50
- selectedAddress: number | null;
51
- selectedDoctor: number | null;
52
- selectedDate: Date;
53
- slots: Slot[];
54
- selectedSlot: Slot | null;
55
- consultationMode: "ONLINE" | "OFFLINE";
56
- consultationCharge: string;
57
- patientName: string;
58
- patientAge: string;
59
- patientEmail: string;
60
- patientGender: string;
61
- bloodGroup: string;
62
- patientAddress: string;
63
- patientCity: string;
64
- patientState: string;
65
- patientCountry: string;
66
- patientZipcode: string;
67
- patientLandmark: string;
68
- countryCode: string;
69
- patientPhone: string;
70
- otpCode: string;
71
- otpSent: boolean;
72
- otpVerified: boolean;
73
- otpSending: boolean;
74
- otpVerifying: boolean;
75
- }
76
- export type AppointmentAction = {
77
- type: "SET_STEP";
78
- payload: number;
79
- } | {
80
- type: "SET_LOADING";
81
- payload: boolean;
82
- } | {
83
- type: "SET_ERROR";
84
- payload: string | null;
85
- } | {
86
- type: "SET_WORKSPACE";
87
- payload: {
88
- id: number;
89
- addresses: AddressItem[];
90
- };
91
- } | {
92
- type: "SET_SELECTED_ADDRESS";
93
- payload: number | null;
94
- } | {
95
- type: "SET_SELECTED_DOCTOR";
96
- payload: number | null;
97
- } | {
98
- type: "SET_SELECTED_DATE";
99
- payload: Date;
100
- } | {
101
- type: "SET_SLOTS";
102
- payload: Slot[];
103
- } | {
104
- type: "SET_SELECTED_SLOT";
105
- payload: Slot | null;
106
- } | {
107
- type: "SET_CONSULTATION_MODE";
108
- payload: "ONLINE" | "OFFLINE";
109
- } | {
110
- type: "SET_CONSULTATION_CHARGE";
111
- payload: string;
112
- } | {
113
- type: "SET_PATIENT_NAME";
114
- payload: string;
115
- } | {
116
- type: "SET_PATIENT_AGE";
117
- payload: string;
118
- } | {
119
- type: "SET_PATIENT_EMAIL";
120
- payload: string;
121
- } | {
122
- type: "SET_PATIENT_GENDER";
123
- payload: string;
124
- } | {
125
- type: "SET_BLOOD_GROUP";
126
- payload: string;
127
- } | {
128
- type: "SET_PATIENT_ADDRESS";
129
- payload: string;
130
- } | {
131
- type: "SET_PATIENT_CITY";
132
- payload: string;
133
- } | {
134
- type: "SET_PATIENT_STATE";
135
- payload: string;
136
- } | {
137
- type: "SET_PATIENT_COUNTRY";
138
- payload: string;
139
- } | {
140
- type: "SET_PATIENT_ZIPCODE";
141
- payload: string;
142
- } | {
143
- type: "SET_PATIENT_LANDMARK";
144
- payload: string;
145
- } | {
146
- type: "SET_COUNTRY_CODE";
147
- payload: string;
148
- } | {
149
- type: "SET_PATIENT_PHONE";
150
- payload: string;
151
- } | {
152
- type: "SET_OTP_CODE";
153
- payload: string;
154
- } | {
155
- type: "SET_OTP_SENT";
156
- payload: boolean;
157
- } | {
158
- type: "SET_OTP_VERIFIED";
159
- payload: boolean;
160
- } | {
161
- type: "SET_OTP_SENDING";
162
- payload: boolean;
163
- } | {
164
- type: "SET_OTP_VERIFYING";
165
- payload: boolean;
166
- } | {
167
- type: "RESET_FORM";
38
+ state: any;
39
+ dispatch: React.Dispatch<any>;
168
40
  };
169
41
  export declare const COUNTRY_CODES: {
170
42
  code: string;
@@ -178,4 +50,3 @@ export declare const BLOOD_GROUP_OPTIONS: {
178
50
  value: string;
179
51
  label: string;
180
52
  }[];
181
- export declare const INITIAL_STATE: AppointmentState;
@@ -1,3 +1,4 @@
1
+ export { INITIAL_STATE } from "./appointment-booking/types";
1
2
  export const COUNTRY_CODES = [
2
3
  { code: "+91", label: "🇮🇳 +91" },
3
4
  { code: "+1", label: "🇺🇸 +1" },
@@ -20,36 +21,3 @@ export const BLOOD_GROUP_OPTIONS = [
20
21
  { value: "O+", label: "O+" },
21
22
  { value: "O-", label: "O-" },
22
23
  ];
23
- export const INITIAL_STATE = {
24
- step: 0,
25
- loading: false,
26
- error: null,
27
- workspaceId: null,
28
- addresses: [],
29
- addressDoctorsMap: {},
30
- selectedAddress: null,
31
- selectedDoctor: null,
32
- selectedDate: new Date(),
33
- slots: [],
34
- selectedSlot: null,
35
- consultationMode: "OFFLINE",
36
- consultationCharge: "",
37
- patientName: "",
38
- patientAge: "",
39
- patientEmail: "",
40
- patientGender: "",
41
- bloodGroup: "",
42
- patientAddress: "",
43
- patientCity: "",
44
- patientState: "",
45
- patientCountry: "",
46
- patientZipcode: "",
47
- patientLandmark: "",
48
- countryCode: "+91",
49
- patientPhone: "",
50
- otpCode: "",
51
- otpSent: false,
52
- otpVerified: false,
53
- otpSending: false,
54
- otpVerifying: false,
55
- };
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import * as React from "react";
2
2
  interface SelectProps {
3
3
  children: React.ReactNode;
4
4
  value?: string;
@@ -1,14 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import * as React from 'react';
3
- import { ChevronDownIcon } from '../Icons/ChevronDownIcon';
4
- import { Check } from '../Icons/Check';
2
+ import * as React from "react";
3
+ import { ChevronDownIcon } from "../Icons/ChevronDownIcon";
4
+ import { Check } from "../Icons/Check";
5
5
  const cn = (...classes) => {
6
- return classes.filter(Boolean).join(' ');
6
+ return classes.filter(Boolean).join(" ");
7
7
  };
8
- if (typeof document !== 'undefined') {
9
- const styleId = 'custom-select-styles';
8
+ if (typeof document !== "undefined") {
9
+ const styleId = "custom-select-styles";
10
10
  if (!document.getElementById(styleId)) {
11
- const styleElement = document.createElement('style');
11
+ const styleElement = document.createElement("style");
12
12
  styleElement.id = styleId;
13
13
  styleElement.innerHTML = `
14
14
  /* Container */
@@ -226,14 +226,14 @@ const SelectContext = React.createContext(undefined);
226
226
  const useSelectContext = () => {
227
227
  const context = React.useContext(SelectContext);
228
228
  if (!context) {
229
- throw new Error('Select components must be used within a Select');
229
+ throw new Error("Select components must be used within a Select");
230
230
  }
231
231
  return context;
232
232
  };
233
- const Select = ({ children, value, onValueChange, defaultValue, disabled = false }) => {
233
+ const Select = ({ children, value, onValueChange, defaultValue, disabled = false, }) => {
234
234
  const [isOpen, setIsOpen] = React.useState(false);
235
- const [selectedValue, setSelectedValue] = React.useState(value || defaultValue || '');
236
- const [selectedLabel, setSelectedLabel] = React.useState('');
235
+ const [selectedValue, setSelectedValue] = React.useState(value || defaultValue || "");
236
+ const [selectedLabel, setSelectedLabel] = React.useState("");
237
237
  const triggerRef = React.useRef(null);
238
238
  const contentRef = React.useRef(null);
239
239
  React.useEffect(() => {
@@ -251,8 +251,8 @@ const Select = ({ children, value, onValueChange, defaultValue, disabled = false
251
251
  }
252
252
  };
253
253
  if (isOpen) {
254
- document.addEventListener('mousedown', handleClickOutside);
255
- return () => document.removeEventListener('mousedown', handleClickOutside);
254
+ document.addEventListener("mousedown", handleClickOutside);
255
+ return () => document.removeEventListener("mousedown", handleClickOutside);
256
256
  }
257
257
  }, [isOpen]);
258
258
  const handleSelect = (value, label) => {
@@ -276,27 +276,27 @@ const Select = ({ children, value, onValueChange, defaultValue, disabled = false
276
276
  };
277
277
  const SelectTrigger = React.forwardRef(({ children, className, error = false, ...props }, ref) => {
278
278
  const { isOpen, setIsOpen, triggerRef, disabled } = useSelectContext();
279
- return (_jsxs("button", { ref: triggerRef, type: "button", className: cn('select-trigger', error && 'select-trigger-error', className), onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox", ...props, children: [children, _jsx(ChevronDownIcon, { className: cn('select-icon', error && 'select-icon-error') })] }));
279
+ return (_jsxs("button", { ref: triggerRef, type: "button", className: cn("select-trigger", error && "select-trigger-error", className), onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox", ...props, children: [children, _jsx(ChevronDownIcon, { className: cn("select-icon", error && "select-icon-error") })] }));
280
280
  });
281
- SelectTrigger.displayName = 'SelectTrigger';
282
- const SelectValue = ({ placeholder = 'Select...' }) => {
281
+ SelectTrigger.displayName = "SelectTrigger";
282
+ const SelectValue = ({ placeholder = "Select...", }) => {
283
283
  const { selectedLabel, selectedValue } = useSelectContext();
284
- return (_jsx("span", { className: cn('select-value', !selectedValue && 'select-placeholder'), children: selectedLabel || placeholder }));
284
+ return (_jsx("span", { className: cn("select-value", !selectedValue && "select-placeholder"), children: selectedLabel || placeholder }));
285
285
  };
286
286
  const SelectContent = React.forwardRef(({ children, className, ...props }, ref) => {
287
287
  const { isOpen, contentRef } = useSelectContext();
288
288
  if (!isOpen)
289
289
  return null;
290
- return (_jsx("div", { ref: contentRef, className: cn('select-content', className), role: "listbox", ...props, children: _jsx("div", { className: "select-viewport", children: children }) }));
290
+ return (_jsx("div", { ref: contentRef, className: cn("select-content", className), role: "listbox", ...props, children: _jsx("div", { className: "select-viewport", children: children }) }));
291
291
  });
292
- SelectContent.displayName = 'SelectContent';
292
+ SelectContent.displayName = "SelectContent";
293
293
  const SelectItem = React.forwardRef(({ children, value, className, disabled = false, ...props }, ref) => {
294
294
  const { selectedValue, handleSelect } = useSelectContext();
295
295
  const isSelected = selectedValue === value;
296
- return (_jsxs("div", { ref: ref, className: cn('select-item', isSelected && 'select-item-selected', disabled && 'select-item-disabled', className), onClick: () => !disabled && handleSelect(value, children), role: "option", "aria-selected": isSelected, "data-disabled": disabled, ...props, children: [isSelected && (_jsx("span", { className: "select-item-indicator", children: _jsx(Check, {}) })), _jsx("span", { className: "select-item-text", children: children })] }));
296
+ return (_jsxs("div", { ref: ref, className: cn("select-item", isSelected && "select-item-selected", disabled && "select-item-disabled", className), onClick: () => !disabled && handleSelect(value, children), role: "option", "aria-selected": isSelected, "data-disabled": disabled, ...props, children: [isSelected && (_jsx("span", { className: "select-item-indicator", children: _jsx(Check, {}) })), _jsx("span", { className: "select-item-text", children: children })] }));
297
297
  });
298
- SelectItem.displayName = 'SelectItem';
299
- const SelectGroup = ({ children, className }) => (_jsx("div", { className: cn('select-group', className), children: children }));
300
- const SelectLabel = ({ children, className }) => (_jsx("div", { className: cn('select-label', className), children: children }));
301
- const SelectSeparator = ({ className }) => (_jsx("div", { className: cn('select-separator', className) }));
298
+ SelectItem.displayName = "SelectItem";
299
+ const SelectGroup = ({ children, className }) => (_jsx("div", { className: cn("select-group", className), children: children }));
300
+ const SelectLabel = ({ children, className }) => (_jsx("div", { className: cn("select-label", className), children: children }));
301
+ const SelectSeparator = ({ className }) => (_jsx("div", { className: cn("select-separator", className) }));
302
302
  export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, };
@@ -14,7 +14,7 @@ export const validateSubject = (subject) => {
14
14
  };
15
15
  export const validateMessage = (message) => {
16
16
  const trimmed = message.trim();
17
- return trimmed.length > 0 && trimmed.length <= 1000;
17
+ return trimmed.length > 0;
18
18
  };
19
19
  export const validateCountryCode = (code) => {
20
20
  return /^\+[1-9]\d{0,3}$/.test(code);
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { MedosThemeProvider } from "./react/ThemeProvider";
4
4
  export type { MedosThemeProviderProps } from "./react/ThemeProvider";
5
5
  export { defaultTheme, modernTheme } from "./core/theme/themes";
6
6
  export { useTheme, useThemeContext, useCssVar } from "./react/hooks/useTheme";
7
- export { AppointmentCalender } from "./components/AppointmentCalender";
7
+ export { AppointmentCalender } from "./components/appointment-booking";
8
8
  export { EnquiryForm } from "./components/EnquiryForm";
9
9
  export type { EnquiryFormProps } from "./components/EnquiryForm";
10
10
  export * from "./appointments/provider";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export * from "./core/theme";
3
3
  export { MedosThemeProvider } from "./react/ThemeProvider";
4
4
  export { defaultTheme, modernTheme } from "./core/theme/themes";
5
5
  export { useTheme, useThemeContext, useCssVar } from "./react/hooks/useTheme";
6
- export { AppointmentCalender } from "./components/AppointmentCalender";
6
+ export { AppointmentCalender } from "./components/appointment-booking";
7
7
  export { EnquiryForm } from "./components/EnquiryForm";
8
8
  export * from "./appointments/provider";
9
9
  export * from "./appointments/types";
@@ -2,6 +2,7 @@ export * from "../core";
2
2
  export { MedosThemeProvider } from "./ThemeProvider";
3
3
  export type { MedosThemeProviderProps } from "./ThemeProvider";
4
4
  export { useTheme, useThemeContext, useCssVar } from "./hooks/useTheme";
5
- export { AppointmentCalender } from "../components/AppointmentCalender";
5
+ export { AppointmentCalender } from "../components/appointment-booking";
6
+ export type { AppointmentCalenderProps } from "../components/appointment-booking";
6
7
  export { EnquiryForm } from "../components/EnquiryForm";
7
8
  export type { EnquiryFormProps } from "../components/EnquiryForm";
@@ -1,5 +1,5 @@
1
1
  export * from "../core";
2
2
  export { MedosThemeProvider } from "./ThemeProvider";
3
3
  export { useTheme, useThemeContext, useCssVar } from "./hooks/useTheme";
4
- export { AppointmentCalender } from "../components/AppointmentCalender";
4
+ export { AppointmentCalender } from "../components/appointment-booking";
5
5
  export { EnquiryForm } from "../components/EnquiryForm";
@@ -593,23 +593,30 @@ class AppointmentCalendarWidget {
593
593
  renderStep0() {
594
594
  const canProceed = this.canProceedFromMergedStep();
595
595
  return `
596
- <div class="medos-section-card">
597
- <div class="medos-section-header">
598
- ${VanillaIcons.mapPin(14)}
599
- <span class="medos-section-title">Location & Doctor</span>
596
+ <div style="border:1px solid #e5e7eb;border-radius:12px;margin-bottom:24px;background:#fff;">
597
+ <div style="background:#F9FAFB;padding:16px 20px;display:flex;align-items:center;gap:12px;border-bottom:1px solid #E5E7EB;">
598
+ ${VanillaIcons.mapPin(18)}
599
+ <h3 style="font-size:18px;font-weight:600;margin:0;">Location & Doctor</h3>
600
600
  </div>
601
- <div class="medos-section-body">
602
- <div class="medos-form-group">
603
- <label class="medos-label">Preferred Location <span class="medos-required">*</span></label>
601
+ <div style="padding:24px;">
602
+ <div style="margin-bottom:20px;">
603
+ <label style="display:block;font-size:13px;margin-bottom:6px;color:#374151;">
604
+ Preferred Location <span style="color:#EF4444">*</span>
605
+ </label>
604
606
  <div id="medos-address-select-container"></div>
605
607
  </div>
606
- <div class="medos-form-group">
607
- <label class="medos-label">Preferred Doctor <span class="medos-required">*</span></label>
608
+ <div style="margin-bottom:20px;">
609
+ <label style="display:block;font-size:13px;margin-bottom:6px;color:#374151;">
610
+ Preferred Doctor <span style="color:#EF4444">*</span>
611
+ </label>
608
612
  <div id="medos-doctor-select-container"></div>
609
613
  </div>
610
- <div class="medos-form-group">
611
- <label class="medos-label">Chief Complaint <span class="medos-optional">(optional)</span></label>
614
+ <div style="margin-bottom:20px;">
615
+ <label style="display:block;font-size:13px;margin-bottom:6px;color:#374151;">
616
+ Chief Complaint <span style="color:#6B7280">(optional)</span>
617
+ </label>
612
618
  <textarea
619
+ style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e6e9ef;font-size:14px;box-sizing:border-box;"
613
620
  class="medos-textarea"
614
621
  id="medos-chief-complaint"
615
622
  placeholder="Enter Chief Complaint or Appointment Notes"
@@ -617,8 +624,8 @@ class AppointmentCalendarWidget {
617
624
  </div>
618
625
  </div>
619
626
  </div>
620
- <div class="medos-actions">
621
- <button class="medos-btn medos-btn-primary" id="medos-btn-next" ${!canProceed ? "disabled" : ""}>Next</button>
627
+ <div style="display:flex;gap:8px;margin-top:16px;justify-content:flex-end;">
628
+ <button style="background:#218838;color:#fff;border:none;padding:10px 14px;border-radius:8px;cursor:pointer;font-weight:600;${!canProceed ? "opacity:0.6;" : ""}" id="medos-btn-next" ${!canProceed ? "disabled" : ""}>Next</button>
622
629
  </div>
623
630
  `;
624
631
  }
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { Doctor, AddressItem } from "../services/AppointmentService";
2
3
  interface AppointmentDetails {
3
4
  patientName?: string;
4
5
  visitationType?: string;
@@ -18,6 +19,8 @@ interface AppointmentConfirmationStepProps {
18
19
  lastName?: string;
19
20
  patientName?: string;
20
21
  };
22
+ selectedDoctor?: Doctor | null;
23
+ selectedAddress?: AddressItem | null;
21
24
  onClose: () => void;
22
25
  }
23
26
  declare const AppointmentConfirmationStep: React.FC<AppointmentConfirmationStepProps>;
@@ -6,6 +6,9 @@ type AppointmentModalProps = {
6
6
  onlineFee?: number | null;
7
7
  offlineFee?: number | null;
8
8
  slots: Slot[];
9
+ selectedDate?: Date;
10
+ selectedSlot?: Slot | null;
11
+ consultationMode?: AppointmentMode;
9
12
  onCancel: () => void;
10
13
  onContinue: (mode: AppointmentMode, date: Date, slot: Slot, charge: string, paymentMode: PaymentMode) => void;
11
14
  onDateChange?: (date: Date) => void;
@@ -1,5 +1,10 @@
1
1
  import React from "react";
2
+ import { Doctor, AddressItem } from "../services/AppointmentService";
2
3
  type DoctorSelectModalProps = {
4
+ addresses?: AddressItem[];
5
+ addressDoctorsMap?: Record<number, Doctor[]>;
6
+ selectedAddressId?: number | null;
7
+ selectedDoctorId?: number | null;
3
8
  onCancel: () => void;
4
9
  onContinue: (addressId: number, doctorId: number, notes?: string) => void;
5
10
  };
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ export interface AppointmentCalenderProps {
3
+ onError?: (err: Error) => void;
4
+ }
5
+ export declare const AppointmentCalender: React.FC<AppointmentCalenderProps>;
@@ -0,0 +1,3 @@
1
+ export { useAppointmentState } from "./useAppointmentState";
2
+ export { useAppointmentFlow } from "./useAppointmentFlow";
3
+ export { useInitializeAddresses } from "./useInitializeAddresses";
@@ -0,0 +1,9 @@
1
+ import { AppointmentState } from "../types";
2
+ export declare const useAppointmentFlow: (state: AppointmentState, dispatch: React.Dispatch<any>, onError?: (error: Error) => void) => {
3
+ goBack: () => void;
4
+ goToNext: () => void;
5
+ handleDateChange: (date: Date) => Promise<(() => void) | undefined>;
6
+ sendOtp: () => Promise<void>;
7
+ verifyOtp: () => Promise<void>;
8
+ submitAppointment: () => Promise<void>;
9
+ };
@@ -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 @@
1
+ export declare const useInitializeAddresses: (dispatch: React.Dispatch<any>, onError?: (error: Error) => void) => void;
@@ -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,128 @@
1
+ import { Doctor, Slot, AddressItem } from "../../services/AppointmentService";
2
+ export interface AppointmentState {
3
+ step: number;
4
+ loading: boolean;
5
+ error: string | null;
6
+ workspaceId: number | null;
7
+ addresses: AddressItem[];
8
+ addressDoctorsMap: Record<number, Doctor[]>;
9
+ selectedAddress: number | null;
10
+ selectedDoctor: number | null;
11
+ selectedDate: Date;
12
+ slots: Slot[];
13
+ selectedSlot: Slot | null;
14
+ consultationMode: "ONLINE" | "OFFLINE";
15
+ consultationCharge: string;
16
+ patientName: string;
17
+ patientAge: string;
18
+ patientEmail: string;
19
+ patientGender: string;
20
+ bloodGroup: string;
21
+ patientAddress: string;
22
+ patientCity: string;
23
+ patientState: string;
24
+ patientCountry: string;
25
+ patientZipcode: string;
26
+ patientLandmark: string;
27
+ countryCode: string;
28
+ patientPhone: string;
29
+ otpCode: string;
30
+ otpSent: boolean;
31
+ otpVerified: boolean;
32
+ otpSending: boolean;
33
+ otpVerifying: boolean;
34
+ }
35
+ export type AppointmentAction = {
36
+ type: "SET_STEP";
37
+ payload: number;
38
+ } | {
39
+ type: "SET_LOADING";
40
+ payload: boolean;
41
+ } | {
42
+ type: "SET_ERROR";
43
+ payload: string | null;
44
+ } | {
45
+ type: "SET_WORKSPACE";
46
+ payload: {
47
+ id: number;
48
+ addresses: AddressItem[];
49
+ };
50
+ } | {
51
+ type: "SET_SELECTED_ADDRESS";
52
+ payload: number | null;
53
+ } | {
54
+ type: "SET_SELECTED_DOCTOR";
55
+ payload: number | null;
56
+ } | {
57
+ type: "SET_SELECTED_DATE";
58
+ payload: Date;
59
+ } | {
60
+ type: "SET_SLOTS";
61
+ payload: Slot[];
62
+ } | {
63
+ type: "SET_SELECTED_SLOT";
64
+ payload: Slot | null;
65
+ } | {
66
+ type: "SET_CONSULTATION_MODE";
67
+ payload: "ONLINE" | "OFFLINE";
68
+ } | {
69
+ type: "SET_CONSULTATION_CHARGE";
70
+ payload: string;
71
+ } | {
72
+ type: "SET_PATIENT_NAME";
73
+ payload: string;
74
+ } | {
75
+ type: "SET_PATIENT_AGE";
76
+ payload: string;
77
+ } | {
78
+ type: "SET_PATIENT_EMAIL";
79
+ payload: string;
80
+ } | {
81
+ type: "SET_PATIENT_GENDER";
82
+ payload: string;
83
+ } | {
84
+ type: "SET_BLOOD_GROUP";
85
+ payload: string;
86
+ } | {
87
+ type: "SET_PATIENT_ADDRESS";
88
+ payload: string;
89
+ } | {
90
+ type: "SET_PATIENT_CITY";
91
+ payload: string;
92
+ } | {
93
+ type: "SET_PATIENT_STATE";
94
+ payload: string;
95
+ } | {
96
+ type: "SET_PATIENT_COUNTRY";
97
+ payload: string;
98
+ } | {
99
+ type: "SET_PATIENT_ZIPCODE";
100
+ payload: string;
101
+ } | {
102
+ type: "SET_PATIENT_LANDMARK";
103
+ payload: string;
104
+ } | {
105
+ type: "SET_COUNTRY_CODE";
106
+ payload: string;
107
+ } | {
108
+ type: "SET_PATIENT_PHONE";
109
+ payload: string;
110
+ } | {
111
+ type: "SET_OTP_CODE";
112
+ payload: string;
113
+ } | {
114
+ type: "SET_OTP_SENT";
115
+ payload: boolean;
116
+ } | {
117
+ type: "SET_OTP_VERIFIED";
118
+ payload: boolean;
119
+ } | {
120
+ type: "SET_OTP_SENDING";
121
+ payload: boolean;
122
+ } | {
123
+ type: "SET_OTP_VERIFYING";
124
+ payload: boolean;
125
+ } | {
126
+ type: "RESET_FORM";
127
+ };
128
+ export declare const INITIAL_STATE: AppointmentState;