medos-sdk 1.0.0 → 1.0.2
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 +562 -9
- package/dist/components/AppointmentCalender.js +56 -10
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/services/AppointmentService.d.ts +7 -7
- package/dist/services/AppointmentService.js +12 -11
- package/dist/vanilla/AppointmentCalendarWidget.d.ts +73 -0
- package/dist/vanilla/AppointmentCalendarWidget.js +857 -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 +6 -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/react/index.d.ts +2 -0
- package/dist/vanilla/services/AppointmentService.d.ts +86 -0
- package/dist/vanilla/services/AuthService.d.ts +6 -0
- package/dist/vanilla/services/PatientService.d.ts +14 -0
- package/dist/vanilla/vanilla/AppointmentCalendarWidget.d.ts +73 -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 +5036 -0
- package/package.json +42 -6
package/README.md
CHANGED
|
@@ -1,15 +1,568 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Medos SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A JavaScript/TypeScript SDK for integrating healthcare appointment booking into your applications. Built for clinics, hospitals, and healthcare platforms.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `npm link`
|
|
5
|
+
## Installation
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install medos-sdk
|
|
9
|
+
```
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
- `npm link medos-sdk-js`
|
|
11
|
+
## Getting Started
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Authentication
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The SDK supports two authentication methods:
|
|
16
|
+
|
|
17
|
+
#### Server-Side (API Key)
|
|
18
|
+
|
|
19
|
+
Use this method for backend services and server-side rendering.
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import { MedosClient } from "medos-sdk";
|
|
23
|
+
|
|
24
|
+
await MedosClient.init({
|
|
25
|
+
apiKey: "your-api-key",
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### Client-Side (Session Token)
|
|
30
|
+
|
|
31
|
+
Use this method for frontend applications. Obtain the session token from your backend.
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { MedosClient } from "medos-sdk";
|
|
35
|
+
|
|
36
|
+
await MedosClient.initWithSession({
|
|
37
|
+
sessionToken: "user-session-token",
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Fetch Clinic Addresses and Doctors
|
|
44
|
+
|
|
45
|
+
Retrieve all available clinic locations with their associated doctors.
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
const result = await MedosClient.fetchAllAddressesAndDoctors();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Response:**
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
{
|
|
55
|
+
totalAddresses: 5,
|
|
56
|
+
totalDoctors: 12,
|
|
57
|
+
workspaceId: "workspace-123",
|
|
58
|
+
addresses: [
|
|
59
|
+
{
|
|
60
|
+
id: "addr-1",
|
|
61
|
+
completeAddress: "123 Medical Center, New York, NY 10001",
|
|
62
|
+
addressLine1: "123 Medical Center",
|
|
63
|
+
city: "New York",
|
|
64
|
+
state: "NY",
|
|
65
|
+
country: "USA",
|
|
66
|
+
zipcode: "10001",
|
|
67
|
+
doctors: [
|
|
68
|
+
{
|
|
69
|
+
id: "doc-1",
|
|
70
|
+
name: "Dr. John Smith",
|
|
71
|
+
email: "john.smith@example.com",
|
|
72
|
+
specialty: "Cardiology"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Fetch Available Slots
|
|
81
|
+
|
|
82
|
+
Get available appointment time slots for a specific doctor.
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
const slots = await MedosClient.fetchAppointments(
|
|
86
|
+
"workspace-123", // workspaceId
|
|
87
|
+
"addr-1", // addressId
|
|
88
|
+
"doc-1", // doctorId
|
|
89
|
+
"2025-11-16" // appointmentDate (YYYY-MM-DD)
|
|
90
|
+
);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Response:**
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
[
|
|
97
|
+
{
|
|
98
|
+
start: "2025-11-16T10:00:00",
|
|
99
|
+
end: "2025-11-16T10:30:00",
|
|
100
|
+
id: "slot-1",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
start: "2025-11-16T11:00:00",
|
|
104
|
+
end: "2025-11-16T11:30:00",
|
|
105
|
+
id: "slot-2",
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Book an Appointment
|
|
111
|
+
|
|
112
|
+
Create a new appointment booking.
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
import { AppointmentService } from "medos-sdk";
|
|
116
|
+
|
|
117
|
+
const appointment = await AppointmentService.createAppointment({
|
|
118
|
+
workspaceAddressId: "addr-1",
|
|
119
|
+
doctorId: "doc-1",
|
|
120
|
+
mode: "OFFLINE",
|
|
121
|
+
appointmentDate: "2025-11-16",
|
|
122
|
+
fromDateTimeTs: "10:00",
|
|
123
|
+
toDateTimeTs: "10:30",
|
|
124
|
+
consultationCharge: "100",
|
|
125
|
+
type: "CONSULTATION",
|
|
126
|
+
source: "SDK_POWERED_WEBSITE",
|
|
127
|
+
patientPayload: {
|
|
128
|
+
firstName: "Jane",
|
|
129
|
+
lastName: "Doe",
|
|
130
|
+
email: "jane.doe@example.com",
|
|
131
|
+
countryCode: "+1",
|
|
132
|
+
phoneNumber: "5551234567",
|
|
133
|
+
age: 30,
|
|
134
|
+
gender: "FEMALE",
|
|
135
|
+
},
|
|
136
|
+
patientAddress: {
|
|
137
|
+
addressLine1: "456 Patient Street",
|
|
138
|
+
city: "New York",
|
|
139
|
+
state: "NY",
|
|
140
|
+
country: "USA",
|
|
141
|
+
zipcode: "10001",
|
|
142
|
+
landmark: "Near Central Park",
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Optional Fields:**
|
|
148
|
+
|
|
149
|
+
| Field | Default Value | Description |
|
|
150
|
+
| -------------------- | ----------------------- | -------------------------------------------- |
|
|
151
|
+
| `mode` | `"OFFLINE"` | Consultation mode: `"OFFLINE"` or `"ONLINE"` |
|
|
152
|
+
| `consultationCharge` | `"0"` | Consultation fee as string |
|
|
153
|
+
| `type` | `"CONSULTATION"` | Appointment type |
|
|
154
|
+
| `source` | `"SDK_POWERED_WEBSITE"` | Source identifier |
|
|
155
|
+
|
|
156
|
+
### Phone Verification
|
|
157
|
+
|
|
158
|
+
Implement OTP-based phone number verification for patients.
|
|
159
|
+
|
|
160
|
+
#### Send OTP
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
await MedosClient.sendPhoneVerificationOtp({
|
|
164
|
+
countryCode: "+1",
|
|
165
|
+
phoneNumber: "5551234567",
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Verify OTP
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
const result = await MedosClient.verifyPhoneVerificationOtp({
|
|
173
|
+
countryCode: "+1",
|
|
174
|
+
phoneNumber: "5551234567",
|
|
175
|
+
otp: "123456",
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## TypeScript
|
|
180
|
+
|
|
181
|
+
The SDK is written in TypeScript and provides comprehensive type definitions.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import {
|
|
185
|
+
MedosClient,
|
|
186
|
+
AppointmentService,
|
|
187
|
+
BookAppointmentPayload,
|
|
188
|
+
AddressesResponse,
|
|
189
|
+
PatientPayload,
|
|
190
|
+
PatientAddressPayload,
|
|
191
|
+
} from "medos-sdk";
|
|
192
|
+
|
|
193
|
+
const payload: BookAppointmentPayload = {
|
|
194
|
+
workspaceAddressId: "addr-1",
|
|
195
|
+
doctorId: "doc-1",
|
|
196
|
+
appointmentDate: "2025-11-16",
|
|
197
|
+
fromDateTimeTs: "10:00",
|
|
198
|
+
toDateTimeTs: "10:30",
|
|
199
|
+
patientPayload: {
|
|
200
|
+
firstName: "John",
|
|
201
|
+
lastName: "Doe",
|
|
202
|
+
countryCode: "+1",
|
|
203
|
+
phoneNumber: "5551234567",
|
|
204
|
+
},
|
|
205
|
+
patientAddress: {
|
|
206
|
+
addressLine1: "123 Main Street",
|
|
207
|
+
city: "New York",
|
|
208
|
+
state: "NY",
|
|
209
|
+
country: "USA",
|
|
210
|
+
zipcode: "10001",
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const appointment = await AppointmentService.createAppointment(payload);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Type Definitions
|
|
218
|
+
|
|
219
|
+
#### `BookAppointmentPayload`
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
{
|
|
223
|
+
workspaceAddressId: string | number;
|
|
224
|
+
doctorId: string | number;
|
|
225
|
+
appointmentDate: string; // Format: "YYYY-MM-DD"
|
|
226
|
+
fromDateTimeTs: string; // Format: "HH:MM"
|
|
227
|
+
toDateTimeTs: string; // Format: "HH:MM"
|
|
228
|
+
mode?: "OFFLINE" | "ONLINE"; // Default: "OFFLINE"
|
|
229
|
+
consultationCharge?: string; // Default: "0"
|
|
230
|
+
type?: "CONSULTATION" | string; // Default: "CONSULTATION"
|
|
231
|
+
source?: string; // Default: "SDK_POWERED_WEBSITE"
|
|
232
|
+
patientPayload: PatientPayload;
|
|
233
|
+
patientAddress: PatientAddressPayload; // Required
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### `PatientPayload`
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
{
|
|
241
|
+
firstName: string;
|
|
242
|
+
lastName: string;
|
|
243
|
+
countryCode: string;
|
|
244
|
+
phoneNumber: string;
|
|
245
|
+
email?: string;
|
|
246
|
+
age?: number;
|
|
247
|
+
gender?: "MALE" | "FEMALE" | "OTHER";
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### `PatientAddressPayload`
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
{
|
|
255
|
+
addressLine1?: string;
|
|
256
|
+
city?: string;
|
|
257
|
+
state?: string;
|
|
258
|
+
country?: string;
|
|
259
|
+
zipcode?: string;
|
|
260
|
+
landmark?: string;
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## React Integration
|
|
265
|
+
|
|
266
|
+
Pre-built appointment calendar component for React applications.
|
|
267
|
+
|
|
268
|
+
```jsx
|
|
269
|
+
import { AppointmentCalender } from "medos-sdk";
|
|
270
|
+
|
|
271
|
+
function BookingPage() {
|
|
272
|
+
return <AppointmentCalender />;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The component automatically uses the initialized `MedosClient` instance.
|
|
277
|
+
|
|
278
|
+
### Using React-specific exports
|
|
279
|
+
|
|
280
|
+
For better tree-shaking and to avoid React dependency conflicts:
|
|
281
|
+
|
|
282
|
+
```jsx
|
|
283
|
+
import { AppointmentCalender } from "medos-sdk/react";
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Vanilla JavaScript / HTML Integration
|
|
287
|
+
|
|
288
|
+
For websites using plain HTML, CSS, and JavaScript (no React), use the vanilla widget.
|
|
289
|
+
|
|
290
|
+
### Installation
|
|
291
|
+
|
|
292
|
+
The widget is available as a bundled UMD module. After building the package, you'll find:
|
|
293
|
+
|
|
294
|
+
- `dist/vanilla/widget.js` - JavaScript bundle
|
|
295
|
+
- `dist/vanilla/widget.css` - Stylesheet
|
|
296
|
+
|
|
297
|
+
### Basic Usage
|
|
298
|
+
|
|
299
|
+
```html
|
|
300
|
+
<!DOCTYPE html>
|
|
301
|
+
<html>
|
|
302
|
+
<head>
|
|
303
|
+
<link rel="stylesheet" href="path/to/widget.css" />
|
|
304
|
+
</head>
|
|
305
|
+
<body>
|
|
306
|
+
<div id="appointment-calendar"></div>
|
|
307
|
+
|
|
308
|
+
<script src="path/to/widget.js"></script>
|
|
309
|
+
<script>
|
|
310
|
+
window.MedosAppointmentCalendar.init({
|
|
311
|
+
containerId: "appointment-calendar",
|
|
312
|
+
apiKey: "your-api-key",
|
|
313
|
+
onError: (err) => {
|
|
314
|
+
console.error("Error:", err);
|
|
315
|
+
alert("An error occurred. Please try again.");
|
|
316
|
+
},
|
|
317
|
+
onSuccess: () => {
|
|
318
|
+
console.log("Appointment booked successfully!");
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
</script>
|
|
322
|
+
</body>
|
|
323
|
+
</html>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Using Session Token (Recommended for Production)
|
|
327
|
+
|
|
328
|
+
For better security, obtain the session token server-side:
|
|
329
|
+
|
|
330
|
+
```html
|
|
331
|
+
<script>
|
|
332
|
+
window.MedosAppointmentCalendar.init({
|
|
333
|
+
containerId: "appointment-calendar",
|
|
334
|
+
sessionToken: "your-session-token", // Obtained from your server
|
|
335
|
+
baseURL: "https://api-dev.medapi.in/v1",
|
|
336
|
+
onError: (err) => console.error(err),
|
|
337
|
+
});
|
|
338
|
+
</script>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### PHP Integration Example
|
|
342
|
+
|
|
343
|
+
```php
|
|
344
|
+
<?php
|
|
345
|
+
// Get session token from your backend
|
|
346
|
+
$sessionToken = getSessionTokenFromBackend();
|
|
347
|
+
?>
|
|
348
|
+
<!DOCTYPE html>
|
|
349
|
+
<html>
|
|
350
|
+
<head>
|
|
351
|
+
<link rel="stylesheet" href="path/to/widget.css">
|
|
352
|
+
</head>
|
|
353
|
+
<body>
|
|
354
|
+
<div id="appointment-calendar"></div>
|
|
355
|
+
<script src="path/to/widget.js"></script>
|
|
356
|
+
<script>
|
|
357
|
+
window.MedosAppointmentCalendar.init({
|
|
358
|
+
containerId: 'appointment-calendar',
|
|
359
|
+
sessionToken: '<?php echo htmlspecialchars($sessionToken); ?>',
|
|
360
|
+
onError: (err) => {
|
|
361
|
+
console.error('Error:', err);
|
|
362
|
+
alert('An error occurred. Please try again.');
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
</script>
|
|
366
|
+
</body>
|
|
367
|
+
</html>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Configuration Options
|
|
371
|
+
|
|
372
|
+
- `containerId` (string, required) - ID of the HTML element where the widget will be rendered
|
|
373
|
+
- `apiKey` (string, optional) - Your Medos API key (if not using sessionToken)
|
|
374
|
+
- `sessionToken` (string, optional) - Session token obtained from your server (if not using apiKey)
|
|
375
|
+
- `baseURL` (string, optional) - API base URL (defaults to `https://api-dev.medapi.in/v1`)
|
|
376
|
+
- `onError` (function, optional) - Callback function for error handling
|
|
377
|
+
- `onSuccess` (function, optional) - Callback function called when appointment is successfully booked
|
|
378
|
+
|
|
379
|
+
### Styling
|
|
380
|
+
|
|
381
|
+
The widget comes with default styles. You can customize them by overriding CSS classes:
|
|
382
|
+
|
|
383
|
+
```css
|
|
384
|
+
.medos-appointment-btn-primary {
|
|
385
|
+
background: #your-color;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.medos-appointment-card {
|
|
389
|
+
border-radius: 8px;
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
See `dist/vanilla/widget.css` for all available classes.
|
|
394
|
+
|
|
395
|
+
### Package Exports
|
|
396
|
+
|
|
397
|
+
The SDK provides multiple entry points:
|
|
398
|
+
|
|
399
|
+
- `medos-sdk` - Default export (includes React components)
|
|
400
|
+
- `medos-sdk/react` - React-specific exports
|
|
401
|
+
- `medos-sdk/vanilla` - Vanilla JS exports (ES modules)
|
|
402
|
+
- `medos-sdk/core` - Core services only (no framework dependencies)
|
|
403
|
+
- `medos-sdk/widget` - Widget bundle with CSS
|
|
404
|
+
|
|
405
|
+
For more details, see [Vanilla Widget Documentation](./docs/VANILLA_WIDGET.md).
|
|
406
|
+
|
|
407
|
+
## API Reference
|
|
408
|
+
|
|
409
|
+
### MedosClient
|
|
410
|
+
|
|
411
|
+
#### `init(config)`
|
|
412
|
+
|
|
413
|
+
Initialize the SDK with an API key (server-side).
|
|
414
|
+
|
|
415
|
+
**Parameters:**
|
|
416
|
+
|
|
417
|
+
- `config.apiKey` (string, required) - Your Medos API key
|
|
418
|
+
- `config.baseURL` (string, optional) - API base URL. Defaults to dev environment
|
|
419
|
+
|
|
420
|
+
**Returns:** `Promise<void>`
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
#### `initWithSession(config)`
|
|
425
|
+
|
|
426
|
+
Initialize the SDK with a session token (client-side).
|
|
427
|
+
|
|
428
|
+
**Parameters:**
|
|
429
|
+
|
|
430
|
+
- `config.sessionToken` (string, required) - Session token
|
|
431
|
+
- `config.baseURL` (string, optional) - API base URL. Defaults to dev environment
|
|
432
|
+
|
|
433
|
+
**Returns:** `Promise<void>`
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
#### `fetchAllAddressesAndDoctors()`
|
|
438
|
+
|
|
439
|
+
Fetch all clinic addresses and their associated doctors.
|
|
440
|
+
|
|
441
|
+
**Returns:** `Promise<AddressesResponse>`
|
|
442
|
+
|
|
443
|
+
**Response Type:**
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
{
|
|
447
|
+
totalAddresses?: number;
|
|
448
|
+
totalDoctors?: number;
|
|
449
|
+
workspaceId?: number | string;
|
|
450
|
+
addresses: Array<{
|
|
451
|
+
id: string;
|
|
452
|
+
completeAddress?: string;
|
|
453
|
+
addressLine1?: string;
|
|
454
|
+
city?: string;
|
|
455
|
+
state?: string;
|
|
456
|
+
country?: string;
|
|
457
|
+
zipcode?: string;
|
|
458
|
+
doctors?: Array<{
|
|
459
|
+
id: string;
|
|
460
|
+
name: string;
|
|
461
|
+
email?: string;
|
|
462
|
+
specialty?: string;
|
|
463
|
+
}>;
|
|
464
|
+
}>;
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
#### `fetchAppointments(workspaceId, addressId, doctorId, appointmentDate)`
|
|
471
|
+
|
|
472
|
+
Fetch available appointment slots for a specific doctor.
|
|
473
|
+
|
|
474
|
+
**Parameters:**
|
|
475
|
+
|
|
476
|
+
- `workspaceId` (string | number) - Workspace identifier
|
|
477
|
+
- `addressId` (string | number) - Address identifier
|
|
478
|
+
- `doctorId` (string | number) - Doctor identifier
|
|
479
|
+
- `appointmentDate` (string) - Date in YYYY-MM-DD format
|
|
480
|
+
|
|
481
|
+
**Returns:** `Promise<Slot[]>`
|
|
482
|
+
|
|
483
|
+
**Response Type:**
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
Array<{
|
|
487
|
+
start: string; // ISO datetime format
|
|
488
|
+
end: string; // ISO datetime format
|
|
489
|
+
id?: string;
|
|
490
|
+
}>;
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
#### `sendPhoneVerificationOtp(payload)`
|
|
496
|
+
|
|
497
|
+
Send OTP to a phone number for verification.
|
|
498
|
+
|
|
499
|
+
**Parameters:**
|
|
500
|
+
|
|
501
|
+
- `payload.countryCode` (string) - Country code with + prefix (e.g., "+1")
|
|
502
|
+
- `payload.phoneNumber` (string) - Phone number without country code
|
|
503
|
+
|
|
504
|
+
**Returns:** `Promise<any>`
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
#### `verifyPhoneVerificationOtp(payload)`
|
|
509
|
+
|
|
510
|
+
Verify OTP for a phone number.
|
|
511
|
+
|
|
512
|
+
**Parameters:**
|
|
513
|
+
|
|
514
|
+
- `payload.countryCode` (string) - Country code with + prefix
|
|
515
|
+
- `payload.phoneNumber` (string) - Phone number without country code
|
|
516
|
+
- `payload.otp` (string) - OTP code received
|
|
517
|
+
|
|
518
|
+
**Returns:** `Promise<any>`
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
### AppointmentService
|
|
523
|
+
|
|
524
|
+
#### `createAppointment(payload)`
|
|
525
|
+
|
|
526
|
+
Create a new appointment booking.
|
|
527
|
+
|
|
528
|
+
**Parameters:**
|
|
529
|
+
|
|
530
|
+
- `payload` (BookAppointmentPayload) - Appointment details
|
|
531
|
+
|
|
532
|
+
**Returns:** `Promise<any>`
|
|
533
|
+
|
|
534
|
+
## Error Handling
|
|
535
|
+
|
|
536
|
+
All SDK methods return Promises and should be wrapped in try-catch blocks.
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
try {
|
|
540
|
+
await MedosClient.init({ apiKey: "your-api-key" });
|
|
541
|
+
const addresses = await MedosClient.fetchAllAddressesAndDoctors();
|
|
542
|
+
} catch (error) {
|
|
543
|
+
console.error("Failed to fetch addresses:", error.message);
|
|
544
|
+
}
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
## Requirements
|
|
548
|
+
|
|
549
|
+
- **Node.js:** v14 or higher
|
|
550
|
+
- **Browsers:** Modern browsers with ES6+ support
|
|
551
|
+
- **React:** v19 or higher (only required for React components, not for vanilla widget)
|
|
552
|
+
- **TypeScript:** v5 or higher (optional)
|
|
553
|
+
|
|
554
|
+
## License
|
|
555
|
+
|
|
556
|
+
UNLICENSED
|
|
557
|
+
|
|
558
|
+
## Support
|
|
559
|
+
|
|
560
|
+
For bug reports and feature requests, please visit our [GitHub Issues](https://github.com/MediLaunch/medos-sdk-react/issues).
|
|
561
|
+
|
|
562
|
+
## Author
|
|
563
|
+
|
|
564
|
+
Pooranjoy Bhattacharya
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
_Built for healthcare providers worldwide._
|
|
@@ -18,6 +18,11 @@ export const AppointmentCalender = ({ onError, }) => {
|
|
|
18
18
|
const [patientName, setPatientName] = useState("");
|
|
19
19
|
const [patientAge, setPatientAge] = useState("");
|
|
20
20
|
const [patientAddress, setPatientAddress] = useState("");
|
|
21
|
+
const [patientCity, setPatientCity] = useState("");
|
|
22
|
+
const [patientState, setPatientState] = useState("");
|
|
23
|
+
const [patientCountry, setPatientCountry] = useState("");
|
|
24
|
+
const [patientZipcode, setPatientZipcode] = useState("");
|
|
25
|
+
const [patientLandmark, setPatientLandmark] = useState("");
|
|
21
26
|
const [patientEmail, setPatientEmail] = useState("");
|
|
22
27
|
const [patientGender, setPatientGender] = useState("");
|
|
23
28
|
const [problemFacing, setProblemFacing] = useState("");
|
|
@@ -300,8 +305,16 @@ export const AppointmentCalender = ({ onError, }) => {
|
|
|
300
305
|
};
|
|
301
306
|
const submitAppointment = async () => {
|
|
302
307
|
setError(null);
|
|
303
|
-
if (!selectedDoctor ||
|
|
304
|
-
|
|
308
|
+
if (!selectedDoctor ||
|
|
309
|
+
!selectedSlot ||
|
|
310
|
+
!workspaceId ||
|
|
311
|
+
!selectedAddress ||
|
|
312
|
+
!patientAddress ||
|
|
313
|
+
!patientCity ||
|
|
314
|
+
!patientState ||
|
|
315
|
+
!patientCountry ||
|
|
316
|
+
!patientZipcode) {
|
|
317
|
+
setError("Please ensure all required fields are complete.");
|
|
305
318
|
return;
|
|
306
319
|
}
|
|
307
320
|
if (!otpVerified) {
|
|
@@ -323,11 +336,14 @@ export const AppointmentCalender = ({ onError, }) => {
|
|
|
323
336
|
};
|
|
324
337
|
const fromDateTimeTs = formatTime(startDate);
|
|
325
338
|
const toDateTimeTs = formatTime(endDate);
|
|
326
|
-
const patientAddressPayload =
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
:
|
|
339
|
+
const patientAddressPayload = {
|
|
340
|
+
addressLine1: patientAddress,
|
|
341
|
+
city: patientCity,
|
|
342
|
+
state: patientState,
|
|
343
|
+
country: patientCountry,
|
|
344
|
+
zipcode: patientZipcode,
|
|
345
|
+
landmark: patientLandmark || undefined,
|
|
346
|
+
};
|
|
331
347
|
await AppointmentService.createAppointment({
|
|
332
348
|
workspaceId: workspaceId,
|
|
333
349
|
workspaceAddressId: selectedAddress,
|
|
@@ -536,10 +552,35 @@ export const AppointmentCalender = ({ onError, }) => {
|
|
|
536
552
|
}, children: "Change Number" }), _jsx("button", { style: {
|
|
537
553
|
...styles.primaryBtn,
|
|
538
554
|
opacity: otpCode.length === 6 ? 1 : 0.6,
|
|
539
|
-
}, disabled: otpCode.length !== 6 || otpVerifying, onClick: verifyOtp, children: otpVerifying ? "Verifying..." : "Verify OTP" })] })] })) }))] })), step === 4 && (_jsxs("div", { style: styles.section, children: [_jsx("label", { style: styles.label, children: "Patient Name" }), _jsx("input", { style: styles.input, placeholder: "Full name", value: patientName, onChange: (e) => setPatientName(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Age" }), _jsx("input", { style: styles.input, type: "number", placeholder: "Age", value: patientAge, onChange: (e) => setPatientAge(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Email (Optional)" }), _jsx("input", { style: styles.input, type: "email", placeholder: "patient@example.com", value: patientEmail, onChange: (e) => setPatientEmail(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Gender (Optional)" }), _jsxs("select", { style: styles.select, value: patientGender, onChange: (e) => setPatientGender(e.target.value), children: [_jsx("option", { value: "", children: "-- Select Gender --" }), _jsx("option", { value: "MALE", children: "Male" }), _jsx("option", { value: "FEMALE", children: "Female" }), _jsx("option", { value: "OTHER", children: "Other" })] }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Address" }), _jsx("
|
|
555
|
+
}, disabled: otpCode.length !== 6 || otpVerifying, onClick: verifyOtp, children: otpVerifying ? "Verifying..." : "Verify OTP" })] })] })) }))] })), step === 4 && (_jsxs("div", { style: styles.section, children: [_jsx("label", { style: styles.label, children: "Patient Name" }), _jsx("input", { style: styles.input, placeholder: "Full name", value: patientName, onChange: (e) => setPatientName(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Age" }), _jsx("input", { style: styles.input, type: "number", placeholder: "Age", value: patientAge, onChange: (e) => setPatientAge(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Email (Optional)" }), _jsx("input", { style: styles.input, type: "email", placeholder: "patient@example.com", value: patientEmail, onChange: (e) => setPatientEmail(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Gender (Optional)" }), _jsxs("select", { style: styles.select, value: patientGender, onChange: (e) => setPatientGender(e.target.value), children: [_jsx("option", { value: "", children: "-- Select Gender --" }), _jsx("option", { value: "MALE", children: "Male" }), _jsx("option", { value: "FEMALE", children: "Female" }), _jsx("option", { value: "OTHER", children: "Other" })] }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Address Line 1 *" }), _jsx("input", { style: styles.input, placeholder: "Street address, building name, etc.", value: patientAddress, onChange: (e) => setPatientAddress(e.target.value) }), _jsxs("div", { style: {
|
|
556
|
+
display: "grid",
|
|
557
|
+
gridTemplateColumns: "1fr 1fr",
|
|
558
|
+
gap: 12,
|
|
559
|
+
marginTop: 12,
|
|
560
|
+
}, children: [_jsxs("div", { children: [_jsx("label", { style: styles.label, children: "City *" }), _jsx("input", { style: styles.input, placeholder: "City", value: patientCity, onChange: (e) => setPatientCity(e.target.value) })] }), _jsxs("div", { children: [_jsx("label", { style: styles.label, children: "State *" }), _jsx("input", { style: styles.input, placeholder: "State", value: patientState, onChange: (e) => setPatientState(e.target.value) })] })] }), _jsxs("div", { style: {
|
|
561
|
+
display: "grid",
|
|
562
|
+
gridTemplateColumns: "1fr 1fr",
|
|
563
|
+
gap: 12,
|
|
564
|
+
marginTop: 12,
|
|
565
|
+
}, children: [_jsxs("div", { children: [_jsx("label", { style: styles.label, children: "Country *" }), _jsx("input", { style: styles.input, placeholder: "Country", value: patientCountry, onChange: (e) => setPatientCountry(e.target.value) })] }), _jsxs("div", { children: [_jsx("label", { style: styles.label, children: "Zipcode *" }), _jsx("input", { style: styles.input, placeholder: "Zipcode", value: patientZipcode, onChange: (e) => setPatientZipcode(e.target.value) })] })] }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Landmark (Optional)" }), _jsx("input", { style: styles.input, placeholder: "Nearby landmark", value: patientLandmark, onChange: (e) => setPatientLandmark(e.target.value) }), _jsx("label", { style: { ...styles.label, marginTop: 12 }, children: "Problem Facing" }), _jsx("textarea", { style: { ...styles.input, minHeight: 80, resize: "vertical" }, placeholder: "Describe the problem you're facing", value: problemFacing, onChange: (e) => setProblemFacing(e.target.value) }), _jsxs("div", { style: styles.actions, children: [_jsx("button", { style: styles.secondaryBtn, onClick: goBack, children: "Back" }), _jsx("button", { style: {
|
|
540
566
|
...styles.primaryBtn,
|
|
541
|
-
opacity: patientName &&
|
|
542
|
-
|
|
567
|
+
opacity: patientName &&
|
|
568
|
+
patientAddress &&
|
|
569
|
+
patientCity &&
|
|
570
|
+
patientState &&
|
|
571
|
+
patientCountry &&
|
|
572
|
+
patientZipcode &&
|
|
573
|
+
otpVerified
|
|
574
|
+
? 1
|
|
575
|
+
: 0.6,
|
|
576
|
+
}, disabled: !patientName ||
|
|
577
|
+
!patientAddress ||
|
|
578
|
+
!patientCity ||
|
|
579
|
+
!patientState ||
|
|
580
|
+
!patientCountry ||
|
|
581
|
+
!patientZipcode ||
|
|
582
|
+
!otpVerified ||
|
|
583
|
+
loading, onClick: submitAppointment, children: loading ? "Booking..." : "Book Appointment" })] })] })), step === 5 && (_jsxs("div", { style: { ...styles.section, textAlign: "center" }, children: [_jsxs("div", { style: styles.successCard, children: [_jsx("div", { style: {
|
|
543
584
|
fontSize: 32,
|
|
544
585
|
color: "#10b981",
|
|
545
586
|
marginBottom: 8,
|
|
@@ -555,6 +596,11 @@ export const AppointmentCalender = ({ onError, }) => {
|
|
|
555
596
|
setPatientName("");
|
|
556
597
|
setPatientAge("");
|
|
557
598
|
setPatientAddress("");
|
|
599
|
+
setPatientCity("");
|
|
600
|
+
setPatientState("");
|
|
601
|
+
setPatientCountry("");
|
|
602
|
+
setPatientZipcode("");
|
|
603
|
+
setPatientLandmark("");
|
|
558
604
|
setPatientEmail("");
|
|
559
605
|
setPatientGender("");
|
|
560
606
|
setProblemFacing("");
|
|
@@ -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";
|