medos-sdk 1.0.1 → 1.0.3

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 (113) hide show
  1. package/README.md +208 -73
  2. package/dist/client/MedosClient.d.ts +1 -1
  3. package/dist/client/MedosClient.js +1 -1
  4. package/dist/components/AppointmentCalender.d.ts +1 -4
  5. package/dist/components/AppointmentCalender.js +282 -486
  6. package/dist/components/AppointmentDateTimeModal.d.ts +14 -0
  7. package/dist/components/AppointmentDateTimeModal.js +206 -0
  8. package/dist/components/ConfigurableCard.d.ts +12 -0
  9. package/dist/components/ConfigurableCard.js +29 -0
  10. package/dist/components/DoctorSelectModal.d.ts +7 -0
  11. package/dist/components/DoctorSelectModal.js +80 -0
  12. package/dist/components/Icons/Check.d.ts +6 -0
  13. package/dist/components/Icons/Check.js +2 -0
  14. package/dist/components/Icons/ChevronDownIcon.d.ts +4 -0
  15. package/dist/components/Icons/ChevronDownIcon.js +2 -0
  16. package/dist/components/Icons/ChevronLeft.d.ts +3 -0
  17. package/dist/components/Icons/ChevronLeft.js +3 -0
  18. package/dist/components/Icons/ChevronRight.d.ts +3 -0
  19. package/dist/components/Icons/ChevronRight.js +3 -0
  20. package/dist/components/Icons/ConfirmationCheck.d.ts +1 -0
  21. package/dist/components/Icons/ConfirmationCheck.js +9 -0
  22. package/dist/components/Icons/ConsultationType.d.ts +1 -0
  23. package/dist/components/Icons/ConsultationType.js +2 -0
  24. package/dist/components/Icons/Date&TimeIcon.d.ts +1 -0
  25. package/dist/components/Icons/Date&TimeIcon.js +2 -0
  26. package/dist/components/Icons/MapIcon.d.ts +1 -0
  27. package/dist/components/Icons/MapIcon.js +2 -0
  28. package/dist/components/Icons/PaymentMethodIcon.d.ts +1 -0
  29. package/dist/components/Icons/PaymentMethodIcon.js +2 -0
  30. package/dist/components/Icons/UserIcon.d.ts +1 -0
  31. package/dist/components/Icons/UserIcon.js +2 -0
  32. package/dist/components/PatientDetailsStep.d.ts +3 -0
  33. package/dist/components/PatientDetailsStep.js +76 -0
  34. package/dist/components/PhoneVerificationStep.d.ts +3 -0
  35. package/dist/components/PhoneVerificationStep.js +39 -0
  36. package/dist/components/SuccessStep.d.ts +3 -0
  37. package/dist/components/SuccessStep.js +17 -0
  38. package/dist/components/custom-calendar.d.ts +5 -0
  39. package/dist/components/custom-calendar.js +153 -0
  40. package/dist/components/styles.d.ts +6 -0
  41. package/dist/components/styles.js +257 -0
  42. package/dist/components/types.d.ts +182 -0
  43. package/dist/components/types.js +55 -0
  44. package/dist/components/ui/select.d.ts +10 -0
  45. package/dist/components/ui/select.js +21 -0
  46. package/dist/components/uiComponents/SelectDropdown.d.ts +41 -0
  47. package/dist/components/uiComponents/SelectDropdown.js +302 -0
  48. package/dist/components/utils.d.ts +5 -0
  49. package/dist/components/utils.js +15 -0
  50. package/dist/components/validation.d.ts +2 -0
  51. package/dist/components/validation.js +7 -0
  52. package/dist/context/TemplateContext.d.ts +12 -0
  53. package/dist/context/TemplateContext.js +19 -0
  54. package/dist/core/index.d.ts +8 -0
  55. package/dist/core/index.js +8 -0
  56. package/dist/lib/templateUtils.d.ts +3 -0
  57. package/dist/lib/templateUtils.js +28 -0
  58. package/dist/react/index.d.ts +2 -0
  59. package/dist/react/index.js +2 -0
  60. package/dist/services/AppointmentService.d.ts +9 -10
  61. package/dist/services/AppointmentService.js +12 -10
  62. package/dist/templates/registry.d.ts +12 -0
  63. package/dist/templates/registry.js +58 -0
  64. package/dist/vanilla/AppointmentCalendarWidget.d.ts +41 -0
  65. package/dist/vanilla/AppointmentCalendarWidget.js +848 -0
  66. package/dist/vanilla/appointment-calendar/provider.d.ts +13 -0
  67. package/dist/vanilla/appointment-calendar/types.d.ts +144 -0
  68. package/dist/vanilla/appointments/provider.d.ts +13 -0
  69. package/dist/vanilla/appointments/types.d.ts +81 -0
  70. package/dist/vanilla/client/MedosClient.d.ts +32 -0
  71. package/dist/vanilla/components/AppointmentCalender.d.ts +3 -0
  72. package/dist/vanilla/components/AppointmentDateTimeModal.d.ts +14 -0
  73. package/dist/vanilla/components/ConfigurableCard.d.ts +12 -0
  74. package/dist/vanilla/components/DoctorSelectModal.d.ts +7 -0
  75. package/dist/vanilla/components/Icons/Check.d.ts +6 -0
  76. package/dist/vanilla/components/Icons/ChevronDownIcon.d.ts +4 -0
  77. package/dist/vanilla/components/Icons/ChevronLeft.d.ts +3 -0
  78. package/dist/vanilla/components/Icons/ChevronRight.d.ts +3 -0
  79. package/dist/vanilla/components/Icons/ConfirmationCheck.d.ts +1 -0
  80. package/dist/vanilla/components/Icons/ConsultationType.d.ts +1 -0
  81. package/dist/vanilla/components/Icons/Date&TimeIcon.d.ts +1 -0
  82. package/dist/vanilla/components/Icons/MapIcon.d.ts +1 -0
  83. package/dist/vanilla/components/Icons/PaymentMethodIcon.d.ts +1 -0
  84. package/dist/vanilla/components/Icons/UserIcon.d.ts +1 -0
  85. package/dist/vanilla/components/PatientDetailsStep.d.ts +3 -0
  86. package/dist/vanilla/components/PhoneVerificationStep.d.ts +3 -0
  87. package/dist/vanilla/components/SuccessStep.d.ts +3 -0
  88. package/dist/vanilla/components/custom-calendar.d.ts +5 -0
  89. package/dist/vanilla/components/styles.d.ts +6 -0
  90. package/dist/vanilla/components/types.d.ts +182 -0
  91. package/dist/vanilla/components/ui/select.d.ts +10 -0
  92. package/dist/vanilla/components/uiComponents/SelectDropdown.d.ts +41 -0
  93. package/dist/vanilla/components/utils.d.ts +5 -0
  94. package/dist/vanilla/components/validation.d.ts +2 -0
  95. package/dist/vanilla/context/TemplateContext.d.ts +12 -0
  96. package/dist/vanilla/core/index.d.ts +8 -0
  97. package/dist/vanilla/index.d.ts +7 -0
  98. package/dist/vanilla/index.js +2 -0
  99. package/dist/vanilla/lib/templateUtils.d.ts +3 -0
  100. package/dist/vanilla/react/index.d.ts +2 -0
  101. package/dist/vanilla/services/AppointmentService.d.ts +85 -0
  102. package/dist/vanilla/services/AuthService.d.ts +6 -0
  103. package/dist/vanilla/services/PatientService.d.ts +14 -0
  104. package/dist/vanilla/templates/alternative.css +13 -0
  105. package/dist/vanilla/templates/default.css +13 -0
  106. package/dist/vanilla/templates/registry.d.ts +12 -0
  107. package/dist/vanilla/vanilla/AppointmentCalendarWidget.d.ts +41 -0
  108. package/dist/vanilla/vanilla/index.d.ts +2 -0
  109. package/dist/vanilla/vanilla/widget.d.ts +10 -0
  110. package/dist/vanilla/widget.css +217 -0
  111. package/dist/vanilla/widget.d.ts +10 -0
  112. package/dist/vanilla/widget.js +5084 -0
  113. package/package.json +40 -5
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BUTTON_STYLES, SUCCESS_STYLES, CONTAINER_STYLES } from "./styles";
3
+ import { ConfirmationCheck } from "./Icons/ConfirmationCheck";
4
+ export const SuccessStep = ({ state, onReset }) => {
5
+ const formattedDate = state.selectedDate
6
+ ? new Date(state.selectedDate).toLocaleDateString("en-US", {
7
+ weekday: "long",
8
+ year: "numeric",
9
+ month: "long",
10
+ day: "numeric",
11
+ })
12
+ : "";
13
+ const formattedTime = state.selectedSlot
14
+ ? state.selectedSlot.startTime
15
+ : "TBD";
16
+ return (_jsx("div", { style: CONTAINER_STYLES.section, children: _jsxs("div", { style: SUCCESS_STYLES.container, children: [_jsxs("div", { style: SUCCESS_STYLES.header, children: [_jsx("div", { style: SUCCESS_STYLES.iconContainer, children: _jsx(ConfirmationCheck, {}) }), _jsx("div", { children: "Appointment Confirmed!" })] }), _jsxs("div", { style: SUCCESS_STYLES.detailsContainer, children: [_jsx("div", { style: SUCCESS_STYLES.detailsTitle, children: "Your appointment has been successfully booked" }), _jsxs("div", { style: SUCCESS_STYLES.detailsList, children: [_jsxs("div", { children: [_jsx("strong", { children: "Patient Name:" }), " ", state.patientName] }), _jsxs("div", { children: [_jsx("strong", { children: "Consultation Mode:" }), " ", state.consultationMode] }), _jsxs("div", { children: [_jsx("strong", { children: "Date:" }), " ", formattedDate] }), _jsxs("div", { children: [_jsx("strong", { children: "Time:" }), " ", formattedTime] }), state.selectedSlot && (_jsxs("div", { children: [_jsx("strong", { children: "Duration:" }), " ", state.selectedSlot.duration, " minutes"] })), _jsxs("div", { children: [_jsx("strong", { children: "Charge:" }), " ", state.consultationCharge] })] }), _jsxs("div", { style: SUCCESS_STYLES.confirmationNote, children: ["A confirmation email has been sent to ", state.patientEmail] })] }), _jsx("div", { style: SUCCESS_STYLES.actionContainer, children: _jsx("button", { style: BUTTON_STYLES.primary, onClick: onReset, children: "Book Another Appointment" }) })] }) }));
17
+ };
@@ -0,0 +1,5 @@
1
+ export declare const CustomCalendarWithDateSelector: ({ selectedDate, onSelect, pastDisabled, }: {
2
+ selectedDate?: Date;
3
+ onSelect: (date: Date) => void;
4
+ pastDisabled?: boolean;
5
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,153 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import ChevronLeft from "./Icons/ChevronLeft";
4
+ import ChevronRight from "./Icons/ChevronRight";
5
+ const style = `
6
+ .custom-calendar {
7
+ width: 340px;
8
+ background-color: #ffffff;
9
+ border-radius: 8px;
10
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
11
+ padding: 16px;
12
+ font-family: Inter, sans-serif;
13
+ }
14
+ .calendar-header {
15
+ display: flex;
16
+ justify-content: space-between;
17
+ align-items: center;
18
+ margin-bottom: 12px;
19
+ }
20
+ .calendar-month {
21
+ font-size: 14px;
22
+ font-weight: 600;
23
+ color: #1e1e1e;
24
+ }
25
+ .calendar-nav {
26
+ width: 20px;
27
+ height: 20px;
28
+ color: #218838;
29
+ cursor: pointer;
30
+ border-radius: 4px;
31
+ transition: background-color 0.2s;
32
+ }
33
+ .calendar-nav:hover {
34
+ background-color: #eaf8f0;
35
+ }
36
+ .calendar-days-header {
37
+ display: grid;
38
+ grid-template-columns: repeat(7, 1fr);
39
+ text-align: center;
40
+ margin-bottom: 6px;
41
+ font-size: 13px;
42
+ font-weight: 500;
43
+ color: #222;
44
+ }
45
+ .calendar-grid {
46
+ display: grid;
47
+ grid-template-columns: repeat(7, 1fr);
48
+ gap: 6px;
49
+ text-align: center;
50
+ }
51
+ .calendar-day {
52
+ width: 38px;
53
+ height: 38px;
54
+ border: 1px solid transparent;
55
+ border-radius: 6px;
56
+ color: #218838;
57
+ background-color: transparent;
58
+ font-size: 14px;
59
+ transition: all 0.2s;
60
+ display: flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ flex-direction: column;
64
+ }
65
+ .calendar-day span {
66
+ line-height: 1;
67
+ }
68
+ .calendar-day:hover:not(.disabled):not(.selected) {
69
+ background-color: #218838;
70
+ color: #ffffff;
71
+ }
72
+ .calendar-day.selected {
73
+ border: 1px solid #218838;
74
+ color: #218838;
75
+ background-color: transparent;
76
+ font-weight: 600;
77
+ }
78
+ .calendar-day.disabled {
79
+ color: #b3b3b3;
80
+ opacity: 0.4;
81
+ cursor: not-allowed;
82
+ }
83
+ .calendar-dot {
84
+ font-size: 10px;
85
+ margin-top: -2px;
86
+ line-height: 1;
87
+ }
88
+ .calendar-empty {
89
+ visibility: hidden;
90
+ }
91
+ `;
92
+ export const CustomCalendarWithDateSelector = ({ selectedDate, onSelect, pastDisabled = false, }) => {
93
+ useEffect(() => {
94
+ if (!document.getElementById("custom-calendar-style")) {
95
+ const s = document.createElement("style");
96
+ s.id = "custom-calendar-style";
97
+ s.innerHTML = style;
98
+ document.head.appendChild(s);
99
+ }
100
+ }, []);
101
+ const today = new Date();
102
+ today.setHours(0, 0, 0, 0);
103
+ const [currentMonth, setCurrentMonth] = useState(today.getMonth());
104
+ const [currentYear, setCurrentYear] = useState(today.getFullYear());
105
+ const daysOfWeek = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
106
+ const months = [
107
+ "January", "February", "March", "April", "May", "June",
108
+ "July", "August", "September", "October", "November", "December"
109
+ ];
110
+ const getDaysInMonth = (year, month) => {
111
+ return new Date(year, month + 1, 0).getDate();
112
+ };
113
+ const getFirstDayOfMonth = (year, month) => {
114
+ return new Date(year, month, 1).getDay();
115
+ };
116
+ const daysInMonth = getDaysInMonth(currentYear, currentMonth);
117
+ const firstDayOfMonth = getFirstDayOfMonth(currentYear, currentMonth);
118
+ const startOffset = (firstDayOfMonth + 6) % 7;
119
+ const prevMonth = () => {
120
+ if (currentMonth === 0) {
121
+ setCurrentMonth(11);
122
+ setCurrentYear(currentYear - 1);
123
+ }
124
+ else {
125
+ setCurrentMonth(currentMonth - 1);
126
+ }
127
+ };
128
+ const nextMonth = () => {
129
+ if (currentMonth === 11) {
130
+ setCurrentMonth(0);
131
+ setCurrentYear(currentYear + 1);
132
+ }
133
+ else {
134
+ setCurrentMonth(currentMonth + 1);
135
+ }
136
+ };
137
+ const isSameDate = (d1, d2) => {
138
+ return d1.getFullYear() === d2.getFullYear() &&
139
+ d1.getMonth() === d2.getMonth() &&
140
+ d1.getDate() === d2.getDate();
141
+ };
142
+ const isBeforeToday = (date) => {
143
+ const todayStart = new Date(today);
144
+ todayStart.setHours(0, 0, 0, 0);
145
+ return date < todayStart;
146
+ };
147
+ return (_jsxs("div", { className: "custom-calendar", children: [_jsxs("div", { className: "calendar-header", children: [_jsx(ChevronLeft, { onClick: prevMonth, className: "calendar-nav" }), _jsxs("p", { className: "calendar-month", children: [months[currentMonth], " ", currentYear] }), _jsx(ChevronRight, { onClick: nextMonth, className: "calendar-nav" })] }), _jsx("div", { className: "calendar-days-header", children: daysOfWeek.map((d) => (_jsx("div", { className: "calendar-day-name", children: d }, d))) }), _jsxs("div", { className: "calendar-grid", children: [Array.from({ length: startOffset }).map((_, idx) => (_jsx("div", { className: "calendar-empty" }, `empty-${idx}`))), Array.from({ length: daysInMonth }).map((_, i) => {
148
+ const date = new Date(currentYear, currentMonth, i + 1);
149
+ const disabled = pastDisabled && isBeforeToday(date);
150
+ const isSelected = selectedDate && isSameDate(selectedDate, date);
151
+ return (_jsxs("button", { disabled: disabled, onClick: () => onSelect(date), className: `calendar-day ${isSelected ? "selected" : ""} ${disabled ? "disabled" : ""}`, children: [_jsx("span", { children: i + 1 }), isSelected && _jsx("span", { className: "calendar-dot", children: "\u2022" })] }, i + 1));
152
+ })] })] }));
153
+ };
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export declare const CONTAINER_STYLES: Record<string, React.CSSProperties>;
3
+ export declare const BUTTON_STYLES: Record<string, React.CSSProperties>;
4
+ export declare const PHONE_VERIFY_STYLES: Record<string, React.CSSProperties>;
5
+ export declare const PATIENT_DETAILS_STYLES: Record<string, React.CSSProperties>;
6
+ export declare const SUCCESS_STYLES: Record<string, React.CSSProperties>;
@@ -0,0 +1,257 @@
1
+ export const CONTAINER_STYLES = {
2
+ container: {
3
+ display: "flex",
4
+ justifyContent: "center",
5
+ padding: 20,
6
+ fontFamily: "'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial",
7
+ background: "#f6f8fa",
8
+ },
9
+ card: {
10
+ width: "100%",
11
+ maxWidth: 720,
12
+ background: "#fff",
13
+ borderRadius: 12,
14
+ boxShadow: "0 8px 24px rgba(16,24,40,0.08)",
15
+ padding: 24,
16
+ boxSizing: "border-box",
17
+ },
18
+ header: {
19
+ display: "flex",
20
+ alignItems: "center",
21
+ justifyContent: "space-between",
22
+ marginBottom: 16,
23
+ },
24
+ title: {
25
+ marginLeft: 10,
26
+ fontSize: 20,
27
+ fontWeight: 600,
28
+ },
29
+ section: { marginTop: 12 },
30
+ errorMessage: {
31
+ marginBottom: 12,
32
+ color: "#ef4444",
33
+ fontWeight: 600,
34
+ },
35
+ actions: {
36
+ display: "flex",
37
+ gap: 8,
38
+ marginTop: 16,
39
+ justifyContent: "flex-end",
40
+ },
41
+ };
42
+ export const BUTTON_STYLES = {
43
+ primary: {
44
+ background: "#218838",
45
+ color: "#fff",
46
+ border: "none",
47
+ padding: "10px 14px",
48
+ borderRadius: 8,
49
+ cursor: "pointer",
50
+ fontWeight: 600,
51
+ },
52
+ secondary: {
53
+ background: "#fff",
54
+ color: "#218838",
55
+ border: "1px solid #218838",
56
+ padding: "10px 14px",
57
+ borderRadius: 8,
58
+ cursor: "pointer",
59
+ },
60
+ };
61
+ export const PHONE_VERIFY_STYLES = {
62
+ container: {
63
+ border: "1px solid #e5e7eb",
64
+ borderRadius: 12,
65
+ overflow: "hidden",
66
+ backgroundColor: "#fff",
67
+ },
68
+ header: {
69
+ padding: "16px 24px",
70
+ borderBottom: "1px solid #e5e7eb",
71
+ backgroundColor: "#f9fafb",
72
+ },
73
+ title: {
74
+ margin: 0,
75
+ fontSize: 18,
76
+ fontWeight: 600,
77
+ color: "#111827",
78
+ },
79
+ content: { padding: "24px" },
80
+ label: {
81
+ display: "block",
82
+ fontSize: 14,
83
+ fontWeight: 500,
84
+ color: "#111827",
85
+ marginBottom: 8,
86
+ },
87
+ phoneInputContainer: { display: "flex", gap: 8 },
88
+ phoneInput: {
89
+ flex: 1,
90
+ padding: "10px 12px",
91
+ borderRadius: 8,
92
+ border: "1px solid #e6e9ef",
93
+ fontSize: 14,
94
+ outline: "none",
95
+ color: "#111827",
96
+ boxSizing: "border-box",
97
+ },
98
+ phoneDisplay: {
99
+ padding: "10px 12px",
100
+ background: "#f9fafb",
101
+ borderRadius: 8,
102
+ fontSize: 14,
103
+ color: "#374151",
104
+ fontWeight: 500,
105
+ },
106
+ otpInput: {
107
+ width: "100%",
108
+ padding: "10px 12px",
109
+ border: "1px solid #d1d5db",
110
+ borderRadius: 8,
111
+ fontSize: 14,
112
+ outline: "none",
113
+ color: "#111827",
114
+ boxSizing: "border-box",
115
+ },
116
+ otpHint: {
117
+ marginTop: 8,
118
+ fontSize: 12,
119
+ color: "#6b7280",
120
+ },
121
+ successMessage: {
122
+ marginTop: 20,
123
+ padding: 16,
124
+ borderRadius: 8,
125
+ backgroundColor: "#F6FBF6",
126
+ border: "1px solid #218838",
127
+ display: "flex",
128
+ alignItems: "center",
129
+ gap: 12,
130
+ },
131
+ successIcon: { fontSize: 24, color: "#218838" },
132
+ successTitle: {
133
+ fontSize: 14,
134
+ fontWeight: 600,
135
+ color: "#218838",
136
+ },
137
+ successSubtitle: {
138
+ fontSize: 12,
139
+ color: "#6B7280",
140
+ marginTop: 2,
141
+ },
142
+ footer: {
143
+ padding: "16px 24px",
144
+ borderTop: "1px solid #e5e7eb",
145
+ backgroundColor: "#fff",
146
+ display: "flex",
147
+ gap: 12,
148
+ justifyContent: "flex-end",
149
+ },
150
+ };
151
+ export const PATIENT_DETAILS_STYLES = {
152
+ sectionCard: {
153
+ border: "1px solid #E5E7EB",
154
+ borderRadius: "12px",
155
+ marginBottom: "24px",
156
+ },
157
+ sectionHeader: {
158
+ backgroundColor: "#F9FAFB",
159
+ padding: "16px 20px",
160
+ display: "flex",
161
+ alignItems: "center",
162
+ gap: "12px",
163
+ borderBottom: "1px solid #E5E7EB",
164
+ },
165
+ sectionTitle: {
166
+ fontSize: "18px",
167
+ fontWeight: 600,
168
+ margin: 0,
169
+ },
170
+ sectionBody: { padding: "24px" },
171
+ gridRow: {
172
+ display: "grid",
173
+ gridTemplateColumns: "1fr 1fr",
174
+ gap: "20px",
175
+ marginTop: "20px",
176
+ },
177
+ label: {
178
+ display: "block",
179
+ fontSize: 13,
180
+ marginBottom: 6,
181
+ color: "#374151",
182
+ },
183
+ input: {
184
+ width: "100%",
185
+ padding: "10px 12px",
186
+ borderRadius: 8,
187
+ border: "1px solid #e6e9ef",
188
+ outline: "none",
189
+ fontSize: 14,
190
+ boxSizing: "border-box",
191
+ },
192
+ phoneDisplay: { display: "flex", gap: "8px" },
193
+ phoneCode: {
194
+ width: "100px",
195
+ padding: "10px 12px",
196
+ borderRadius: 8,
197
+ border: "1px solid #e6e9ef",
198
+ backgroundColor: "#F9FAFB",
199
+ fontSize: 14,
200
+ boxSizing: "border-box",
201
+ },
202
+ phoneNumber: {
203
+ flex: 1,
204
+ padding: "10px 12px",
205
+ borderRadius: 8,
206
+ border: "1px solid #e6e9ef",
207
+ backgroundColor: "#F9FAFB",
208
+ fontSize: 14,
209
+ boxSizing: "border-box",
210
+ },
211
+ };
212
+ export const SUCCESS_STYLES = {
213
+ container: {
214
+ display: "flex",
215
+ flexDirection: "column",
216
+ height: "100%",
217
+ },
218
+ header: {
219
+ marginTop: "-16px",
220
+ alignItems: "center",
221
+ textAlign: "center",
222
+ color: "#27903F",
223
+ fontWeight: 800,
224
+ fontSize: "18px",
225
+ marginBottom: "20px",
226
+ },
227
+ iconContainer: {
228
+ display: "flex",
229
+ alignItems: "center",
230
+ justifyContent: "center",
231
+ padding: "12px 0",
232
+ },
233
+ detailsContainer: {
234
+ display: "flex",
235
+ flexDirection: "column",
236
+ alignItems: "center",
237
+ gap: "12px",
238
+ textAlign: "center",
239
+ color: "#27903F",
240
+ },
241
+ detailsTitle: { fontWeight: 600, fontSize: "16px" },
242
+ detailsList: {
243
+ display: "flex",
244
+ flexDirection: "column",
245
+ gap: "4px",
246
+ fontSize: "14px",
247
+ width: "100%",
248
+ maxWidth: "28rem",
249
+ textAlign: "center",
250
+ },
251
+ confirmationNote: {
252
+ marginTop: "8px",
253
+ fontSize: "12px",
254
+ color: "#6B7280",
255
+ },
256
+ actionContainer: { marginTop: "24px" },
257
+ };
@@ -0,0 +1,182 @@
1
+ import { Doctor, Slot, AddressItem } from "../services/AppointmentService";
2
+ export type AppointmentCalenderProps = {
3
+ onError?: (err: Error) => void;
4
+ };
5
+ export type PhoneVerificationStepProps = {
6
+ state: AppointmentState;
7
+ dispatch: React.Dispatch<AppointmentAction>;
8
+ onSendOtp: () => Promise<void>;
9
+ onVerifyOtp: () => Promise<void>;
10
+ onBack: () => void;
11
+ onContinue: () => void;
12
+ };
13
+ export type PatientDetailsStepProps = {
14
+ state: AppointmentState;
15
+ dispatch: React.Dispatch<AppointmentAction>;
16
+ onBack: () => void;
17
+ onSubmit: () => Promise<void>;
18
+ };
19
+ export type SuccessStepProps = {
20
+ state: AppointmentState;
21
+ onReset: () => void;
22
+ };
23
+ export type PhoneInputSectionProps = {
24
+ countryCode: string;
25
+ patientPhone: string;
26
+ onCountryCodeChange: (code: string) => void;
27
+ onPhoneChange: (phone: string) => void;
28
+ };
29
+ export type OtpInputSectionProps = {
30
+ countryCode: string;
31
+ patientPhone: string;
32
+ otpCode: string;
33
+ otpVerified: boolean;
34
+ onOtpChange: (code: string) => void;
35
+ };
36
+ export type PatientInfoSectionProps = {
37
+ state: AppointmentState;
38
+ dispatch: React.Dispatch<AppointmentAction>;
39
+ };
40
+ export type AddressInfoSectionProps = {
41
+ state: AppointmentState;
42
+ dispatch: React.Dispatch<AppointmentAction>;
43
+ };
44
+ export interface AppointmentState {
45
+ step: number;
46
+ loading: boolean;
47
+ error: string | null;
48
+ workspaceId: number | null;
49
+ addresses: AddressItem[];
50
+ addressDoctorsMap: Record<number, Doctor[]>;
51
+ selectedAddress: number | null;
52
+ selectedDoctor: number | null;
53
+ selectedDate: Date;
54
+ slots: Slot[];
55
+ selectedSlot: Slot | null;
56
+ consultationMode: "ONLINE" | "OFFLINE";
57
+ consultationCharge: string;
58
+ patientName: string;
59
+ patientAge: string;
60
+ patientEmail: string;
61
+ patientGender: string;
62
+ bloodGroup: string;
63
+ patientAddress: string;
64
+ patientCity: string;
65
+ patientState: string;
66
+ patientCountry: string;
67
+ patientZipcode: string;
68
+ patientLandmark: string;
69
+ countryCode: string;
70
+ patientPhone: string;
71
+ otpCode: string;
72
+ otpSent: boolean;
73
+ otpVerified: boolean;
74
+ otpSending: boolean;
75
+ otpVerifying: boolean;
76
+ }
77
+ export type AppointmentAction = {
78
+ type: "SET_STEP";
79
+ payload: number;
80
+ } | {
81
+ type: "SET_LOADING";
82
+ payload: boolean;
83
+ } | {
84
+ type: "SET_ERROR";
85
+ payload: string | null;
86
+ } | {
87
+ type: "SET_WORKSPACE";
88
+ payload: {
89
+ id: number;
90
+ addresses: AddressItem[];
91
+ };
92
+ } | {
93
+ type: "SET_SELECTED_ADDRESS";
94
+ payload: number | null;
95
+ } | {
96
+ type: "SET_SELECTED_DOCTOR";
97
+ payload: number | null;
98
+ } | {
99
+ type: "SET_SELECTED_DATE";
100
+ payload: Date;
101
+ } | {
102
+ type: "SET_SLOTS";
103
+ payload: Slot[];
104
+ } | {
105
+ type: "SET_SELECTED_SLOT";
106
+ payload: Slot | null;
107
+ } | {
108
+ type: "SET_CONSULTATION_MODE";
109
+ payload: "ONLINE" | "OFFLINE";
110
+ } | {
111
+ type: "SET_CONSULTATION_CHARGE";
112
+ payload: string;
113
+ } | {
114
+ type: "SET_PATIENT_NAME";
115
+ payload: string;
116
+ } | {
117
+ type: "SET_PATIENT_AGE";
118
+ payload: string;
119
+ } | {
120
+ type: "SET_PATIENT_EMAIL";
121
+ payload: string;
122
+ } | {
123
+ type: "SET_PATIENT_GENDER";
124
+ payload: string;
125
+ } | {
126
+ type: "SET_BLOOD_GROUP";
127
+ payload: string;
128
+ } | {
129
+ type: "SET_PATIENT_ADDRESS";
130
+ payload: string;
131
+ } | {
132
+ type: "SET_PATIENT_CITY";
133
+ payload: string;
134
+ } | {
135
+ type: "SET_PATIENT_STATE";
136
+ payload: string;
137
+ } | {
138
+ type: "SET_PATIENT_COUNTRY";
139
+ payload: string;
140
+ } | {
141
+ type: "SET_PATIENT_ZIPCODE";
142
+ payload: string;
143
+ } | {
144
+ type: "SET_PATIENT_LANDMARK";
145
+ payload: string;
146
+ } | {
147
+ type: "SET_COUNTRY_CODE";
148
+ payload: string;
149
+ } | {
150
+ type: "SET_PATIENT_PHONE";
151
+ payload: string;
152
+ } | {
153
+ type: "SET_OTP_CODE";
154
+ payload: string;
155
+ } | {
156
+ type: "SET_OTP_SENT";
157
+ payload: boolean;
158
+ } | {
159
+ type: "SET_OTP_VERIFIED";
160
+ payload: boolean;
161
+ } | {
162
+ type: "SET_OTP_SENDING";
163
+ payload: boolean;
164
+ } | {
165
+ type: "SET_OTP_VERIFYING";
166
+ payload: boolean;
167
+ } | {
168
+ type: "RESET_FORM";
169
+ };
170
+ export declare const COUNTRY_CODES: {
171
+ code: string;
172
+ label: string;
173
+ }[];
174
+ export declare const GENDER_OPTIONS: {
175
+ value: string;
176
+ label: string;
177
+ }[];
178
+ export declare const BLOOD_GROUP_OPTIONS: {
179
+ value: string;
180
+ label: string;
181
+ }[];
182
+ export declare const INITIAL_STATE: AppointmentState;
@@ -0,0 +1,55 @@
1
+ export const COUNTRY_CODES = [
2
+ { code: "+91", label: "🇮🇳 +91" },
3
+ { code: "+1", label: "🇺🇸 +1" },
4
+ { code: "+44", label: "🇬🇧 +44" },
5
+ { code: "+86", label: "🇨🇳 +86" },
6
+ { code: "+81", label: "🇯🇵 +81" },
7
+ ];
8
+ export const GENDER_OPTIONS = [
9
+ { value: "MALE", label: "Male" },
10
+ { value: "FEMALE", label: "Female" },
11
+ { value: "OTHER", label: "Other" },
12
+ ];
13
+ export const BLOOD_GROUP_OPTIONS = [
14
+ { value: "A+", label: "A+" },
15
+ { value: "A-", label: "A-" },
16
+ { value: "B+", label: "B+" },
17
+ { value: "B-", label: "B-" },
18
+ { value: "AB+", label: "AB+" },
19
+ { value: "AB-", label: "AB-" },
20
+ { value: "O+", label: "O+" },
21
+ { value: "O-", label: "O-" },
22
+ ];
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
+ };
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ export interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
3
+ children: React.ReactNode;
4
+ }
5
+ declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLSelectElement>>;
6
+ export interface SelectOptionProps extends React.OptionHTMLAttributes<HTMLOptionElement> {
7
+ children: React.ReactNode;
8
+ }
9
+ declare const SelectOption: React.ForwardRefExoticComponent<SelectOptionProps & React.RefAttributes<HTMLOptionElement>>;
10
+ export { Select, SelectOption };