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.
- package/README.md +208 -73
- package/dist/client/MedosClient.d.ts +1 -1
- package/dist/client/MedosClient.js +1 -1
- package/dist/components/AppointmentCalender.d.ts +1 -4
- package/dist/components/AppointmentCalender.js +282 -486
- package/dist/components/AppointmentDateTimeModal.d.ts +14 -0
- package/dist/components/AppointmentDateTimeModal.js +206 -0
- package/dist/components/ConfigurableCard.d.ts +12 -0
- package/dist/components/ConfigurableCard.js +29 -0
- package/dist/components/DoctorSelectModal.d.ts +7 -0
- package/dist/components/DoctorSelectModal.js +80 -0
- package/dist/components/Icons/Check.d.ts +6 -0
- package/dist/components/Icons/Check.js +2 -0
- package/dist/components/Icons/ChevronDownIcon.d.ts +4 -0
- package/dist/components/Icons/ChevronDownIcon.js +2 -0
- package/dist/components/Icons/ChevronLeft.d.ts +3 -0
- package/dist/components/Icons/ChevronLeft.js +3 -0
- package/dist/components/Icons/ChevronRight.d.ts +3 -0
- package/dist/components/Icons/ChevronRight.js +3 -0
- package/dist/components/Icons/ConfirmationCheck.d.ts +1 -0
- package/dist/components/Icons/ConfirmationCheck.js +9 -0
- package/dist/components/Icons/ConsultationType.d.ts +1 -0
- package/dist/components/Icons/ConsultationType.js +2 -0
- package/dist/components/Icons/Date&TimeIcon.d.ts +1 -0
- package/dist/components/Icons/Date&TimeIcon.js +2 -0
- package/dist/components/Icons/MapIcon.d.ts +1 -0
- package/dist/components/Icons/MapIcon.js +2 -0
- package/dist/components/Icons/PaymentMethodIcon.d.ts +1 -0
- package/dist/components/Icons/PaymentMethodIcon.js +2 -0
- package/dist/components/Icons/UserIcon.d.ts +1 -0
- package/dist/components/Icons/UserIcon.js +2 -0
- package/dist/components/PatientDetailsStep.d.ts +3 -0
- package/dist/components/PatientDetailsStep.js +76 -0
- package/dist/components/PhoneVerificationStep.d.ts +3 -0
- package/dist/components/PhoneVerificationStep.js +39 -0
- package/dist/components/SuccessStep.d.ts +3 -0
- package/dist/components/SuccessStep.js +17 -0
- package/dist/components/custom-calendar.d.ts +5 -0
- package/dist/components/custom-calendar.js +153 -0
- package/dist/components/styles.d.ts +6 -0
- package/dist/components/styles.js +257 -0
- package/dist/components/types.d.ts +182 -0
- package/dist/components/types.js +55 -0
- package/dist/components/ui/select.d.ts +10 -0
- package/dist/components/ui/select.js +21 -0
- package/dist/components/uiComponents/SelectDropdown.d.ts +41 -0
- package/dist/components/uiComponents/SelectDropdown.js +302 -0
- package/dist/components/utils.d.ts +5 -0
- package/dist/components/utils.js +15 -0
- package/dist/components/validation.d.ts +2 -0
- package/dist/components/validation.js +7 -0
- package/dist/context/TemplateContext.d.ts +12 -0
- package/dist/context/TemplateContext.js +19 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/lib/templateUtils.d.ts +3 -0
- package/dist/lib/templateUtils.js +28 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/services/AppointmentService.d.ts +9 -10
- package/dist/services/AppointmentService.js +12 -10
- package/dist/templates/registry.d.ts +12 -0
- package/dist/templates/registry.js +58 -0
- package/dist/vanilla/AppointmentCalendarWidget.d.ts +41 -0
- package/dist/vanilla/AppointmentCalendarWidget.js +848 -0
- package/dist/vanilla/appointment-calendar/provider.d.ts +13 -0
- package/dist/vanilla/appointment-calendar/types.d.ts +144 -0
- package/dist/vanilla/appointments/provider.d.ts +13 -0
- package/dist/vanilla/appointments/types.d.ts +81 -0
- package/dist/vanilla/client/MedosClient.d.ts +32 -0
- package/dist/vanilla/components/AppointmentCalender.d.ts +3 -0
- package/dist/vanilla/components/AppointmentDateTimeModal.d.ts +14 -0
- package/dist/vanilla/components/ConfigurableCard.d.ts +12 -0
- package/dist/vanilla/components/DoctorSelectModal.d.ts +7 -0
- package/dist/vanilla/components/Icons/Check.d.ts +6 -0
- package/dist/vanilla/components/Icons/ChevronDownIcon.d.ts +4 -0
- package/dist/vanilla/components/Icons/ChevronLeft.d.ts +3 -0
- package/dist/vanilla/components/Icons/ChevronRight.d.ts +3 -0
- package/dist/vanilla/components/Icons/ConfirmationCheck.d.ts +1 -0
- package/dist/vanilla/components/Icons/ConsultationType.d.ts +1 -0
- package/dist/vanilla/components/Icons/Date&TimeIcon.d.ts +1 -0
- package/dist/vanilla/components/Icons/MapIcon.d.ts +1 -0
- package/dist/vanilla/components/Icons/PaymentMethodIcon.d.ts +1 -0
- package/dist/vanilla/components/Icons/UserIcon.d.ts +1 -0
- package/dist/vanilla/components/PatientDetailsStep.d.ts +3 -0
- package/dist/vanilla/components/PhoneVerificationStep.d.ts +3 -0
- package/dist/vanilla/components/SuccessStep.d.ts +3 -0
- package/dist/vanilla/components/custom-calendar.d.ts +5 -0
- package/dist/vanilla/components/styles.d.ts +6 -0
- package/dist/vanilla/components/types.d.ts +182 -0
- package/dist/vanilla/components/ui/select.d.ts +10 -0
- package/dist/vanilla/components/uiComponents/SelectDropdown.d.ts +41 -0
- package/dist/vanilla/components/utils.d.ts +5 -0
- package/dist/vanilla/components/validation.d.ts +2 -0
- package/dist/vanilla/context/TemplateContext.d.ts +12 -0
- package/dist/vanilla/core/index.d.ts +8 -0
- package/dist/vanilla/index.d.ts +7 -0
- package/dist/vanilla/index.js +2 -0
- package/dist/vanilla/lib/templateUtils.d.ts +3 -0
- package/dist/vanilla/react/index.d.ts +2 -0
- package/dist/vanilla/services/AppointmentService.d.ts +85 -0
- package/dist/vanilla/services/AuthService.d.ts +6 -0
- package/dist/vanilla/services/PatientService.d.ts +14 -0
- package/dist/vanilla/templates/alternative.css +13 -0
- package/dist/vanilla/templates/default.css +13 -0
- package/dist/vanilla/templates/registry.d.ts +12 -0
- package/dist/vanilla/vanilla/AppointmentCalendarWidget.d.ts +41 -0
- package/dist/vanilla/vanilla/index.d.ts +2 -0
- package/dist/vanilla/vanilla/widget.d.ts +10 -0
- package/dist/vanilla/widget.css +217 -0
- package/dist/vanilla/widget.d.ts +10 -0
- package/dist/vanilla/widget.js +5084 -0
- package/package.json +40 -5
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const Select = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
4
|
+
return (_jsx("select", { ref: ref, className: className, style: {
|
|
5
|
+
width: "100%",
|
|
6
|
+
padding: "8px 12px",
|
|
7
|
+
borderRadius: "6px",
|
|
8
|
+
border: "1px solid var(--medos-border-color, #e6e9ef)",
|
|
9
|
+
fontSize: "14px",
|
|
10
|
+
cursor: "pointer",
|
|
11
|
+
backgroundColor: "#fff",
|
|
12
|
+
fontFamily: "inherit",
|
|
13
|
+
...props.style,
|
|
14
|
+
}, ...props, children: children }));
|
|
15
|
+
});
|
|
16
|
+
Select.displayName = "Select";
|
|
17
|
+
const SelectOption = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
18
|
+
return (_jsx("option", { ref: ref, className: className, ...props, children: children }));
|
|
19
|
+
});
|
|
20
|
+
SelectOption.displayName = "SelectOption";
|
|
21
|
+
export { Select, SelectOption };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
interface SelectProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
value?: string;
|
|
5
|
+
onValueChange?: (value: string) => void;
|
|
6
|
+
defaultValue?: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface SelectTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
error?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface SelectValueProps {
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
}
|
|
17
|
+
interface SelectContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
interface SelectItemProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
value: string;
|
|
24
|
+
className?: string;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface BaseComponentProps {
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
declare const Select: React.FC<SelectProps>;
|
|
32
|
+
declare const SelectTrigger: React.ForwardRefExoticComponent<SelectTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
33
|
+
declare const SelectValue: React.FC<SelectValueProps>;
|
|
34
|
+
declare const SelectContent: React.ForwardRefExoticComponent<SelectContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
35
|
+
declare const SelectItem: React.ForwardRefExoticComponent<SelectItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
36
|
+
declare const SelectGroup: React.FC<BaseComponentProps>;
|
|
37
|
+
declare const SelectLabel: React.FC<BaseComponentProps>;
|
|
38
|
+
declare const SelectSeparator: React.FC<{
|
|
39
|
+
className?: string;
|
|
40
|
+
}>;
|
|
41
|
+
export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, };
|
|
@@ -0,0 +1,302 @@
|
|
|
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';
|
|
5
|
+
const cn = (...classes) => {
|
|
6
|
+
return classes.filter(Boolean).join(' ');
|
|
7
|
+
};
|
|
8
|
+
if (typeof document !== 'undefined') {
|
|
9
|
+
const styleId = 'custom-select-styles';
|
|
10
|
+
if (!document.getElementById(styleId)) {
|
|
11
|
+
const styleElement = document.createElement('style');
|
|
12
|
+
styleElement.id = styleId;
|
|
13
|
+
styleElement.innerHTML = `
|
|
14
|
+
/* Container */
|
|
15
|
+
.select-container {
|
|
16
|
+
position: relative;
|
|
17
|
+
display: inline-block;
|
|
18
|
+
width: 100%;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Trigger Button */
|
|
22
|
+
.select-trigger {
|
|
23
|
+
display: flex;
|
|
24
|
+
height: 40px;
|
|
25
|
+
width: 100%;
|
|
26
|
+
align-items: center;
|
|
27
|
+
justify-content: space-between;
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
border-radius: 6px;
|
|
30
|
+
border: 1px solid #e2e8f0;
|
|
31
|
+
background-color: #fff;
|
|
32
|
+
padding: 8px 12px;
|
|
33
|
+
font-size: 14px;
|
|
34
|
+
line-height: 1.5;
|
|
35
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
36
|
+
transition: all 0.15s ease-in-out;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
outline: none;
|
|
39
|
+
font-family: inherit;
|
|
40
|
+
text-align: left;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.select-trigger:hover:not(:disabled) {
|
|
44
|
+
background-color: #f8fafc;
|
|
45
|
+
border-color: #cbd5e1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.select-trigger:focus:not(:disabled) {
|
|
49
|
+
border-color: #94a3b8;
|
|
50
|
+
box-shadow: 0 0 0 2px rgba(148, 163, 184, 0.2);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.select-trigger:disabled {
|
|
54
|
+
cursor: not-allowed;
|
|
55
|
+
opacity: 0.5;
|
|
56
|
+
background-color: #f9fafb;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.select-trigger-error {
|
|
60
|
+
border-color: #ef4444;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.select-trigger-error:focus {
|
|
64
|
+
border-color: #ef4444;
|
|
65
|
+
box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Select Value */
|
|
69
|
+
.select-value {
|
|
70
|
+
flex: 1;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
text-overflow: ellipsis;
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
color: #1e293b;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.select-placeholder {
|
|
78
|
+
color: #94a3b8;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Select Icon */
|
|
82
|
+
.select-icon {
|
|
83
|
+
height: 16px;
|
|
84
|
+
width: 16px;
|
|
85
|
+
opacity: 0.5;
|
|
86
|
+
flex-shrink: 0;
|
|
87
|
+
margin-left: 8px;
|
|
88
|
+
transition: transform 0.2s;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.select-trigger[aria-expanded="true"] .select-icon {
|
|
92
|
+
transform: rotate(180deg);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.select-icon-error {
|
|
96
|
+
color: #ef4444;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Content Dropdown */
|
|
100
|
+
.select-content {
|
|
101
|
+
position: absolute;
|
|
102
|
+
top: 100%;
|
|
103
|
+
left: 0;
|
|
104
|
+
right: 0;
|
|
105
|
+
z-index: 1050;
|
|
106
|
+
margin-top: 4px;
|
|
107
|
+
overflow: hidden;
|
|
108
|
+
border-radius: 6px;
|
|
109
|
+
border: 1px solid #e2e8f0;
|
|
110
|
+
background-color: #ffffff;
|
|
111
|
+
color: #1e293b;
|
|
112
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
113
|
+
animation: select-show 0.15s ease-out;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@keyframes select-show {
|
|
117
|
+
from {
|
|
118
|
+
opacity: 0;
|
|
119
|
+
transform: translateY(-4px);
|
|
120
|
+
}
|
|
121
|
+
to {
|
|
122
|
+
opacity: 1;
|
|
123
|
+
transform: translateY(0);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Viewport */
|
|
128
|
+
.select-viewport {
|
|
129
|
+
padding: 4px;
|
|
130
|
+
max-height: 256px;
|
|
131
|
+
overflow-y: auto;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Select Item */
|
|
135
|
+
.select-item {
|
|
136
|
+
position: relative;
|
|
137
|
+
display: flex;
|
|
138
|
+
width: 100%;
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
user-select: none;
|
|
141
|
+
align-items: center;
|
|
142
|
+
border-radius: 4px;
|
|
143
|
+
padding: 8px 8px 8px 32px;
|
|
144
|
+
font-size: 14px;
|
|
145
|
+
outline: none;
|
|
146
|
+
transition: background-color 0.1s ease;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.select-item:hover:not(.select-item-disabled) {
|
|
150
|
+
background-color: #f1f5f9;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.select-item:focus {
|
|
154
|
+
background-color: #f1f5f9;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.select-item-selected {
|
|
158
|
+
background-color: #f3f4f6;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.select-item-disabled {
|
|
162
|
+
pointer-events: none;
|
|
163
|
+
opacity: 0.5;
|
|
164
|
+
cursor: not-allowed;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Item Indicator */
|
|
168
|
+
.select-item-indicator {
|
|
169
|
+
position: absolute;
|
|
170
|
+
left: 8px;
|
|
171
|
+
display: flex;
|
|
172
|
+
height: 14px;
|
|
173
|
+
width: 14px;
|
|
174
|
+
align-items: center;
|
|
175
|
+
justify-content: center;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Item Text */
|
|
179
|
+
.select-item-text {
|
|
180
|
+
flex: 1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Select Group */
|
|
184
|
+
.select-group {
|
|
185
|
+
padding: 2px 0;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Select Label */
|
|
189
|
+
.select-label {
|
|
190
|
+
padding: 8px 8px 6px;
|
|
191
|
+
font-size: 12px;
|
|
192
|
+
font-weight: 600;
|
|
193
|
+
color: #64748b;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* Select Separator */
|
|
197
|
+
.select-separator {
|
|
198
|
+
margin: 4px 0;
|
|
199
|
+
height: 1px;
|
|
200
|
+
background-color: #e2e8f0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Scrollbar styling */
|
|
204
|
+
.select-viewport::-webkit-scrollbar {
|
|
205
|
+
width: 8px;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.select-viewport::-webkit-scrollbar-track {
|
|
209
|
+
background: #f1f5f9;
|
|
210
|
+
border-radius: 4px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.select-viewport::-webkit-scrollbar-thumb {
|
|
214
|
+
background: #cbd5e1;
|
|
215
|
+
border-radius: 4px;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.select-viewport::-webkit-scrollbar-thumb:hover {
|
|
219
|
+
background: #94a3b8;
|
|
220
|
+
}
|
|
221
|
+
`;
|
|
222
|
+
document.head.appendChild(styleElement);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const SelectContext = React.createContext(undefined);
|
|
226
|
+
const useSelectContext = () => {
|
|
227
|
+
const context = React.useContext(SelectContext);
|
|
228
|
+
if (!context) {
|
|
229
|
+
throw new Error('Select components must be used within a Select');
|
|
230
|
+
}
|
|
231
|
+
return context;
|
|
232
|
+
};
|
|
233
|
+
const Select = ({ children, value, onValueChange, defaultValue, disabled = false }) => {
|
|
234
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
235
|
+
const [selectedValue, setSelectedValue] = React.useState(value || defaultValue || '');
|
|
236
|
+
const [selectedLabel, setSelectedLabel] = React.useState('');
|
|
237
|
+
const triggerRef = React.useRef(null);
|
|
238
|
+
const contentRef = React.useRef(null);
|
|
239
|
+
React.useEffect(() => {
|
|
240
|
+
if (value !== undefined) {
|
|
241
|
+
setSelectedValue(value);
|
|
242
|
+
}
|
|
243
|
+
}, [value]);
|
|
244
|
+
React.useEffect(() => {
|
|
245
|
+
const handleClickOutside = (event) => {
|
|
246
|
+
if (triggerRef.current &&
|
|
247
|
+
contentRef.current &&
|
|
248
|
+
!triggerRef.current.contains(event.target) &&
|
|
249
|
+
!contentRef.current.contains(event.target)) {
|
|
250
|
+
setIsOpen(false);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
if (isOpen) {
|
|
254
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
255
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
256
|
+
}
|
|
257
|
+
}, [isOpen]);
|
|
258
|
+
const handleSelect = (value, label) => {
|
|
259
|
+
setSelectedValue(value);
|
|
260
|
+
setSelectedLabel(label);
|
|
261
|
+
if (onValueChange) {
|
|
262
|
+
onValueChange(value);
|
|
263
|
+
}
|
|
264
|
+
setIsOpen(false);
|
|
265
|
+
};
|
|
266
|
+
return (_jsx(SelectContext.Provider, { value: {
|
|
267
|
+
isOpen,
|
|
268
|
+
setIsOpen,
|
|
269
|
+
selectedValue,
|
|
270
|
+
selectedLabel,
|
|
271
|
+
handleSelect,
|
|
272
|
+
triggerRef,
|
|
273
|
+
contentRef,
|
|
274
|
+
disabled,
|
|
275
|
+
}, children: _jsx("div", { className: "select-container", children: children }) }));
|
|
276
|
+
};
|
|
277
|
+
const SelectTrigger = React.forwardRef(({ children, className, error = false, ...props }, ref) => {
|
|
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') })] }));
|
|
280
|
+
});
|
|
281
|
+
SelectTrigger.displayName = 'SelectTrigger';
|
|
282
|
+
const SelectValue = ({ placeholder = 'Select...' }) => {
|
|
283
|
+
const { selectedLabel, selectedValue } = useSelectContext();
|
|
284
|
+
return (_jsx("span", { className: cn('select-value', !selectedValue && 'select-placeholder'), children: selectedLabel || placeholder }));
|
|
285
|
+
};
|
|
286
|
+
const SelectContent = React.forwardRef(({ children, className, ...props }, ref) => {
|
|
287
|
+
const { isOpen, contentRef } = useSelectContext();
|
|
288
|
+
if (!isOpen)
|
|
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 }) }));
|
|
291
|
+
});
|
|
292
|
+
SelectContent.displayName = 'SelectContent';
|
|
293
|
+
const SelectItem = React.forwardRef(({ children, value, className, disabled = false, ...props }, ref) => {
|
|
294
|
+
const { selectedValue, handleSelect } = useSelectContext();
|
|
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 })] }));
|
|
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) }));
|
|
302
|
+
export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const formatDateToISO = (date) => {
|
|
2
|
+
const year = String(date.getFullYear()).padStart(4, "0");
|
|
3
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
4
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
5
|
+
return `${year}-${month}-${day}`;
|
|
6
|
+
};
|
|
7
|
+
export const parsePatientName = (fullName) => {
|
|
8
|
+
const nameParts = fullName.trim().split(/\s+/);
|
|
9
|
+
const firstName = nameParts[0] || "Patient";
|
|
10
|
+
const lastName = nameParts.slice(1).join(" ") || "";
|
|
11
|
+
return {
|
|
12
|
+
firstName,
|
|
13
|
+
lastName,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import type { TemplateId } from "../core";
|
|
3
|
+
interface TemplateContextType {
|
|
4
|
+
templateId: TemplateId;
|
|
5
|
+
}
|
|
6
|
+
export interface TemplateProviderProps {
|
|
7
|
+
templateId: TemplateId;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare const TemplateProvider: React.FC<TemplateProviderProps>;
|
|
11
|
+
export declare const useTemplate: () => TemplateContextType;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { createContext, useContext, useEffect } from "react";
|
|
3
|
+
import { injectTemplateStyles, removeTemplateStyles, } from "../lib/templateUtils";
|
|
4
|
+
const TemplateContext = createContext(null);
|
|
5
|
+
export const TemplateProvider = ({ templateId, children, }) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
injectTemplateStyles(templateId);
|
|
8
|
+
return () => removeTemplateStyles();
|
|
9
|
+
}, [templateId]);
|
|
10
|
+
const contextValue = React.useMemo(() => ({ templateId }), [templateId]);
|
|
11
|
+
return (_jsx(TemplateContext.Provider, { value: contextValue, children: _jsx("div", { className: "medos-sdk-container", children: children }) }));
|
|
12
|
+
};
|
|
13
|
+
export const useTemplate = () => {
|
|
14
|
+
const context = useContext(TemplateContext);
|
|
15
|
+
if (!context) {
|
|
16
|
+
return { templateId: "default" };
|
|
17
|
+
}
|
|
18
|
+
return context;
|
|
19
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { MedosClient } from "../client/MedosClient";
|
|
2
|
+
export * from "../appointments/provider";
|
|
3
|
+
export * from "../appointments/types";
|
|
4
|
+
export * from "../appointment-calendar/provider";
|
|
5
|
+
export * from "../appointment-calendar/types";
|
|
6
|
+
export { PatientService, SendPhoneVerificationOtpPayload, VerifyPhoneVerificationOtpPayload, } from "../services/PatientService";
|
|
7
|
+
export { AppointmentService, type BookAppointmentPayload, type PatientPayload, type PatientAddressPayload, type AddressesResponse, type AddressItem, } from "../services/AppointmentService";
|
|
8
|
+
export { AuthService } from "../services/AuthService";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { MedosClient } from "../client/MedosClient";
|
|
2
|
+
export * from "../appointments/provider";
|
|
3
|
+
export * from "../appointments/types";
|
|
4
|
+
export * from "../appointment-calendar/provider";
|
|
5
|
+
export * from "../appointment-calendar/types";
|
|
6
|
+
export { PatientService, } from "../services/PatientService";
|
|
7
|
+
export { AppointmentService, } from "../services/AppointmentService";
|
|
8
|
+
export { AuthService } from "../services/AuthService";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { templateRegistry } from "../core";
|
|
2
|
+
export function injectTemplateStyles(templateId) {
|
|
3
|
+
const existing = document.getElementById("medos-template-styles");
|
|
4
|
+
if (existing)
|
|
5
|
+
existing.remove();
|
|
6
|
+
const template = templateRegistry.getTemplate(templateId);
|
|
7
|
+
const style = document.createElement("style");
|
|
8
|
+
style.id = "medos-template-styles";
|
|
9
|
+
style.textContent = `
|
|
10
|
+
.medos-appointment-container {
|
|
11
|
+
--medos-primary-color: ${template.primaryColor} !important;
|
|
12
|
+
--medos-secondary-color: ${template.secondaryColor} !important;
|
|
13
|
+
--medos-accent-color: ${template.accentColor} !important;
|
|
14
|
+
--medos-background-color: ${template.backgroundColor} !important;
|
|
15
|
+
--medos-text-color: ${template.textColor} !important;
|
|
16
|
+
--medos-border-color: ${template.borderColor} !important;
|
|
17
|
+
--medos-muted-text: ${template.mutedText} !important;
|
|
18
|
+
--medos-success-color: ${template.successColor} !important;
|
|
19
|
+
--medos-error-color: ${template.errorColor} !important;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
document.head.appendChild(style);
|
|
23
|
+
}
|
|
24
|
+
export function removeTemplateStyles() {
|
|
25
|
+
const existing = document.getElementById("medos-template-styles");
|
|
26
|
+
if (existing)
|
|
27
|
+
existing.remove();
|
|
28
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type Doctor = {
|
|
2
|
-
id:
|
|
2
|
+
id: number;
|
|
3
3
|
name: string;
|
|
4
4
|
specialty?: string;
|
|
5
5
|
[key: string]: any;
|
|
@@ -20,11 +20,11 @@ type PatientPayload = {
|
|
|
20
20
|
gender?: "MALE" | "FEMALE" | "OTHER";
|
|
21
21
|
};
|
|
22
22
|
type PatientAddressPayload = {
|
|
23
|
-
addressLine1
|
|
24
|
-
city
|
|
25
|
-
state
|
|
26
|
-
country
|
|
27
|
-
zipcode
|
|
23
|
+
addressLine1: string;
|
|
24
|
+
city: string;
|
|
25
|
+
state: string;
|
|
26
|
+
country: string;
|
|
27
|
+
zipcode: string;
|
|
28
28
|
landmark?: string;
|
|
29
29
|
};
|
|
30
30
|
type BookAppointmentPayload = {
|
|
@@ -58,7 +58,7 @@ type AppointmentPayload = {
|
|
|
58
58
|
attachments?: File[];
|
|
59
59
|
};
|
|
60
60
|
type AddressItem = {
|
|
61
|
-
id: number
|
|
61
|
+
id: number;
|
|
62
62
|
completeAddress?: string;
|
|
63
63
|
label?: string;
|
|
64
64
|
address?: string;
|
|
@@ -67,7 +67,6 @@ type AddressItem = {
|
|
|
67
67
|
doctorsCount?: number;
|
|
68
68
|
totalConfiguredAppointments?: number;
|
|
69
69
|
doctors?: Doctor[];
|
|
70
|
-
[key: string]: any;
|
|
71
70
|
};
|
|
72
71
|
type AddressesResponse = {
|
|
73
72
|
totalAddresses?: number;
|
|
@@ -75,12 +74,12 @@ type AddressesResponse = {
|
|
|
75
74
|
totalConfiguredAppointments?: number;
|
|
76
75
|
totalPartialConfiguredAppointments?: number;
|
|
77
76
|
totalNotConfiguredAppointments?: number;
|
|
78
|
-
workspaceId?: number
|
|
77
|
+
workspaceId?: number;
|
|
79
78
|
addresses: AddressItem[];
|
|
80
79
|
};
|
|
81
80
|
declare const AppointmentService: {
|
|
82
81
|
getAddresses(): Promise<AddressesResponse>;
|
|
83
|
-
fetchSlots(workspaceId:
|
|
82
|
+
fetchSlots(workspaceId: number, addressId: number, doctorId: number, appointmentDate: string): Promise<Slot[]>;
|
|
84
83
|
createAppointment(payload: BookAppointmentPayload): Promise<any>;
|
|
85
84
|
};
|
|
86
85
|
export { AppointmentService, AppointmentPayload, BookAppointmentPayload, PatientPayload, PatientAddressPayload, AddressesResponse, AddressItem, };
|
|
@@ -10,18 +10,19 @@ const AppointmentService = {
|
|
|
10
10
|
.map((ad) => {
|
|
11
11
|
const addr = ad.address;
|
|
12
12
|
const doctors = (ad.doctors || []).map((d) => ({
|
|
13
|
-
id:
|
|
14
|
-
name: `${d.firstName || ""} ${d.lastName || ""}`.trim() ||
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
id: Number(d.user.id),
|
|
14
|
+
name: `${d.user.firstName || ""} ${d.user.lastName || ""}`.trim() ||
|
|
15
|
+
"Doctor",
|
|
16
|
+
email: d.user.email,
|
|
17
|
+
gender: d.user.gender,
|
|
18
|
+
countryCode: d.user.countryCode,
|
|
19
|
+
phoneNumber: d.user.phoneNumber,
|
|
20
|
+
dob: d.user.dob,
|
|
21
|
+
platform: d.user.platform,
|
|
22
|
+
isKycCompleted: d.user.isKycCompleted,
|
|
22
23
|
}));
|
|
23
24
|
return {
|
|
24
|
-
id:
|
|
25
|
+
id: Number(addr.id),
|
|
25
26
|
completeAddress: addr.completeAddress,
|
|
26
27
|
addressLine1: addr.addressLine1,
|
|
27
28
|
addressLine2: addr.addressLine2,
|
|
@@ -47,6 +48,7 @@ const AppointmentService = {
|
|
|
47
48
|
},
|
|
48
49
|
async fetchSlots(workspaceId, addressId, doctorId, appointmentDate) {
|
|
49
50
|
const client = await MedosClient.ensureInitialized();
|
|
51
|
+
console.log("fetching slots", workspaceId, addressId, doctorId, appointmentDate);
|
|
50
52
|
const res = await client.get(`/appointments/available-slots`, {
|
|
51
53
|
params: {
|
|
52
54
|
workspaceId,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TemplateId, TemplateConfig } from "../core";
|
|
2
|
+
export declare class TemplateRegistry {
|
|
3
|
+
private static instance;
|
|
4
|
+
private readonly templates;
|
|
5
|
+
private constructor();
|
|
6
|
+
static getInstance(): TemplateRegistry;
|
|
7
|
+
getTemplate(id: TemplateId): TemplateConfig;
|
|
8
|
+
getAllTemplates(): Record<TemplateId, TemplateConfig>;
|
|
9
|
+
hasTemplate(id: TemplateId): boolean;
|
|
10
|
+
private initializeTemplates;
|
|
11
|
+
}
|
|
12
|
+
export declare const templateRegistry: TemplateRegistry;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export class TemplateRegistry {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.templates = new Map();
|
|
4
|
+
this.initializeTemplates();
|
|
5
|
+
}
|
|
6
|
+
static getInstance() {
|
|
7
|
+
if (!TemplateRegistry.instance) {
|
|
8
|
+
TemplateRegistry.instance = new TemplateRegistry();
|
|
9
|
+
}
|
|
10
|
+
return TemplateRegistry.instance;
|
|
11
|
+
}
|
|
12
|
+
getTemplate(id) {
|
|
13
|
+
const template = this.templates.get(id);
|
|
14
|
+
if (!template) {
|
|
15
|
+
return this.templates.get("default");
|
|
16
|
+
}
|
|
17
|
+
return template;
|
|
18
|
+
}
|
|
19
|
+
getAllTemplates() {
|
|
20
|
+
const result = {};
|
|
21
|
+
for (const [id, template] of this.templates) {
|
|
22
|
+
result[id] = template;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
hasTemplate(id) {
|
|
27
|
+
return this.templates.has(id);
|
|
28
|
+
}
|
|
29
|
+
initializeTemplates() {
|
|
30
|
+
this.templates.set("default", {
|
|
31
|
+
id: "default",
|
|
32
|
+
name: "Default Blue",
|
|
33
|
+
primaryColor: "#0b79f7",
|
|
34
|
+
secondaryColor: "#eef2ff",
|
|
35
|
+
accentColor: "#0b79f7",
|
|
36
|
+
backgroundColor: "#f6f8fa",
|
|
37
|
+
textColor: "#333",
|
|
38
|
+
borderColor: "#e6e9ef",
|
|
39
|
+
mutedText: "#6b7280",
|
|
40
|
+
successColor: "#10b981",
|
|
41
|
+
errorColor: "#ef4444",
|
|
42
|
+
});
|
|
43
|
+
this.templates.set("alternative", {
|
|
44
|
+
id: "alternative",
|
|
45
|
+
name: "Alternative Green",
|
|
46
|
+
primaryColor: "#10b981",
|
|
47
|
+
secondaryColor: "#d1fae5",
|
|
48
|
+
accentColor: "#059669",
|
|
49
|
+
backgroundColor: "#f0fdf4",
|
|
50
|
+
textColor: "#1f2937",
|
|
51
|
+
borderColor: "#d1d5db",
|
|
52
|
+
mutedText: "#6b7280",
|
|
53
|
+
successColor: "#059669",
|
|
54
|
+
errorColor: "#dc2626",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const templateRegistry = TemplateRegistry.getInstance();
|