pih-appointment-widget 0.0.21 → 0.0.23
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/dist/components/AppointmentPage.js +152 -9
- package/dist/pih-appointment-widget.umd.js +158 -20
- package/dist/pih-appointment-widget.umd.min.js +1 -1
- package/dist/services/appointmentService.js +7 -6
- package/package.json +1 -1
- package/src/components/AppointmentPage.js +125 -10
- package/src/services/appointmentService.js +7 -4
|
@@ -29,6 +29,7 @@ const STORAGE_KEY_APP_TOKEN = "pih_appointment_appToken";
|
|
|
29
29
|
const STORAGE_KEY_DOCTOR_ID = "pih_appointment_doctorId";
|
|
30
30
|
const STORAGE_KEY_USER_NAME = "pih_appointment_userName";
|
|
31
31
|
const STORAGE_KEY_API_BASE_URL = "pih_appointment_apiBaseUrl";
|
|
32
|
+
const STORAGE_KEY_HOSPITAL_ID = "pih_appointment_hospitalId";
|
|
32
33
|
const DEFAULT_PIP_WIDTH = 720;
|
|
33
34
|
const DEFAULT_PIP_HEIGHT = 560;
|
|
34
35
|
|
|
@@ -125,8 +126,15 @@ const AppointmentPage = _ref => {
|
|
|
125
126
|
return null;
|
|
126
127
|
}
|
|
127
128
|
});
|
|
129
|
+
const [storedHospitalId, setStoredHospitalId] = (0, _react.useState)(() => {
|
|
130
|
+
try {
|
|
131
|
+
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_HOSPITAL_ID) : null;
|
|
132
|
+
} catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
128
136
|
const apiBaseUrl = config.apiBaseUrl || storedApiBaseUrl || _apiConfig.API_BASE_URL;
|
|
129
|
-
const hospitalId = config.hospitalId ||
|
|
137
|
+
const hospitalId = config.hospitalId || storedHospitalId;
|
|
130
138
|
|
|
131
139
|
// idToken/email: config first, then localStorage. When Flutter (or parent) passes a new token, we use it and re-login.
|
|
132
140
|
const [storedIdToken, setStoredIdToken] = (0, _react.useState)(() => {
|
|
@@ -173,8 +181,12 @@ const AppointmentPage = _ref => {
|
|
|
173
181
|
localStorage.setItem(STORAGE_KEY_API_BASE_URL, config.apiBaseUrl.trim());
|
|
174
182
|
setStoredApiBaseUrl(config.apiBaseUrl.trim());
|
|
175
183
|
}
|
|
184
|
+
if (config.hospitalId != null && String(config.hospitalId).trim()) {
|
|
185
|
+
localStorage.setItem(STORAGE_KEY_HOSPITAL_ID, String(config.hospitalId).trim());
|
|
186
|
+
setStoredHospitalId(String(config.hospitalId).trim());
|
|
187
|
+
}
|
|
176
188
|
} catch (e) {}
|
|
177
|
-
}, [config.idToken, config.token, config.email, config.apiBaseUrl]);
|
|
189
|
+
}, [config.idToken, config.token, config.email, config.apiBaseUrl, config.hospitalId]);
|
|
178
190
|
const [appToken, setAppToken] = (0, _react.useState)(() => {
|
|
179
191
|
try {
|
|
180
192
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_APP_TOKEN) : null;
|
|
@@ -331,6 +343,8 @@ const AppointmentPage = _ref => {
|
|
|
331
343
|
const [selectedDate, setSelectedDate] = (0, _react.useState)("today"); // today, tomorrow, week, month, year, custom
|
|
332
344
|
const [dateOption, setDateOption] = (0, _react.useState)("today"); // Currently selected option in dropdown
|
|
333
345
|
const [showDatePicker, setShowDatePicker] = (0, _react.useState)(false);
|
|
346
|
+
const [showAppointmentTypePicker, setShowAppointmentTypePicker] = (0, _react.useState)(false);
|
|
347
|
+
const [appointmentTypeFilter, setAppointmentTypeFilter] = (0, _react.useState)("all"); // 'all' | 'ONLINE' | 'PHYSICAL'
|
|
334
348
|
const [sortOrder, setSortOrder] = (0, _react.useState)("asc"); // asc or desc for date sorting
|
|
335
349
|
const [searchQuery, setSearchQuery] = (0, _react.useState)(""); // Search query for filtering
|
|
336
350
|
|
|
@@ -441,10 +455,11 @@ const AppointmentPage = _ref => {
|
|
|
441
455
|
setSelectedAppointment(sortedAppointments[0]);
|
|
442
456
|
}
|
|
443
457
|
};
|
|
444
|
-
const fetchAppointments = (0, _react.useCallback)(async
|
|
458
|
+
const fetchAppointments = (0, _react.useCallback)(async overrideType => {
|
|
445
459
|
if (!appToken) return;
|
|
446
460
|
console.log(doctorIdFromLogin, 'fetchAppointments -> doctorIdFromLogin');
|
|
447
461
|
const doctorId = doctorIdFromLogin;
|
|
462
|
+
const typeToUse = overrideType !== undefined ? overrideType : appointmentTypeFilter;
|
|
448
463
|
setLoading(true);
|
|
449
464
|
setError(null);
|
|
450
465
|
try {
|
|
@@ -454,7 +469,7 @@ const AppointmentPage = _ref => {
|
|
|
454
469
|
doctorId,
|
|
455
470
|
token: appToken
|
|
456
471
|
};
|
|
457
|
-
const response = await (0, _appointmentService.getAppointmentsByStatus)(activeTab, fromDate, toDate,
|
|
472
|
+
const response = await (0, _appointmentService.getAppointmentsByStatus)(activeTab, fromDate, toDate, typeToUse, serviceConfig);
|
|
458
473
|
if (response.status === 401 || response.status === 403) {
|
|
459
474
|
// Token expired — clear stored token and trigger re-login (SSO effect will fire)
|
|
460
475
|
try {
|
|
@@ -488,7 +503,7 @@ const AppointmentPage = _ref => {
|
|
|
488
503
|
} finally {
|
|
489
504
|
setLoading(false);
|
|
490
505
|
}
|
|
491
|
-
}, [activeTab, fromDate, toDate, apiBaseUrl, hospitalId, doctorIdFromLogin, appToken]);
|
|
506
|
+
}, [activeTab, fromDate, toDate, appointmentTypeFilter, apiBaseUrl, hospitalId, doctorIdFromLogin, appToken]);
|
|
492
507
|
|
|
493
508
|
// Handle appointment selection - no API call, just show data from list
|
|
494
509
|
const handleAppointmentSelect = appointment => {
|
|
@@ -505,6 +520,7 @@ const AppointmentPage = _ref => {
|
|
|
505
520
|
localStorage.removeItem(STORAGE_KEY_DOCTOR_ID);
|
|
506
521
|
localStorage.removeItem(STORAGE_KEY_USER_NAME);
|
|
507
522
|
localStorage.removeItem(STORAGE_KEY_API_BASE_URL);
|
|
523
|
+
localStorage.removeItem(STORAGE_KEY_HOSPITAL_ID);
|
|
508
524
|
}
|
|
509
525
|
} catch (e) {}
|
|
510
526
|
setShowProfileDropdown(false);
|
|
@@ -794,7 +810,7 @@ const AppointmentPage = _ref => {
|
|
|
794
810
|
// Reset page to 1 when filters change
|
|
795
811
|
(0, _react.useEffect)(() => {
|
|
796
812
|
setCurrentPage(1);
|
|
797
|
-
}, [activeTab, selectedDate, fromDate, toDate, searchQuery]);
|
|
813
|
+
}, [activeTab, selectedDate, fromDate, toDate, searchQuery, appointmentTypeFilter]);
|
|
798
814
|
|
|
799
815
|
// Fetch appointments when we have appToken (tab/date change triggers refetch via fetchAppointments deps)
|
|
800
816
|
(0, _react.useEffect)(() => {
|
|
@@ -851,18 +867,21 @@ const AppointmentPage = _ref => {
|
|
|
851
867
|
};
|
|
852
868
|
}, []);
|
|
853
869
|
|
|
854
|
-
// Close date picker when clicking outside
|
|
870
|
+
// Close date picker and appointment type picker when clicking outside
|
|
855
871
|
(0, _react.useEffect)(() => {
|
|
856
872
|
const handleClickOutside = event => {
|
|
857
873
|
if (showDatePicker && !event.target.closest('button') && !event.target.closest('input[type="date"]')) {
|
|
858
874
|
setShowDatePicker(false);
|
|
859
875
|
}
|
|
876
|
+
if (showAppointmentTypePicker && !event.target.closest('[data-appointment-type-picker]')) {
|
|
877
|
+
setShowAppointmentTypePicker(false);
|
|
878
|
+
}
|
|
860
879
|
};
|
|
861
880
|
document.addEventListener("click", handleClickOutside);
|
|
862
881
|
return () => {
|
|
863
882
|
document.removeEventListener("click", handleClickOutside);
|
|
864
883
|
};
|
|
865
|
-
}, [showDatePicker]);
|
|
884
|
+
}, [showDatePicker, showAppointmentTypePicker]);
|
|
866
885
|
let fontFamily = '"Nunito", serif';
|
|
867
886
|
|
|
868
887
|
// Error as popup overlay (main page stays in background); auto-redirect to home
|
|
@@ -1215,9 +1234,133 @@ const AppointmentPage = _ref => {
|
|
|
1215
1234
|
alignItems: "center",
|
|
1216
1235
|
width: isMobile ? "auto" : "auto",
|
|
1217
1236
|
position: "relative",
|
|
1218
|
-
justifyContent: isMobile ? "flex-start" : "flex-end"
|
|
1237
|
+
justifyContent: isMobile ? "flex-start" : "flex-end",
|
|
1238
|
+
flexWrap: "wrap"
|
|
1219
1239
|
}
|
|
1240
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
1241
|
+
style: {
|
|
1242
|
+
position: "relative"
|
|
1243
|
+
},
|
|
1244
|
+
"data-appointment-type-picker": true
|
|
1220
1245
|
}, /*#__PURE__*/_react.default.createElement("button", {
|
|
1246
|
+
onClick: () => setShowAppointmentTypePicker(!showAppointmentTypePicker),
|
|
1247
|
+
style: {
|
|
1248
|
+
padding: isMobile ? "8px 12px" : "8px 12px",
|
|
1249
|
+
fontFamily,
|
|
1250
|
+
fontWeight: 600,
|
|
1251
|
+
border: "1px solid #E5E5E5",
|
|
1252
|
+
borderRadius: "6px",
|
|
1253
|
+
fontSize: isMobile ? "11px" : "13px",
|
|
1254
|
+
color: "#1a1a1a",
|
|
1255
|
+
background: "#FFFFFF",
|
|
1256
|
+
display: "flex",
|
|
1257
|
+
alignItems: "center",
|
|
1258
|
+
gap: isMobile ? "4px" : "6px",
|
|
1259
|
+
cursor: "pointer",
|
|
1260
|
+
flex: "none",
|
|
1261
|
+
minWidth: isMobile ? "100px" : "auto",
|
|
1262
|
+
justifyContent: "center"
|
|
1263
|
+
}
|
|
1264
|
+
}, /*#__PURE__*/_react.default.createElement("svg", {
|
|
1265
|
+
width: isMobile ? "14" : "16",
|
|
1266
|
+
height: isMobile ? "14" : "16",
|
|
1267
|
+
viewBox: "0 0 24 24",
|
|
1268
|
+
fill: "none",
|
|
1269
|
+
stroke: "currentColor",
|
|
1270
|
+
strokeWidth: "2",
|
|
1271
|
+
strokeLinecap: "round",
|
|
1272
|
+
strokeLinejoin: "round"
|
|
1273
|
+
}, /*#__PURE__*/_react.default.createElement("path", {
|
|
1274
|
+
d: "M4.8 2A2.8 2.8 0 0 0 2 4.8v14.4A2.8 2.8 0 0 0 4.8 22h14.4a2.8 2.8 0 0 0 2.8-2.8V4.8A2.8 2.8 0 0 0 19.2 2H4.8z"
|
|
1275
|
+
}), /*#__PURE__*/_react.default.createElement("path", {
|
|
1276
|
+
d: "M8 12h8M8 16h5"
|
|
1277
|
+
})), /*#__PURE__*/_react.default.createElement("span", {
|
|
1278
|
+
style: {
|
|
1279
|
+
overflow: "hidden",
|
|
1280
|
+
textOverflow: "ellipsis",
|
|
1281
|
+
whiteSpace: "nowrap",
|
|
1282
|
+
color: "#4C4DDC"
|
|
1283
|
+
}
|
|
1284
|
+
}, appointmentTypeFilter === "all" ? "All Appointment" : appointmentTypeFilter === "ONLINE" ? "Online" : "Physical"), /*#__PURE__*/_react.default.createElement("svg", {
|
|
1285
|
+
width: isMobile ? "8" : "10",
|
|
1286
|
+
height: isMobile ? "8" : "10",
|
|
1287
|
+
viewBox: "0 0 24 24",
|
|
1288
|
+
fill: "none",
|
|
1289
|
+
stroke: "currentColor",
|
|
1290
|
+
strokeWidth: "2",
|
|
1291
|
+
strokeLinecap: "round",
|
|
1292
|
+
strokeLinejoin: "round"
|
|
1293
|
+
}, /*#__PURE__*/_react.default.createElement("polyline", {
|
|
1294
|
+
points: "6 9 12 15 18 9"
|
|
1295
|
+
}))), showAppointmentTypePicker && /*#__PURE__*/_react.default.createElement("div", {
|
|
1296
|
+
style: {
|
|
1297
|
+
position: "absolute",
|
|
1298
|
+
top: "100%",
|
|
1299
|
+
right: isMobile ? "auto" : 0,
|
|
1300
|
+
left: isMobile ? 0 : "auto",
|
|
1301
|
+
marginTop: "4px",
|
|
1302
|
+
background: "#FFFFFF",
|
|
1303
|
+
border: "1px solid #E5E5E5",
|
|
1304
|
+
borderRadius: "8px",
|
|
1305
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.15)",
|
|
1306
|
+
padding: "8px",
|
|
1307
|
+
zIndex: 1000,
|
|
1308
|
+
minWidth: isMobile ? "240px" : "200px",
|
|
1309
|
+
width: isMobile ? "calc(100vw - 24px)" : "auto",
|
|
1310
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "240px"
|
|
1311
|
+
}
|
|
1312
|
+
}, [{
|
|
1313
|
+
value: "all",
|
|
1314
|
+
label: "All Appointment"
|
|
1315
|
+
}, {
|
|
1316
|
+
value: "ONLINE",
|
|
1317
|
+
label: "Online"
|
|
1318
|
+
}, {
|
|
1319
|
+
value: "PHYSICAL",
|
|
1320
|
+
label: "Physical"
|
|
1321
|
+
}].map(_ref2 => {
|
|
1322
|
+
let {
|
|
1323
|
+
value,
|
|
1324
|
+
label
|
|
1325
|
+
} = _ref2;
|
|
1326
|
+
return /*#__PURE__*/_react.default.createElement("button", {
|
|
1327
|
+
key: value,
|
|
1328
|
+
onClick: () => {
|
|
1329
|
+
setAppointmentTypeFilter(value);
|
|
1330
|
+
setShowAppointmentTypePicker(false);
|
|
1331
|
+
fetchAppointments(value);
|
|
1332
|
+
},
|
|
1333
|
+
style: {
|
|
1334
|
+
width: "100%",
|
|
1335
|
+
padding: "10px 12px",
|
|
1336
|
+
background: appointmentTypeFilter === value ? "#E8EEF4" : "#FFFFFF",
|
|
1337
|
+
border: "none",
|
|
1338
|
+
borderRadius: "4px",
|
|
1339
|
+
fontSize: "13px",
|
|
1340
|
+
fontFamily,
|
|
1341
|
+
cursor: "pointer",
|
|
1342
|
+
textAlign: "left",
|
|
1343
|
+
fontWeight: appointmentTypeFilter === value ? 600 : 400,
|
|
1344
|
+
color: appointmentTypeFilter === value ? "#4C4DDC" : "#1a1a1a",
|
|
1345
|
+
marginBottom: "4px",
|
|
1346
|
+
display: "flex",
|
|
1347
|
+
justifyContent: "space-between",
|
|
1348
|
+
alignItems: "center",
|
|
1349
|
+
transition: "all 0.2s ease"
|
|
1350
|
+
},
|
|
1351
|
+
onMouseEnter: e => {
|
|
1352
|
+
if (appointmentTypeFilter !== value) e.target.style.background = "#F5F5F5";
|
|
1353
|
+
},
|
|
1354
|
+
onMouseLeave: e => {
|
|
1355
|
+
if (appointmentTypeFilter !== value) e.target.style.background = "#FFFFFF";
|
|
1356
|
+
}
|
|
1357
|
+
}, /*#__PURE__*/_react.default.createElement("span", null, label), appointmentTypeFilter === value && /*#__PURE__*/_react.default.createElement("span", {
|
|
1358
|
+
style: {
|
|
1359
|
+
color: "#4C4DDC",
|
|
1360
|
+
fontSize: "16px"
|
|
1361
|
+
}
|
|
1362
|
+
}, "\u2713"));
|
|
1363
|
+
}))), /*#__PURE__*/_react.default.createElement("button", {
|
|
1221
1364
|
onClick: () => {
|
|
1222
1365
|
// Initialize temp dates and option with current values when opening picker
|
|
1223
1366
|
if (!showDatePicker) {
|
|
@@ -147,11 +147,6 @@
|
|
|
147
147
|
INITIATE_CALL: "/notification/V1/consultation/online/initiate"
|
|
148
148
|
};
|
|
149
149
|
|
|
150
|
-
// Default request parameters (will be fetched from auth API later)
|
|
151
|
-
const DEFAULT_PARAMS = {
|
|
152
|
-
hospitalId: "dMtEGhak"
|
|
153
|
-
};
|
|
154
|
-
|
|
155
150
|
// Join call URL (will be dynamic from auth API later)
|
|
156
151
|
const JOIN_CALL_URL = "https://wbafedevittisalwe01-had2b3e0a7h6fyey.westeurope-01.azurewebsites.net/call/";
|
|
157
152
|
const WEB_URL = "https://wbaemrdevittisalwe01-fnapdpfme7bvduhh.westeurope-01.azurewebsites.net/";
|
|
@@ -164,8 +159,7 @@
|
|
|
164
159
|
* @param {object} config - Optional configuration { apiBaseUrl, hospitalId, doctorId }
|
|
165
160
|
* @returns {Promise} Appointments data
|
|
166
161
|
*/
|
|
167
|
-
const getAppointmentsByStatus = async function (status, fromDate, toDate) {
|
|
168
|
-
let type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'ONLINE';
|
|
162
|
+
const getAppointmentsByStatus = async function (status, fromDate, toDate, type) {
|
|
169
163
|
let config = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
170
164
|
// Map status to API format
|
|
171
165
|
let apiStatus = (status || "").toUpperCase();
|
|
@@ -173,7 +167,7 @@
|
|
|
173
167
|
apiStatus = "IN_PROGRESS";
|
|
174
168
|
}
|
|
175
169
|
const baseURL = config.apiBaseUrl;
|
|
176
|
-
const hospitalId = config.hospitalId
|
|
170
|
+
const hospitalId = config.hospitalId;
|
|
177
171
|
const doctorId = config.doctorId;
|
|
178
172
|
const token = config.token || '';
|
|
179
173
|
const params = {
|
|
@@ -181,9 +175,11 @@
|
|
|
181
175
|
doctorId,
|
|
182
176
|
fromDate,
|
|
183
177
|
toDate,
|
|
184
|
-
statuses: apiStatus
|
|
185
|
-
type
|
|
178
|
+
statuses: apiStatus
|
|
186
179
|
};
|
|
180
|
+
if (type && String(type).toUpperCase() !== "ALL") {
|
|
181
|
+
params.appointmentType = String(type).toUpperCase();
|
|
182
|
+
}
|
|
187
183
|
const url = `${baseURL}${API_PATHS.APPOINTMENTS}`;
|
|
188
184
|
|
|
189
185
|
// Return raw response (including status) so caller can detect 401 and re-login
|
|
@@ -206,7 +202,7 @@
|
|
|
206
202
|
const body = {
|
|
207
203
|
patientId: String(appointment.patientId || ""),
|
|
208
204
|
primaryPatientId: String(appointment.primaryPatientId || appointment.patientId || ""),
|
|
209
|
-
hospitalId: config.hospitalId
|
|
205
|
+
hospitalId: config.hospitalId,
|
|
210
206
|
doctorId: String(config.doctorId),
|
|
211
207
|
patientName: appointment.patientName || appointment.name || "",
|
|
212
208
|
doctorName: appointment.doctorName || config.doctorName,
|
|
@@ -234,6 +230,7 @@
|
|
|
234
230
|
const STORAGE_KEY_DOCTOR_ID = "pih_appointment_doctorId";
|
|
235
231
|
const STORAGE_KEY_USER_NAME = "pih_appointment_userName";
|
|
236
232
|
const STORAGE_KEY_API_BASE_URL = "pih_appointment_apiBaseUrl";
|
|
233
|
+
const STORAGE_KEY_HOSPITAL_ID = "pih_appointment_hospitalId";
|
|
237
234
|
const DEFAULT_PIP_WIDTH = 720;
|
|
238
235
|
const DEFAULT_PIP_HEIGHT = 560;
|
|
239
236
|
|
|
@@ -330,8 +327,15 @@
|
|
|
330
327
|
return null;
|
|
331
328
|
}
|
|
332
329
|
});
|
|
330
|
+
const [storedHospitalId, setStoredHospitalId] = React.useState(() => {
|
|
331
|
+
try {
|
|
332
|
+
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_HOSPITAL_ID) : null;
|
|
333
|
+
} catch {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
});
|
|
333
337
|
const apiBaseUrl = config.apiBaseUrl || storedApiBaseUrl || API_BASE_URL;
|
|
334
|
-
const hospitalId = config.hospitalId ||
|
|
338
|
+
const hospitalId = config.hospitalId || storedHospitalId;
|
|
335
339
|
|
|
336
340
|
// idToken/email: config first, then localStorage. When Flutter (or parent) passes a new token, we use it and re-login.
|
|
337
341
|
const [storedIdToken, setStoredIdToken] = React.useState(() => {
|
|
@@ -378,8 +382,12 @@
|
|
|
378
382
|
localStorage.setItem(STORAGE_KEY_API_BASE_URL, config.apiBaseUrl.trim());
|
|
379
383
|
setStoredApiBaseUrl(config.apiBaseUrl.trim());
|
|
380
384
|
}
|
|
385
|
+
if (config.hospitalId != null && String(config.hospitalId).trim()) {
|
|
386
|
+
localStorage.setItem(STORAGE_KEY_HOSPITAL_ID, String(config.hospitalId).trim());
|
|
387
|
+
setStoredHospitalId(String(config.hospitalId).trim());
|
|
388
|
+
}
|
|
381
389
|
} catch (e) {}
|
|
382
|
-
}, [config.idToken, config.token, config.email, config.apiBaseUrl]);
|
|
390
|
+
}, [config.idToken, config.token, config.email, config.apiBaseUrl, config.hospitalId]);
|
|
383
391
|
const [appToken, setAppToken] = React.useState(() => {
|
|
384
392
|
try {
|
|
385
393
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_APP_TOKEN) : null;
|
|
@@ -536,6 +544,8 @@
|
|
|
536
544
|
const [selectedDate, setSelectedDate] = React.useState("today"); // today, tomorrow, week, month, year, custom
|
|
537
545
|
const [dateOption, setDateOption] = React.useState("today"); // Currently selected option in dropdown
|
|
538
546
|
const [showDatePicker, setShowDatePicker] = React.useState(false);
|
|
547
|
+
const [showAppointmentTypePicker, setShowAppointmentTypePicker] = React.useState(false);
|
|
548
|
+
const [appointmentTypeFilter, setAppointmentTypeFilter] = React.useState("all"); // 'all' | 'ONLINE' | 'PHYSICAL'
|
|
539
549
|
const [sortOrder, setSortOrder] = React.useState("asc"); // asc or desc for date sorting
|
|
540
550
|
const [searchQuery, setSearchQuery] = React.useState(""); // Search query for filtering
|
|
541
551
|
|
|
@@ -646,10 +656,11 @@
|
|
|
646
656
|
setSelectedAppointment(sortedAppointments[0]);
|
|
647
657
|
}
|
|
648
658
|
};
|
|
649
|
-
const fetchAppointments = React.useCallback(async
|
|
659
|
+
const fetchAppointments = React.useCallback(async overrideType => {
|
|
650
660
|
if (!appToken) return;
|
|
651
661
|
console.log(doctorIdFromLogin, 'fetchAppointments -> doctorIdFromLogin');
|
|
652
662
|
const doctorId = doctorIdFromLogin;
|
|
663
|
+
const typeToUse = overrideType !== undefined ? overrideType : appointmentTypeFilter;
|
|
653
664
|
setLoading(true);
|
|
654
665
|
setError(null);
|
|
655
666
|
try {
|
|
@@ -659,7 +670,7 @@
|
|
|
659
670
|
doctorId,
|
|
660
671
|
token: appToken
|
|
661
672
|
};
|
|
662
|
-
const response = await getAppointmentsByStatus(activeTab, fromDate, toDate,
|
|
673
|
+
const response = await getAppointmentsByStatus(activeTab, fromDate, toDate, typeToUse, serviceConfig);
|
|
663
674
|
if (response.status === 401 || response.status === 403) {
|
|
664
675
|
// Token expired — clear stored token and trigger re-login (SSO effect will fire)
|
|
665
676
|
try {
|
|
@@ -693,7 +704,7 @@
|
|
|
693
704
|
} finally {
|
|
694
705
|
setLoading(false);
|
|
695
706
|
}
|
|
696
|
-
}, [activeTab, fromDate, toDate, apiBaseUrl, hospitalId, doctorIdFromLogin, appToken]);
|
|
707
|
+
}, [activeTab, fromDate, toDate, appointmentTypeFilter, apiBaseUrl, hospitalId, doctorIdFromLogin, appToken]);
|
|
697
708
|
|
|
698
709
|
// Handle appointment selection - no API call, just show data from list
|
|
699
710
|
const handleAppointmentSelect = appointment => {
|
|
@@ -980,7 +991,7 @@
|
|
|
980
991
|
// Reset page to 1 when filters change
|
|
981
992
|
React.useEffect(() => {
|
|
982
993
|
setCurrentPage(1);
|
|
983
|
-
}, [activeTab, selectedDate, fromDate, toDate, searchQuery]);
|
|
994
|
+
}, [activeTab, selectedDate, fromDate, toDate, searchQuery, appointmentTypeFilter]);
|
|
984
995
|
|
|
985
996
|
// Fetch appointments when we have appToken (tab/date change triggers refetch via fetchAppointments deps)
|
|
986
997
|
React.useEffect(() => {
|
|
@@ -1037,18 +1048,21 @@
|
|
|
1037
1048
|
};
|
|
1038
1049
|
}, []);
|
|
1039
1050
|
|
|
1040
|
-
// Close date picker when clicking outside
|
|
1051
|
+
// Close date picker and appointment type picker when clicking outside
|
|
1041
1052
|
React.useEffect(() => {
|
|
1042
1053
|
const handleClickOutside = event => {
|
|
1043
1054
|
if (showDatePicker && !event.target.closest('button') && !event.target.closest('input[type="date"]')) {
|
|
1044
1055
|
setShowDatePicker(false);
|
|
1045
1056
|
}
|
|
1057
|
+
if (showAppointmentTypePicker && !event.target.closest('[data-appointment-type-picker]')) {
|
|
1058
|
+
setShowAppointmentTypePicker(false);
|
|
1059
|
+
}
|
|
1046
1060
|
};
|
|
1047
1061
|
document.addEventListener("click", handleClickOutside);
|
|
1048
1062
|
return () => {
|
|
1049
1063
|
document.removeEventListener("click", handleClickOutside);
|
|
1050
1064
|
};
|
|
1051
|
-
}, [showDatePicker]);
|
|
1065
|
+
}, [showDatePicker, showAppointmentTypePicker]);
|
|
1052
1066
|
let fontFamily = '"Nunito", serif';
|
|
1053
1067
|
|
|
1054
1068
|
// Error as popup overlay (main page stays in background); auto-redirect to home
|
|
@@ -1255,9 +1269,133 @@
|
|
|
1255
1269
|
alignItems: "center",
|
|
1256
1270
|
width: isMobile ? "auto" : "auto",
|
|
1257
1271
|
position: "relative",
|
|
1258
|
-
justifyContent: isMobile ? "flex-start" : "flex-end"
|
|
1272
|
+
justifyContent: isMobile ? "flex-start" : "flex-end",
|
|
1273
|
+
flexWrap: "wrap"
|
|
1259
1274
|
}
|
|
1275
|
+
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
1276
|
+
style: {
|
|
1277
|
+
position: "relative"
|
|
1278
|
+
},
|
|
1279
|
+
"data-appointment-type-picker": true
|
|
1260
1280
|
}, /*#__PURE__*/React__default["default"].createElement("button", {
|
|
1281
|
+
onClick: () => setShowAppointmentTypePicker(!showAppointmentTypePicker),
|
|
1282
|
+
style: {
|
|
1283
|
+
padding: isMobile ? "8px 12px" : "8px 12px",
|
|
1284
|
+
fontFamily,
|
|
1285
|
+
fontWeight: 600,
|
|
1286
|
+
border: "1px solid #E5E5E5",
|
|
1287
|
+
borderRadius: "6px",
|
|
1288
|
+
fontSize: isMobile ? "11px" : "13px",
|
|
1289
|
+
color: "#1a1a1a",
|
|
1290
|
+
background: "#FFFFFF",
|
|
1291
|
+
display: "flex",
|
|
1292
|
+
alignItems: "center",
|
|
1293
|
+
gap: isMobile ? "4px" : "6px",
|
|
1294
|
+
cursor: "pointer",
|
|
1295
|
+
flex: "none",
|
|
1296
|
+
minWidth: isMobile ? "100px" : "auto",
|
|
1297
|
+
justifyContent: "center"
|
|
1298
|
+
}
|
|
1299
|
+
}, /*#__PURE__*/React__default["default"].createElement("svg", {
|
|
1300
|
+
width: isMobile ? "14" : "16",
|
|
1301
|
+
height: isMobile ? "14" : "16",
|
|
1302
|
+
viewBox: "0 0 24 24",
|
|
1303
|
+
fill: "none",
|
|
1304
|
+
stroke: "currentColor",
|
|
1305
|
+
strokeWidth: "2",
|
|
1306
|
+
strokeLinecap: "round",
|
|
1307
|
+
strokeLinejoin: "round"
|
|
1308
|
+
}, /*#__PURE__*/React__default["default"].createElement("path", {
|
|
1309
|
+
d: "M4.8 2A2.8 2.8 0 0 0 2 4.8v14.4A2.8 2.8 0 0 0 4.8 22h14.4a2.8 2.8 0 0 0 2.8-2.8V4.8A2.8 2.8 0 0 0 19.2 2H4.8z"
|
|
1310
|
+
}), /*#__PURE__*/React__default["default"].createElement("path", {
|
|
1311
|
+
d: "M8 12h8M8 16h5"
|
|
1312
|
+
})), /*#__PURE__*/React__default["default"].createElement("span", {
|
|
1313
|
+
style: {
|
|
1314
|
+
overflow: "hidden",
|
|
1315
|
+
textOverflow: "ellipsis",
|
|
1316
|
+
whiteSpace: "nowrap",
|
|
1317
|
+
color: "#4C4DDC"
|
|
1318
|
+
}
|
|
1319
|
+
}, appointmentTypeFilter === "all" ? "All Appointment" : appointmentTypeFilter === "ONLINE" ? "Online" : "Physical"), /*#__PURE__*/React__default["default"].createElement("svg", {
|
|
1320
|
+
width: isMobile ? "8" : "10",
|
|
1321
|
+
height: isMobile ? "8" : "10",
|
|
1322
|
+
viewBox: "0 0 24 24",
|
|
1323
|
+
fill: "none",
|
|
1324
|
+
stroke: "currentColor",
|
|
1325
|
+
strokeWidth: "2",
|
|
1326
|
+
strokeLinecap: "round",
|
|
1327
|
+
strokeLinejoin: "round"
|
|
1328
|
+
}, /*#__PURE__*/React__default["default"].createElement("polyline", {
|
|
1329
|
+
points: "6 9 12 15 18 9"
|
|
1330
|
+
}))), showAppointmentTypePicker && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
1331
|
+
style: {
|
|
1332
|
+
position: "absolute",
|
|
1333
|
+
top: "100%",
|
|
1334
|
+
right: isMobile ? "auto" : 0,
|
|
1335
|
+
left: isMobile ? 0 : "auto",
|
|
1336
|
+
marginTop: "4px",
|
|
1337
|
+
background: "#FFFFFF",
|
|
1338
|
+
border: "1px solid #E5E5E5",
|
|
1339
|
+
borderRadius: "8px",
|
|
1340
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.15)",
|
|
1341
|
+
padding: "8px",
|
|
1342
|
+
zIndex: 1000,
|
|
1343
|
+
minWidth: isMobile ? "240px" : "200px",
|
|
1344
|
+
width: isMobile ? "calc(100vw - 24px)" : "auto",
|
|
1345
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "240px"
|
|
1346
|
+
}
|
|
1347
|
+
}, [{
|
|
1348
|
+
value: "all",
|
|
1349
|
+
label: "All Appointment"
|
|
1350
|
+
}, {
|
|
1351
|
+
value: "ONLINE",
|
|
1352
|
+
label: "Online"
|
|
1353
|
+
}, {
|
|
1354
|
+
value: "PHYSICAL",
|
|
1355
|
+
label: "Physical"
|
|
1356
|
+
}].map(_ref2 => {
|
|
1357
|
+
let {
|
|
1358
|
+
value,
|
|
1359
|
+
label
|
|
1360
|
+
} = _ref2;
|
|
1361
|
+
return /*#__PURE__*/React__default["default"].createElement("button", {
|
|
1362
|
+
key: value,
|
|
1363
|
+
onClick: () => {
|
|
1364
|
+
setAppointmentTypeFilter(value);
|
|
1365
|
+
setShowAppointmentTypePicker(false);
|
|
1366
|
+
fetchAppointments(value);
|
|
1367
|
+
},
|
|
1368
|
+
style: {
|
|
1369
|
+
width: "100%",
|
|
1370
|
+
padding: "10px 12px",
|
|
1371
|
+
background: appointmentTypeFilter === value ? "#E8EEF4" : "#FFFFFF",
|
|
1372
|
+
border: "none",
|
|
1373
|
+
borderRadius: "4px",
|
|
1374
|
+
fontSize: "13px",
|
|
1375
|
+
fontFamily,
|
|
1376
|
+
cursor: "pointer",
|
|
1377
|
+
textAlign: "left",
|
|
1378
|
+
fontWeight: appointmentTypeFilter === value ? 600 : 400,
|
|
1379
|
+
color: appointmentTypeFilter === value ? "#4C4DDC" : "#1a1a1a",
|
|
1380
|
+
marginBottom: "4px",
|
|
1381
|
+
display: "flex",
|
|
1382
|
+
justifyContent: "space-between",
|
|
1383
|
+
alignItems: "center",
|
|
1384
|
+
transition: "all 0.2s ease"
|
|
1385
|
+
},
|
|
1386
|
+
onMouseEnter: e => {
|
|
1387
|
+
if (appointmentTypeFilter !== value) e.target.style.background = "#F5F5F5";
|
|
1388
|
+
},
|
|
1389
|
+
onMouseLeave: e => {
|
|
1390
|
+
if (appointmentTypeFilter !== value) e.target.style.background = "#FFFFFF";
|
|
1391
|
+
}
|
|
1392
|
+
}, /*#__PURE__*/React__default["default"].createElement("span", null, label), appointmentTypeFilter === value && /*#__PURE__*/React__default["default"].createElement("span", {
|
|
1393
|
+
style: {
|
|
1394
|
+
color: "#4C4DDC",
|
|
1395
|
+
fontSize: "16px"
|
|
1396
|
+
}
|
|
1397
|
+
}, "\u2713"));
|
|
1398
|
+
}))), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
1261
1399
|
onClick: () => {
|
|
1262
1400
|
// Initialize temp dates and option with current values when opening picker
|
|
1263
1401
|
if (!showDatePicker) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MyPackage={},e.React,e.ReactDOM)}(this,(function(e,t,n){"use strict";function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=o(t),i=o(n);const r="/appointment/V1/consultant/all-appointments",l="/notification/V1/consultation/online/initiate",d="dMtEGhak",s="https://wbafedevittisalwe01-had2b3e0a7h6fyey.westeurope-01.azurewebsites.net/call/",p=async function(e,t,n){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"ONLINE",a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{},i=(e||"").toUpperCase();"INPROGRESS"===i&&(i="IN_PROGRESS");const l=a.apiBaseUrl,s=a.hospitalId||d,p=a.doctorId,c=a.token||"",u={hospitalId:s,doctorId:p,fromDate:t,toDate:n,statuses:i,type:o},f=`${l}${r}`,m=await async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";const o=new URL(e);return o.search=new URLSearchParams(t).toString(),fetch(o,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`${n}`}}).then((async e=>{const t=await e.json().catch((()=>({})));return e.ok?t:{err:t?.resultInfo?.message||"Something went wrong!",status:e.status}})).catch((e=>(console.error("Fetch error:",e),{err:e?.message||String(e)||"Network error"})))}(f,u,"PIH-Appointment-Widget",c);return m},c=async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};console.log("initiateConsultation -> config",t);const n=`${t.apiBaseUrl.replace(/\/$/,"")}${l}`,o=t.appToken||"";return async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=arguments.length>4?arguments[4]:void 0;const a=new URL(e);Object.keys(n).forEach((e=>{a.searchParams.append(e,n[e])}));const i={"Content-Type":"application/json"};o&&(i.Authorization=o);const r={method:"POST",headers:i,body:JSON.stringify(t)};return fetch(a.toString(),r).then((async e=>{const t=await e.json().catch((()=>({})));return e.ok?t:{err:t?.resultInfo?.message||"Something went wrong!",status:e.status}})).catch((e=>(console.error("Fetch error:",e),{err:e.message||"Network error"})))}(n,{patientId:String(e.patientId||""),primaryPatientId:String(e.primaryPatientId||e.patientId||""),hospitalId:t.hospitalId||d,doctorId:String(t.doctorId),patientName:e.patientName||e.name||"",doctorName:e.doctorName||t.doctorName,appointmentId:String(e.id||e.appointmentId||e._id||"")},"PIH-Appointment-Widget",{},o)};const u="pih_appointment_idToken",f="pih_appointment_email",m="pih_appointment_appToken",x="pih_appointment_doctorId",g="pih_appointment_userName",h="pih_appointment_apiBaseUrl",y=720,E="pih-appointment-widget",F="data-pih-widget";class b extends t.Component{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,t){"undefined"!=typeof console&&console.error&&console.error("Appointment widget error:",e,t)}render(){return this.state.hasError?a.default.createElement("div",{className:E,[F]:"teleconsult-appointments",style:{fontFamily:'"Nunito", serif',background:"#F5F5F7",boxSizing:"border-box",minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",textAlign:"center"}},a.default.createElement("div",{style:{maxWidth:"400px"}},a.default.createElement("div",{style:{fontSize:"48px",marginBottom:"16px"}},"⚠️"),a.default.createElement("h2",{style:{fontSize:"20px",fontWeight:700,color:"#1a1a1a",margin:"0 0 8px 0"}},"Something went wrong"),a.default.createElement("p",{style:{fontSize:"14px",color:"#666",margin:0,lineHeight:1.5}},"Please refresh the page or try again later."))):this.props.children}}const w=e=>{let{config:n={}}=e;const[o,i]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(h):null}catch{return null}})),r=n.apiBaseUrl||o||"https://afiyaapiqa.powermindinc.com",l=n.hospitalId||d,[w,S]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(u):null}catch{return null}})),[v,k]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(f):null}catch{return null}})),C=n.idToken||n.token||w,I=n.email||v;t.useEffect((()=>{try{if("undefined"==typeof localStorage)return;const e=n.idToken||n.token;if(e&&String(e).trim()){localStorage.getItem(u)!==e&&(z(null),T(null),A(null),localStorage.removeItem(m),localStorage.removeItem(x),localStorage.removeItem(g)),localStorage.setItem(u,e),S(e)}n.email&&String(n.email).trim()&&(localStorage.setItem(f,n.email),k(n.email)),n.apiBaseUrl&&String(n.apiBaseUrl).trim()&&(localStorage.setItem(h,n.apiBaseUrl.trim()),i(n.apiBaseUrl.trim()))}catch(e){}}),[n.idToken,n.token,n.email,n.apiBaseUrl]);const[D,z]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(m):null}catch{return null}})),[W,T]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(x):null}catch{return null}})),[M,A]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(g):null}catch{return null}})),[R,N]=t.useState((()=>{try{if("undefined"==typeof localStorage)return!1;const e=localStorage.getItem(m),t=localStorage.getItem(u),n=localStorage.getItem(f);return!e&&!(!t||!n)}catch{return!1}})),[P,j]=t.useState(null),[B,H]=t.useState(!1),[L,U]=t.useState(0);t.useEffect((()=>{D&&R&&N(!1)}),[D,R]),t.useEffect((()=>{D||(C&&I?(H(!1),j((e=>"Sign in required. Redirecting to home..."===e?null:e))):(j("Sign in required. Redirecting to home..."),H(!0)))}),[D,C,I]),t.useEffect((()=>{if(!B)return;const e=n.homeUrl||"https://wbaemrdevittisalwe01-fnapdpfme7bvduhh.westeurope-01.azurewebsites.net/";if(!e||"undefined"==typeof window)return;const t=setTimeout((()=>{window.location.href=e}),2500);return()=>clearTimeout(t)}),[B,n.homeUrl]),t.useEffect((()=>{if(!R)return;const e=setTimeout((()=>{j("Request timed out. Please try again."),N(!1)}),3e4);return()=>clearTimeout(e)}),[R]);const $=n.joinCallUrl||s;D&&String($||"").replace(/\/?$/,"/");const _=function(e){if(!e||"string"!=typeof e)return{};try{const t=e.split(".");if(3!==t.length)return{};const n=t[1].replace(/-/g,"+").replace(/_/g,"/"),o=n.padEnd(n.length+(4-n.length%4)%4,"=");return JSON.parse(atob(o))}catch{return{}}}(C),O=M||_.name||_.sub||"User",Y=()=>(new Date).toISOString().split("T")[0],[V,q]=t.useState("upcoming"),[X,G]=t.useState([]),[J,K]=t.useState(null),[Q,Z]=t.useState(!1),[ee,te]=t.useState(null),[ne,oe]=t.useState(window.innerWidth<768),[ae,ie]=t.useState("today"),[re,le]=t.useState("today"),[de,se]=t.useState(!1),[pe,ce]=t.useState("asc"),[ue,fe]=t.useState(""),[me,xe]=t.useState(!1),[ge,he]=t.useState(!1),[ye,Ee]=t.useState(!1),[Fe,be]=t.useState(null),[we,Se]=t.useState(null),[ve,ke]=t.useState(!1),[Ce,Ie]=t.useState(null),[De,ze]=t.useState((()=>({x:Math.max(20,"undefined"!=typeof window?window.innerWidth-y-20:300),y:80}))),[We,Te]=t.useState({width:y,height:560}),[Me,Ae]=t.useState(!1),[Re,Ne]=t.useState({x:0,y:0}),[Pe,je]=t.useState(!1),[Be,He]=t.useState(null),[Le,Ue]=t.useState({x:0,y:0,width:0,height:0});t.useState(!1);const[$e,_e]=t.useState(1),Oe=X.filter((e=>{if(!ue.trim())return!0;const t=ue.toLowerCase(),n=(e.patientName||"").toLowerCase(),o=String(e.patientId||"").toLowerCase();return n.includes(t)||o.includes(t)})),Ye=20*($e-1),Ve=Ye+20,qe=Oe.slice(Ye,Ve),Xe=Math.ceil(Oe.length/20),Ge=Oe.length,[Je,Ke]=t.useState(Y()),[Qe,Ze]=t.useState(Y()),[et,tt]=t.useState(),[nt,ot]=t.useState(),at=e=>e?.id||e?._id||e?.appointmentId||e?.patientId||JSON.stringify(e),it=e=>e?.image?e.image:null,rt=e=>e?e.charAt(0).toUpperCase():"?",lt=e=>{if(!e)return"#4C4DDC";const t=["#4C4DDC","#1CC3CE","#FF6B6B","#4ECDC4","#45B7D1","#FFA07A","#98D8C8","#F7DC6F"];return t[e.charCodeAt(0)%t.length]},dt=()=>{const e="asc"===pe?"desc":"asc";ce(e);const t=[...X].sort(((t,n)=>{const o=new Date(t.appointmentDate||t.date||0),a=new Date(n.appointmentDate||n.date||0);return"asc"===e?o-a:a-o}));G(t),_e(1),t.length>0&&K(t[0])},st=t.useCallback((async()=>{if(!D)return;console.log(W,"fetchAppointments -> doctorIdFromLogin");const e=W;Z(!0),te(null);try{const t={apiBaseUrl:r,hospitalId:l,doctorId:e,token:D},n=await p(V,Je,Qe,"PHYSICAL",t);if(401===n.status||403===n.status){try{"undefined"!=typeof localStorage&&(localStorage.removeItem(m),localStorage.removeItem(x),localStorage.removeItem(g))}catch(e){}return z(null),T(null),A(null),U((e=>e+1)),void te("Session expired. Re-authenticating...")}if(n.err)return void te(String(n.err||"Failed to fetch appointments"));const o=n.data||n.appointments||n||[];G(Array.isArray(o)?o:[]),Array.isArray(o)&&o.length>0?K(o[0]):K(null)}catch(e){console.error("Error fetching appointments:",e),te(e.message||"Failed to fetch appointments")}finally{Z(!1)}}),[V,Je,Qe,r,l,W,D]),pt=e=>{K(e)},ct=async()=>{if(J&&D){ke(!0),Ie(null);try{const e={apiBaseUrl:r,hospitalId:l,doctorId:W,doctorName:M||O,appToken:D};console.log(J,"selectedAppointment"),console.log(e,"callConfig");const t=await c(J,e);if(401===t.status||403===t.status)return Ie("Session expired. Please try again."),void ke(!1);if(t.err||!t.data?.token)return Ie(String(t.err||"Failed to initiate call")),void ke(!1);const o=n.joinCallUrl||s,a=t.data.token?String(o||"").replace(/\/?$/,"/")+t.data.token:"";console.log("joinCallUrl",a),be(t.data.token),Se(a||""),xe(!0),he(!1),Ee(!1),Te({width:y,height:560}),ze({x:Math.max(20,window.innerWidth-y-20),y:80})}catch(e){Ie(e.message||"Failed to initiate call")}finally{Ie(null),ke(!1)}}},ut=()=>{xe(!1),he(!1),Ee(!1),be(null),Se(null),Ie(null),st()},ft=()=>{ye&&Ee(!1),he(!ge)},mt=()=>{ge&&he(!1),Ee(!ye)},xt=e=>{if(0!==e.button)return;if(e.target.closest("button"))return;e.currentTarget.setPointerCapture&&e.currentTarget.setPointerCapture(e.pointerId),Ae(!0);const t=e.currentTarget.getBoundingClientRect();Ne({x:e.clientX-t.left,y:e.clientY-t.top})},gt=t.useCallback((e=>{if(!ye)if(Me){const t=e.clientX-Re.x,n=e.clientY-Re.y,o=window.innerWidth-We.width,a=window.innerHeight-We.height;ze({x:Math.max(0,Math.min(t,o)),y:Math.max(0,Math.min(n,a))})}else if(Pe){const t=e.clientX-Le.x,n=e.clientY-Le.y;let o=Le.width,a=Le.height,i=Le.posX,r=Le.posY;const l=300,d=250,s=window.innerWidth-40,p=window.innerHeight-100;if("bottom-right"===Be)o=Math.min(Math.max(Le.width+t,l),s),a=Math.min(Math.max(Le.height+n,d),p),i+o>window.innerWidth&&(o=window.innerWidth-i),r+a>window.innerHeight&&(a=window.innerHeight-r);else if("bottom-left"===Be){o=Math.min(Math.max(Le.width-t,l),s),i=Math.max(0,Le.posX+t),0===i&&(o=Le.posX+Le.width),a=Math.min(Math.max(Le.height+n,d),p),r+a>window.innerHeight&&(a=window.innerHeight-r)}else if("top-right"===Be){o=Math.min(Math.max(Le.width+t,l),s),i+o>window.innerWidth&&(o=window.innerWidth-i);a=Math.min(Math.max(Le.height-n,d),p),r=Math.max(0,Le.posY+n),0===r&&(a=Le.posY+Le.height)}else if("top-left"===Be){o=Math.min(Math.max(Le.width-t,l),s),i=Math.max(0,Le.posX+t),0===i&&(o=Le.posX+Le.width);a=Math.min(Math.max(Le.height-n,d),p),r=Math.max(0,Le.posY+n),0===r&&(a=Le.posY+Le.height)}Te({width:o,height:a}),ze({x:i,y:r})}}),[Me,Pe,Re,Be,Le,De,We,ye]),ht=()=>{Ae(!1),je(!1),He(null)},yt=(e,t)=>{t.preventDefault(),t.stopPropagation(),t.currentTarget.setPointerCapture&&t.currentTarget.setPointerCapture(t.pointerId),je(!0),He(e),Ue({x:t.clientX,y:t.clientY,width:We.width,height:We.height,posX:De.x,posY:De.y})};t.useEffect((()=>{if(!me||ye)return;const e=()=>{if(!(window.innerWidth<768)){const e=ge?350:We.width,t=ge?60:We.height,n=window.innerWidth-40,o=window.innerHeight-100,a=Math.min(e,n),i=Math.min(t,o);a===We.width&&i===We.height||Te({width:a,height:i});const r=window.innerWidth-a-20,l=window.innerHeight-i-20;ze((e=>({x:Math.min(e.x,r),y:Math.min(e.y,l)})))}};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)}),[me,ge,ye,We]),t.useEffect((()=>{if(!(C&&I&&(!D||L>0)))return;let e=!1;return N(!0),j(null),(async(e,t,n,o)=>{const a=`${e.replace(/\/$/,"")}/um/user/V1/sso/login?hospitalId=${encodeURIComponent(t)}`,i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({idToken:n,email:o})};return console.log("[getTokenFromSso] request",{url:a,body:{idToken:n?n.slice(0,50)+"...":null,email:o}}),fetch(a,i).then((e=>(console.log("[getTokenFromSso] response status",e.status,e.statusText),e.ok?e.json().then((e=>(console.log("[getTokenFromSso] success",{hasData:!!e,dataKeys:e?Object.keys(e):[],hasAccessToken:!!e?.data?.access_token}),e))):e.json().then((t=>{const n=t?.resultInfo?.message||"SSO login failed";return console.log("[getTokenFromSso] error body",t),{err:n,status:e.status}})).catch((()=>({err:"Something went wrong!",status:e.status})))))).catch((e=>(console.error("[getTokenFromSso] catch",e),{err:e.message||"Network error"})))})(r,l,C,I).then((t=>{if(e)return;const n=function(e){return!e||e.err?null:e.data?.access_token??e.data?.token??e.token??e.accessToken??null}(t);if(400===t.status)return j(t.err||"Invalid request. Redirecting to home..."),N(!1),void H(!0);if(t.err||!n){j(String(t.err||"Failed to get token")),z(null),T(null),A(null);try{"undefined"!=typeof localStorage&&(localStorage.removeItem(m),localStorage.removeItem(x),localStorage.removeItem(g))}catch(e){}}else{const e=function(e){if(!e?.data)return null;const t=e.data.doctor_id??e.data.doctorId??null;return console.log(t,"extractDoctorIdFromLoginResponse -> id"),null!=t?String(t):null}(t);console.log(e,"extractDoctorIdFromLoginResponse -> doctorId");const o=function(e){if(!e?.data)return null;const t=e.data.name??e.data.doctor_name??e.data.userName??null;return null!=t?String(t):null}(t);z(n),T(e),A(o),j(null),H(!1);try{"undefined"!=typeof localStorage&&(localStorage.setItem(m,n),e&&localStorage.setItem(x,e),o&&localStorage.setItem(g,o))}catch(e){}}})).catch((()=>{})).finally((()=>{e||N(!1)})),()=>{e=!0}}),[r,l,C,I,L]),t.useEffect((()=>{_e(1)}),[V,ae,Je,Qe,ue]),t.useEffect((()=>{!R&&D&&st()}),[st,D,R]),t.useEffect((()=>{const e=document.createElement("link");e.href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap",e.rel="stylesheet",document.head.appendChild(e);const t=document.createElement("style");t.innerHTML="\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n @media (max-width: 768px) {\n .appointments-grid {\n grid-template-columns: 1.5fr 1fr 0.8fr !important;\n }\n .appointments-header-grid {\n grid-template-columns: 1.5fr 1fr 0.8fr !important;\n }\n .hide-on-mobile {\n display: none !important;\n }\n }\n @media (max-width: 480px) {\n .appointments-header-grid {\n font-size: 10px !important;\n }\n .appointments-grid {\n font-size: 11px !important;\n }\n }\n ",document.head.appendChild(t);const n=()=>{oe(window.innerWidth<768)};return window.addEventListener("resize",n),()=>{document.head.removeChild(e),document.head.removeChild(t),window.removeEventListener("resize",n)}}),[]),t.useEffect((()=>{const e=e=>{!de||e.target.closest("button")||e.target.closest('input[type="date"]')||se(!1)};return document.addEventListener("click",e),()=>{document.removeEventListener("click",e)}}),[de]);let Et='"Nunito", serif';const Ft=P||!D&&(!C||!I),bt=P||"Sign in required. Redirecting to home...";let wt;return wt=R&&C&&I?a.default.createElement("div",{className:E,[F]:"teleconsult-appointments",style:{fontFamily:Et,background:"#F5F5F7",boxSizing:"border-box",height:"100%",minHeight:"100vh",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"24px"}},a.default.createElement("style",null,"@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }"),a.default.createElement("div",{style:{width:"40px",height:"40px",border:"3px solid #f3f3f3",borderTop:"3px solid #4C4DDC",borderRadius:"50%",animation:"spin 1s linear infinite",marginBottom:"16px"}}),a.default.createElement("p",{style:{fontSize:"14px",color:"#666",margin:0}},"Checking authorisation...")):a.default.createElement(a.default.Fragment,null,a.default.createElement("div",{className:E,[F]:"teleconsult-appointments",style:{fontFamily:Et,background:"#F5F5F7",boxSizing:"border-box",height:"100%",minHeight:"100vh",width:"100%",display:"flex",flexDirection:"column",overflow:"hidden"}},a.default.createElement("div",{style:{background:"#FFFFFF",padding:ne?"10px 12px":"12px 24px",display:"flex",justifyContent:"space-between",alignItems:"center",borderBottom:"1px solid #E5E5E5",flexWrap:"nowrap",gap:ne?"8px":"0"}},a.default.createElement("div",{style:{position:"relative",width:ne?"calc(100% - 90px)":"480px",maxWidth:ne?"none":"480px"}},a.default.createElement("input",{type:"text",placeholder:"Search by patient name or ID",value:ue,onChange:e=>fe(e.target.value),style:{width:"100%",padding:ne?"8px 32px 8px 10px":"8px 36px 8px 14px",border:"1px solid #E5E5E5",borderRadius:"6px",fontSize:ne?"12px":"13px",fontFamily:Et,background:"#FFFFFF",outline:"none",boxSizing:"border-box"}}),ue&&a.default.createElement("button",{onClick:()=>fe(""),style:{position:"absolute",right:"8px",top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",padding:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"#999",fontSize:"16px"},title:"Clear search"},"✕")),!1),a.default.createElement("div",{style:{padding:ne?"12px":"16px 24px",flex:1,minHeight:0,overflow:"hidden",display:"flex",flexDirection:"column"}},a.default.createElement("div",{style:{marginBottom:ne?"10px":"14px"}},a.default.createElement("h1",{style:{fontSize:ne?"18px":"22px",fontWeight:700,color:"#1a1a1a",margin:"0 0 2px 0"}},"Tele Consultation"),a.default.createElement("p",{style:{fontSize:ne?"11px":"12px",color:"#999",margin:0}},"Displaying All Tele Consultation Appointments")),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:ne?"flex-start":"center",marginBottom:ne?"10px":"14px",flexDirection:ne?"column":"row",gap:ne?"12px":"0"}},a.default.createElement("div",{style:{display:"flex",gap:"6px",flexWrap:"wrap",width:ne?"100%":"auto"}},a.default.createElement("button",{onClick:()=>q("upcoming"),style:{background:"upcoming"===V?"#4C4DDC":"#FFFFFF",padding:ne?"8px 10px":"9px 16px",border:"upcoming"===V?"none":"1px solid #E5E5E5",borderRadius:"6px",fontSize:ne?"10px":"13px",color:"upcoming"===V?"white":"#555555",fontWeight:600,fontFamily:Et,cursor:"pointer",flex:ne?"1 1 auto":"none",minWidth:ne?"0":"auto",transition:"all 0.3s ease",whiteSpace:"nowrap"}},"Upcoming Appointments"),a.default.createElement("button",{onClick:()=>q("completed"),style:{background:"completed"===V?"#4C4DDC":"#FFFFFF",padding:ne?"8px 10px":"9px 16px",border:"completed"===V?"none":"1px solid #E5E5E5",borderRadius:"6px",fontSize:ne?"10px":"13px",color:"completed"===V?"white":"#555555",fontWeight:600,fontFamily:Et,cursor:"pointer",flex:ne?"1 1 auto":"none",minWidth:ne?"0":"auto",transition:"all 0.3s ease",whiteSpace:"nowrap"}},"Completed Appointments"),a.default.createElement("button",{onClick:()=>q("cancelled"),style:{background:"cancelled"===V?"#4C4DDC":"#FFFFFF",padding:ne?"8px 10px":"9px 16px",border:"cancelled"===V?"none":"1px solid #E5E5E5",borderRadius:"6px",fontSize:ne?"10px":"13px",color:"cancelled"===V?"white":"#555555",fontWeight:600,fontFamily:Et,cursor:"pointer",flex:ne?"1 1 auto":"none",minWidth:ne?"0":"auto",transition:"all 0.3s ease",whiteSpace:"nowrap"}},"Cancelled Appointments")),a.default.createElement("div",{style:{display:"flex",gap:"8px",alignItems:"center",width:"auto",position:"relative",justifyContent:ne?"flex-start":"flex-end"}},a.default.createElement("button",{onClick:()=>{de||(tt(Je),ot(Qe),le(ae)),se(!de)},style:{padding:"8px 12px",fontFamily:Et,fontWeight:600,border:"1px solid #E5E5E5",borderRadius:"6px",fontSize:ne?"11px":"13px",color:"#1a1a1a",background:"#FFFFFF",display:"flex",alignItems:"center",gap:ne?"4px":"6px",cursor:"pointer",flex:"none",minWidth:ne?"100px":"auto",justifyContent:"center"}},a.default.createElement("svg",{width:ne?"12":"14",height:ne?"12":"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a.default.createElement("rect",{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"}),a.default.createElement("line",{x1:"16",y1:"2",x2:"16",y2:"6"}),a.default.createElement("line",{x1:"8",y1:"2",x2:"8",y2:"6"}),a.default.createElement("line",{x1:"3",y1:"10",x2:"21",y2:"10"})),a.default.createElement("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},(()=>{switch(ae){case"today":default:return"Today";case"tomorrow":return"Tomorrow";case"currentWeek":return"Current Week";case"thisMonth":return"This Month";case"currentYear":return"Current Year";case"custom":return ne?"Custom":`${Je} to ${Qe}`}})()),a.default.createElement("svg",{width:ne?"8":"10",height:ne?"8":"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a.default.createElement("polyline",{points:"6 9 12 15 18 9"}))),de&&a.default.createElement("div",{style:{position:"absolute",top:"100%",right:ne?"auto":0,left:ne?0:"auto",marginTop:"4px",background:"#FFFFFF",border:"1px solid #E5E5E5",borderRadius:"8px",boxShadow:"0 4px 16px rgba(0,0,0,0.15)",padding:"8px",zIndex:1e3,minWidth:ne?"280px":"240px",width:ne?"calc(100vw - 24px)":"auto",maxWidth:ne?"calc(100vw - 24px)":"280px"}},a.default.createElement("div",{style:{marginBottom:"custom"===re?"12px":"0"}},["thisMonth","today","tomorrow","currentWeek","currentYear","custom"].map((e=>a.default.createElement("button",{key:e,onClick:()=>{if(le(e),"custom"!==e){const t=(e=>{const t=new Date;let n,o;switch(e){case"today":default:n=o=Y();break;case"tomorrow":const e=new Date(t);e.setDate(e.getDate()+1),n=o=e.toISOString().split("T")[0];break;case"currentWeek":const a=new Date(t),i=new Date(t),r=t.getDay(),l=0===r?-6:1-r;a.setDate(t.getDate()+l),i.setDate(a.getDate()+6),n=a.toISOString().split("T")[0],o=i.toISOString().split("T")[0];break;case"thisMonth":const d=new Date(t.getFullYear(),t.getMonth(),1),s=new Date(t.getFullYear(),t.getMonth()+1,0);n=d.toISOString().split("T")[0],o=s.toISOString().split("T")[0];break;case"currentYear":n=`${t.getFullYear()}-01-01`,o=`${t.getFullYear()}-12-31`}return{from:n,to:o}})(e);ie(e),Ke(t.from),Ze(t.to),tt(t.from),ot(t.to),se(!1)}else tt(""),ot("")},style:{width:"100%",padding:"10px 12px",background:re===e?"#E8EEF4":"#FFFFFF",border:"none",borderRadius:"4px",fontSize:"13px",fontFamily:Et,cursor:"pointer",textAlign:"left",fontWeight:re===e?600:400,color:re===e?"#4C4DDC":"#1a1a1a",marginBottom:"4px",display:"flex",justifyContent:"space-between",alignItems:"center",transition:"all 0.2s ease"},onMouseEnter:t=>{re!==e&&(t.target.style.background="#F5F5F5")},onMouseLeave:t=>{re!==e&&(t.target.style.background="#FFFFFF")}},a.default.createElement("span",null,{thisMonth:"This Month",today:"Today",tomorrow:"Tomorrow",currentWeek:"Current Week",currentYear:"Current Year",custom:"Custom"}[e]),re===e&&a.default.createElement("span",{style:{color:"#4C4DDC",fontSize:"16px"}},"✓"))))),"custom"===re&&a.default.createElement("div",{style:{paddingTop:"8px",borderTop:"1px solid #E5E5E5"}},a.default.createElement("div",{style:{marginBottom:"8px"}},a.default.createElement("input",{type:"date",value:et,onChange:e=>tt(e.target.value),placeholder:"Start Date",style:{width:"100%",padding:"10px 8px",border:"1px solid #E5E5E5",borderRadius:"4px",fontSize:"13px",fontFamily:Et,boxSizing:"border-box",cursor:"pointer"}})),a.default.createElement("div",{style:{marginBottom:"12px"}},a.default.createElement("input",{type:"date",value:nt,onChange:e=>ot(e.target.value),placeholder:"End Date",style:{width:"100%",padding:"10px 8px",border:"1px solid #E5E5E5",borderRadius:"4px",fontSize:"13px",fontFamily:Et,boxSizing:"border-box",cursor:"pointer"}})),a.default.createElement("div",{style:{display:"flex",gap:"8px"}},a.default.createElement("button",{onClick:()=>{le(ae),tt(Je),ot(Qe),se(!1)},style:{flex:1,padding:"10px 12px",background:"#FFFFFF",color:"#4C4DDC",border:"1px solid #4C4DDC",borderRadius:"4px",fontSize:"13px",fontFamily:Et,fontWeight:600,cursor:"pointer"}},"Cancel"),a.default.createElement("button",{onClick:()=>{et&&nt&&(ie("custom"),Ke(et),Ze(nt),se(!1))},style:{flex:1,padding:"10px 12px",background:"#4C4DDC",color:"#FFFFFF",border:"none",borderRadius:"4px",fontSize:"13px",fontFamily:Et,fontWeight:600,cursor:"pointer"}},"Submit")))))),a.default.createElement("div",{style:{display:"flex",flexDirection:ne?"column":"row",gap:ne?"12px":"14px",flex:1,minHeight:0,overflow:ne?"auto":"hidden"}},a.default.createElement("div",{style:{flex:ne?"none":"1 1 65%",width:ne?"100%":"auto",display:"flex",flexDirection:"column",minHeight:ne?"400px":0}},a.default.createElement("div",{style:{background:"#FFFFFF",borderRadius:"8px",boxShadow:"0 1px 4px rgba(0,0,0,0.08)",overflow:"hidden",display:"flex",flexDirection:"column",flex:ne?"none":1,minHeight:ne?"auto":0}},a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:ne?"12px 14px":"14px 18px",borderBottom:"1px solid #F1F1F1"}},a.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:ne?"6px":"8px"}},a.default.createElement("span",{style:{fontSize:ne?"14px":"15px",fontWeight:700,color:"#1a1a1a"}},"Appointments"),a.default.createElement("span",{style:{background:"#4C4DDC",color:"#fff",fontSize:ne?"10px":"11px",fontWeight:600,padding:ne?"2px 7px":"3px 8px",borderRadius:"12px"}},Ge))),a.default.createElement("div",{className:"appointments-header-grid",style:{display:"grid",gridTemplateColumns:ne?"1.5fr 1fr 0.8fr":"2.5fr 1fr 1.5fr 0.8fr 1.2fr",gap:ne?"8px":"12px",padding:ne?"8px 12px":"10px 18px",background:"#F5F5F5",fontSize:ne?"10px":"12px",fontWeight:600,color:"#666"}},a.default.createElement("div",null,"Patients name"),!ne&&a.default.createElement("div",null,"Patient ID"),a.default.createElement("div",{onClick:dt,style:{display:"flex",alignItems:"center",gap:"3px",cursor:"pointer",userSelect:"none"}},"Date",a.default.createElement("span",{style:{opacity:.7,fontSize:"10px"}},"asc"===pe?"▲":"▼")),!ne&&a.default.createElement("div",null,"Slot"),!ne&&a.default.createElement("div",null,"Doctor")),a.default.createElement("div",{style:{overflow:"auto",flex:1}},R?a.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",padding:"40px",color:"#888"}},a.default.createElement("div",{style:{textAlign:"center"}},a.default.createElement("div",{style:{width:"40px",height:"40px",border:"3px solid #f3f3f3",borderTop:"3px solid #4C4DDC",borderRadius:"50%",animation:"spin 1s linear infinite",margin:"0 auto 10px"}}),"Getting token...")):Q?a.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",padding:"40px",color:"#888"}},a.default.createElement("div",{style:{textAlign:"center"}},a.default.createElement("div",{style:{width:"40px",height:"40px",border:"3px solid #f3f3f3",borderTop:"3px solid #4C4DDC",borderRadius:"50%",animation:"spin 1s linear infinite",margin:"0 auto 10px"}}),"Loading appointments...")):ee?a.default.createElement("div",{style:{padding:"40px",textAlign:"center",color:"#FF0000"}},a.default.createElement("div",{style:{fontSize:"16px",marginBottom:"8px"}},"⚠️ Error"),a.default.createElement("div",{style:{fontSize:"13px"}},ee),a.default.createElement("button",{onClick:st,style:{marginTop:"16px",padding:"8px 16px",background:"#4C4DDC",color:"white",border:"none",borderRadius:"6px",cursor:"pointer",fontFamily:Et}},"Retry")):0===qe.length?a.default.createElement("div",{style:{padding:"40px",textAlign:"center",color:"#888"}},a.default.createElement("div",{style:{fontSize:"16px",marginBottom:"8px"}},"📋"),a.default.createElement("div",{style:{fontSize:"13px"}},ue?`No appointments found for "${ue}"`:"No appointments found"),ue&&a.default.createElement("button",{onClick:()=>fe(""),style:{marginTop:"12px",padding:"6px 12px",background:"#4C4DDC",color:"white",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"12px",fontFamily:Et}},"Clear Search")):qe.map((e=>a.default.createElement("div",{key:at(e),role:"button",tabIndex:0,onClick:()=>pt(e),onKeyDown:t=>"Enter"===t.key&&pt(e),className:"appointments-grid",style:{display:"grid",gridTemplateColumns:ne?"1.5fr 1fr 0.8fr":"2.5fr 1fr 1.5fr 0.8fr 1.2fr",gap:ne?"8px":"12px",padding:ne?"10px 12px":"12px 18px",background:at(J)===at(e)?"#E8EEF4":"#FFFFFF",borderTop:"1px solid #F1F1F1",alignItems:"center",cursor:"pointer",fontSize:ne?"11px":"13px"}},a.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:ne?"8px":"10px"}},it(e)?a.default.createElement("img",{src:e.image,alt:"",style:{width:ne?"32px":"36px",height:ne?"32px":"36px",borderRadius:"50%",objectFit:"cover"}}):a.default.createElement("div",{style:{width:ne?"32px":"36px",height:ne?"32px":"36px",borderRadius:"50%",background:lt(e.patientName),display:"flex",alignItems:"center",justifyContent:"center",color:"#FFFFFF",fontWeight:600,fontSize:ne?"14px":"16px"}},rt(e.patientName)),a.default.createElement("div",null,a.default.createElement("div",{style:{fontWeight:600,color:"#1a1a1a",fontSize:ne?"11px":"13px"}},e.patientName),a.default.createElement("div",{style:{fontSize:ne?"9px":"11px",color:"#888"}},e.email))),!ne&&a.default.createElement("div",{style:{color:"#555",fontSize:"12px"}},e.patientId),a.default.createElement("div",{style:{color:"#555",fontSize:ne?"10px":"12px"}},(()=>{const t=e.appointmentDate||"",n=t.match(/\s(\d{1,2}:\d{2}(?:\s*(?:AM|PM))?)$/i);return n?a.default.createElement(a.default.Fragment,null,a.default.createElement("div",null,t.slice(0,n.index).trim()),a.default.createElement("div",{style:{fontSize:ne?"9px":"11px",color:"#888"}},n[1].trim())):a.default.createElement("div",null,t)})()),!ne&&a.default.createElement("div",{style:{color:"#555",fontSize:"12px"}},e.appointmentTime||"-"),!ne&&a.default.createElement("div",{style:{color:"#555",fontSize:"12px"}},e.doctorName||e.doctor||"-"))))),!Q&&!ee&&qe.length>0&&a.default.createElement("div",{style:{padding:ne?"12px 14px":"14px 18px",borderTop:"1px solid #F1F1F1",display:"flex",justifyContent:"space-between",alignItems:"center",background:"#FFFFFF",flexWrap:ne?"wrap":"nowrap",gap:ne?"10px":"0"}},a.default.createElement("div",{style:{fontSize:ne?"11px":"12px",color:"#666"}},"Showing page ",$e," of ",Xe," (",Ge," total)"),a.default.createElement("div",{style:{display:"flex",gap:"6px",alignItems:"center"}},a.default.createElement("button",{onClick:()=>_e((e=>Math.max(1,e-1))),disabled:1===$e,style:{padding:ne?"6px 10px":"6px 12px",border:"1px solid #E5E5E5",borderRadius:"4px",background:1===$e?"#F5F5F5":"#FFFFFF",color:1===$e?"#999":"#1a1a1a",fontSize:ne?"11px":"12px",fontFamily:Et,fontWeight:600,cursor:1===$e?"not-allowed":"pointer",opacity:1===$e?.5:1}},"Previous"),a.default.createElement("div",{style:{display:"flex",gap:"4px"}},[...Array(Math.min(5,Xe))].map(((e,t)=>{let n;return n=Xe<=5||$e<=3?t+1:$e>=Xe-2?Xe-4+t:$e-2+t,a.default.createElement("button",{key:n,onClick:()=>_e(n),style:{padding:ne?"6px 10px":"6px 12px",border:$e===n?"none":"1px solid #E5E5E5",borderRadius:"4px",background:$e===n?"#4C4DDC":"#FFFFFF",color:$e===n?"#FFFFFF":"#1a1a1a",fontSize:ne?"11px":"12px",fontFamily:Et,fontWeight:600,cursor:"pointer",minWidth:ne?"32px":"36px"}},n)}))),a.default.createElement("button",{onClick:()=>_e((e=>Math.min(Xe,e+1))),disabled:$e===Xe,style:{padding:ne?"6px 10px":"6px 12px",border:"1px solid #E5E5E5",borderRadius:"4px",background:$e===Xe?"#F5F5F5":"#FFFFFF",color:$e===Xe?"#999":"#1a1a1a",fontSize:ne?"11px":"12px",fontFamily:Et,fontWeight:600,cursor:$e===Xe?"not-allowed":"pointer",opacity:$e===Xe?.5:1}},"Next"))))),a.default.createElement("div",{style:{flex:ne?"none":"1 1 35%",width:ne?"100%":"auto",display:J||!ne?"flex":"none",flexDirection:"column",minHeight:ne?"auto":0}},a.default.createElement("div",{style:{border:"1px solid #E5E5E5",borderRadius:"8px",overflow:"hidden",background:"#FFFFFF",boxShadow:"0 1px 4px rgba(0,0,0,0.08)",display:"flex",flexDirection:"column",flex:ne?"none":1,minHeight:ne?"auto":0}},J?a.default.createElement(a.default.Fragment,null,a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:ne?"12px 14px":"16px 18px",background:"#E8EEF4",borderBottom:"1px solid #E5E5E5"}},a.default.createElement("div",null,a.default.createElement("div",{style:{color:"#002668",fontSize:ne?"14px":"16px",fontWeight:"700"}},J.patientName||"N/A"),a.default.createElement("div",{style:{color:"#002668",fontSize:ne?"11px":"13px"}},J.patientId||J.mrn||"N/A")),a.default.createElement("div",null,it(J)?a.default.createElement("img",{style:{width:ne?"36px":"44px",height:ne?"36px":"44px",borderRadius:"50%",objectFit:"cover"},src:J.image,alt:J.patientName}):a.default.createElement("div",{style:{width:ne?"36px":"44px",height:ne?"36px":"44px",borderRadius:"50%",background:lt(J.patientName),display:"flex",alignItems:"center",justifyContent:"center",color:"#FFFFFF",fontWeight:700,fontSize:ne?"16px":"20px"}},rt(J.patientName)))),a.default.createElement("div",{style:{padding:ne?"12px 14px":"14px 18px",gap:ne?"10px":"12px",display:"flex",flexDirection:"column",background:"white",overflow:"auto",flex:1,position:"relative"}},a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Speciality"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ne?"12px":"13px"}},J?.specialisation||J?.speciality||"N/A")),a.default.createElement("div",{style:{textAlign:"right"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Appointment Type"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ne?"12px":"13px"}},J?.type||J?.appointmentType||"Online"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Appointment Date"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ne?"12px":"13px"}},J?.date||J?.appointmentDate||"N/A")),a.default.createElement("div",{style:{textAlign:"right"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Appointment Time"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ne?"12px":"13px"}},J?.time||J?.appointmentTime||"N/A"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Doctor"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ne?"12px":"13px"}},J?.doctor||J?.doctorName||"N/A"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Hospital"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ne?"12px":"13px"}},J?.hospital||J?.hospitalName||"N/A"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ne?"10px":"11px",color:"#888",marginBottom:"3px"}},"Reason for Appointment"),a.default.createElement("div",{style:{fontWeight:"600",fontSize:ne?"11px":"12px",lineHeight:"1.4"}},J?.reason||J?.reasonForAppointment||"No reason provided"))),"upcoming"===V&&a.default.createElement("div",{style:{display:"flex",flexDirection:ne?"column":"row",gap:"6px",marginTop:"10px"}},a.default.createElement("button",{type:"button",onClick:ct,disabled:ve,style:{flex:1,background:ve?"#99e4e8":"#1CC3CE",color:"#FFFFFF",border:"1px solid #1CC3CE",borderRadius:"6px",padding:ne?"10px 8px":"8px 6px",fontFamily:Et,fontWeight:600,fontSize:ne?"11px":"12px",cursor:ve?"not-allowed":"pointer"}},ve?"Connecting...":"Join Call >")),"upcoming"===V&&Ce&&a.default.createElement("div",{style:{fontSize:"11px",color:"#e53935",marginTop:"6px",textAlign:"center",width:"100%"}},"⚠️ ",Ce))):a.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100%",padding:"40px",color:"#888",textAlign:"center"}},a.default.createElement("div",null,a.default.createElement("div",{style:{fontSize:"16px",marginBottom:"8px"}},"📋"),a.default.createElement("div",{style:{fontSize:"13px"}},"Select an appointment to view details"))))))),me&&a.default.createElement("div",{style:{position:"fixed",left:ye?"0":ne?"10px":`${De.x}px`,top:ye?"0":ne?"70px":`${De.y}px`,right:ye?"0":ne?"10px":"auto",bottom:ye?"0":"auto",width:ye?"100vw":ne?"calc(100vw - 20px)":ge?"350px":`${We.width}px`,height:ye?"100vh":ge?"auto":ne?"300px":`${We.height}px`,background:"#FFFFFF",borderRadius:ye?"0":"8px",boxShadow:"0 8px 24px rgba(0, 0, 0, 0.3)",zIndex:1e4,overflow:"hidden",display:"flex",flexDirection:"column",transition:Me||Pe?"none":"all 0.3s ease"}},a.default.createElement("div",{onPointerDown:ne||ye?void 0:xt,onPointerMove:ne||ye?void 0:gt,onPointerUp:ne||ye?void 0:ht,onPointerCancel:ne||ye?void 0:ht,style:{background:"linear-gradient(135deg, #4C4DDC 0%, #3A3BBD 100%)",color:"#FFFFFF",padding:ne?"8px 10px":"10px 12px",display:"flex",justifyContent:"space-between",alignItems:"center",cursor:ne||ye?"default":"move",userSelect:"none"}},a.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:ne?"6px":"8px",flex:1,minWidth:0}},a.default.createElement("div",{style:{width:ne?"6px":"8px",height:ne?"6px":"8px",borderRadius:"50%",background:"#FF4444",animation:"pulse 2s infinite",flexShrink:0}}),a.default.createElement("span",{style:{fontSize:ne?"11px":"13px",fontWeight:600,fontFamily:Et,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},"Video Call - ",J?.patientName||"Patient")),a.default.createElement("div",{style:{display:"flex",gap:ne?"4px":"6px",alignItems:"center",flexShrink:0}},!ye&&a.default.createElement("button",{onClick:ft,style:{background:"rgba(255, 255, 255, 0.2)",border:"1px solid rgba(255, 255, 255, 0.3)",borderRadius:"6px",color:"#FFFFFF",cursor:"pointer",padding:ne?"5px 8px":"6px 10px",lineHeight:1,display:"flex",alignItems:"center",justifyContent:"center",minWidth:ne?"28px":"32px",height:ne?"28px":"32px",transition:"background 0.2s ease"},onMouseEnter:e=>e.target.style.background="rgba(255, 255, 255, 0.3)",onMouseLeave:e=>e.target.style.background="rgba(255, 255, 255, 0.2)",title:ge?"Restore":"Minimize"},ge?a.default.createElement("svg",{width:ne?"14":"16",height:ne?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("rect",{x:"3",y:"3",width:"10",height:"10",stroke:"white",strokeWidth:"1.8",fill:"none"})):a.default.createElement("svg",{width:ne?"14":"16",height:ne?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("line",{x1:"3",y1:"8",x2:"13",y2:"8",stroke:"white",strokeWidth:"1.8",strokeLinecap:"round"}))),a.default.createElement("button",{onClick:mt,style:{background:"rgba(255, 255, 255, 0.2)",border:"1px solid rgba(255, 255, 255, 0.3)",borderRadius:"6px",color:"#FFFFFF",cursor:"pointer",padding:ne?"5px 8px":"6px 10px",lineHeight:1,display:"flex",alignItems:"center",justifyContent:"center",minWidth:ne?"28px":"32px",height:ne?"28px":"32px",transition:"background 0.2s ease"},onMouseEnter:e=>e.target.style.background="rgba(255, 255, 255, 0.3)",onMouseLeave:e=>e.target.style.background="rgba(255, 255, 255, 0.2)",title:ye?"Exit Fullscreen":"Fullscreen"},ye?a.default.createElement("svg",{width:ne?"14":"16",height:ne?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("path",{d:"M10 3H13V6M6 13H3V10M13 10V13H10M3 6V3H6",stroke:"white",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})):a.default.createElement("svg",{width:ne?"14":"16",height:ne?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("path",{d:"M3 6V3H6M13 10V13H10M10 3H13V6M6 13H3V10",stroke:"white",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"}))),a.default.createElement("button",{onClick:ut,style:{background:"rgba(255, 255, 255, 0.2)",border:"1px solid rgba(255, 255, 255, 0.3)",borderRadius:"6px",color:"#FFFFFF",cursor:"pointer",padding:ne?"5px 8px":"6px 10px",lineHeight:1,display:"flex",alignItems:"center",justifyContent:"center",minWidth:ne?"28px":"32px",height:ne?"28px":"32px",fontWeight:"bold",fontSize:ne?"18px":"22px",transition:"background 0.2s ease"},onMouseEnter:e=>e.target.style.background="rgba(255, 255, 255, 0.3)",onMouseLeave:e=>e.target.style.background="rgba(255, 255, 255, 0.2)",title:"Close"},"×"))),!ge&&a.default.createElement("div",{style:{flex:1,background:"#000000",position:"relative"}},a.default.createElement("iframe",{src:(()=>{if(!Fe)return"";const e=String($||"").replace(/\/?$/,"/");return console.log("${base}token=${callToken}",`${e}token=${Fe}`),`${e}token=${Fe}`})(),style:{width:"100%",height:"100%",border:"none"},allow:"camera; microphone; display-capture; autoplay",allowFullScreen:!0,title:"Video Call"})),!ne&&!ye&&!ge&&a.default.createElement(a.default.Fragment,null,a.default.createElement("div",{onPointerDown:e=>yt("top-left",e),onPointerMove:gt,onPointerUp:ht,onPointerCancel:ht,style:{position:"absolute",left:0,top:0,width:"16px",height:"16px",cursor:"nwse-resize",background:"transparent",zIndex:10001}}),a.default.createElement("div",{onPointerDown:e=>yt("top-right",e),onPointerMove:gt,onPointerUp:ht,onPointerCancel:ht,style:{position:"absolute",right:0,top:0,width:"16px",height:"16px",cursor:"nesw-resize",background:"transparent",zIndex:10001}}),a.default.createElement("div",{onPointerDown:e=>yt("bottom-left",e),onPointerMove:gt,onPointerUp:ht,onPointerCancel:ht,style:{position:"absolute",left:0,bottom:0,width:"16px",height:"16px",cursor:"nesw-resize",background:"transparent",zIndex:10001}}),a.default.createElement("div",{onPointerDown:e=>yt("bottom-right",e),onPointerMove:gt,onPointerUp:ht,onPointerCancel:ht,style:{position:"absolute",right:0,bottom:0,width:"16px",height:"16px",cursor:"nwse-resize",background:"transparent",zIndex:10001}})),a.default.createElement("style",null,"\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n "))),Ft&&a.default.createElement("div",{style:{position:"fixed",inset:0,zIndex:1e5,display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",background:"rgba(0,0,0,0.4)",boxSizing:"border-box"}},a.default.createElement("div",{style:{fontFamily:Et,maxWidth:"400px",width:"100%",padding:"32px 24px",background:"#FFFFFF",borderRadius:"12px",boxShadow:"0 8px 32px rgba(0,0,0,0.2)",textAlign:"center"}},a.default.createElement("div",{style:{fontSize:"48px",marginBottom:"16px"}},"🔒"),a.default.createElement("h2",{style:{fontSize:"20px",fontWeight:700,color:"#1a1a1a",margin:"0 0 8px 0"}},P?"Not authorised":"Sign in required"),a.default.createElement("p",{style:{fontSize:"14px",color:"#666",margin:0,lineHeight:1.5}},bt),a.default.createElement("p",{style:{fontSize:"13px",color:"#999",marginTop:"16px",marginBottom:0}},"Redirecting to login...")))),a.default.createElement(b,null,wt)};let S=null;const v={showWidget:(e,t)=>{S||(S=document.createElement("div"),document.body.appendChild(S));const n=()=>a.default.createElement(a.default.Fragment,null,a.default.createElement(w,{config:e}));i.default.render(a.default.createElement(n,null),S)},closePopup:()=>{S&&(i.default.unmountComponentAtNode(S),S=null)}};window.BookingSDK=v,e.AppointmentPage=w,e.PIH_APPOINTMENT_WIDGET_CLASS=E,e.default=v,Object.defineProperty(e,"__esModule",{value:!0})}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MyPackage={},e.React,e.ReactDOM)}(this,(function(e,t,n){"use strict";function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=o(t),i=o(n);const l="/appointment/V1/consultant/all-appointments",r="/notification/V1/consultation/online/initiate",d="https://wbafedevittisalwe01-had2b3e0a7h6fyey.westeurope-01.azurewebsites.net/call/",p=async function(e,t,n,o){let a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{},i=(e||"").toUpperCase();"INPROGRESS"===i&&(i="IN_PROGRESS");const r=a.apiBaseUrl,d=a.hospitalId,p=a.doctorId,s=a.token||"",c={hospitalId:d,doctorId:p,fromDate:t,toDate:n,statuses:i};o&&"ALL"!==String(o).toUpperCase()&&(c.appointmentType=String(o).toUpperCase());const u=`${r}${l}`,f=await async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";const o=new URL(e);return o.search=new URLSearchParams(t).toString(),fetch(o,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`${n}`}}).then((async e=>{const t=await e.json().catch((()=>({})));return e.ok?t:{err:t?.resultInfo?.message||"Something went wrong!",status:e.status}})).catch((e=>(console.error("Fetch error:",e),{err:e?.message||String(e)||"Network error"})))}(u,c,"PIH-Appointment-Widget",s);return f},s=async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};console.log("initiateConsultation -> config",t);const n=`${t.apiBaseUrl.replace(/\/$/,"")}${r}`,o=t.appToken||"";return async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=arguments.length>4?arguments[4]:void 0;const a=new URL(e);Object.keys(n).forEach((e=>{a.searchParams.append(e,n[e])}));const i={"Content-Type":"application/json"};o&&(i.Authorization=o);const l={method:"POST",headers:i,body:JSON.stringify(t)};return fetch(a.toString(),l).then((async e=>{const t=await e.json().catch((()=>({})));return e.ok?t:{err:t?.resultInfo?.message||"Something went wrong!",status:e.status}})).catch((e=>(console.error("Fetch error:",e),{err:e.message||"Network error"})))}(n,{patientId:String(e.patientId||""),primaryPatientId:String(e.primaryPatientId||e.patientId||""),hospitalId:t.hospitalId,doctorId:String(t.doctorId),patientName:e.patientName||e.name||"",doctorName:e.doctorName||t.doctorName,appointmentId:String(e.id||e.appointmentId||e._id||"")},"PIH-Appointment-Widget",{},o)};const c="pih_appointment_idToken",u="pih_appointment_email",f="pih_appointment_appToken",m="pih_appointment_doctorId",x="pih_appointment_userName",g="pih_appointment_apiBaseUrl",h="pih_appointment_hospitalId",y=720,E="pih-appointment-widget",F="data-pih-widget";class b extends t.Component{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,t){"undefined"!=typeof console&&console.error&&console.error("Appointment widget error:",e,t)}render(){return this.state.hasError?a.default.createElement("div",{className:E,[F]:"teleconsult-appointments",style:{fontFamily:'"Nunito", serif',background:"#F5F5F7",boxSizing:"border-box",minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",textAlign:"center"}},a.default.createElement("div",{style:{maxWidth:"400px"}},a.default.createElement("div",{style:{fontSize:"48px",marginBottom:"16px"}},"⚠️"),a.default.createElement("h2",{style:{fontSize:"20px",fontWeight:700,color:"#1a1a1a",margin:"0 0 8px 0"}},"Something went wrong"),a.default.createElement("p",{style:{fontSize:"14px",color:"#666",margin:0,lineHeight:1.5}},"Please refresh the page or try again later."))):this.props.children}}const w=e=>{let{config:n={}}=e;const[o,i]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(g):null}catch{return null}})),[l,r]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(h):null}catch{return null}})),w=n.apiBaseUrl||o||"https://afiyaapiqa.powermindinc.com",S=n.hospitalId||l,[v,k]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(c):null}catch{return null}})),[C,I]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(u):null}catch{return null}})),D=n.idToken||n.token||v,z=n.email||C;t.useEffect((()=>{try{if("undefined"==typeof localStorage)return;const e=n.idToken||n.token;if(e&&String(e).trim()){localStorage.getItem(c)!==e&&(M(null),A(null),N(null),localStorage.removeItem(f),localStorage.removeItem(m),localStorage.removeItem(x)),localStorage.setItem(c,e),k(e)}n.email&&String(n.email).trim()&&(localStorage.setItem(u,n.email),I(n.email)),n.apiBaseUrl&&String(n.apiBaseUrl).trim()&&(localStorage.setItem(g,n.apiBaseUrl.trim()),i(n.apiBaseUrl.trim())),null!=n.hospitalId&&String(n.hospitalId).trim()&&(localStorage.setItem(h,String(n.hospitalId).trim()),r(String(n.hospitalId).trim()))}catch(e){}}),[n.idToken,n.token,n.email,n.apiBaseUrl,n.hospitalId]);const[W,M]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(f):null}catch{return null}})),[T,A]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(m):null}catch{return null}})),[R,N]=t.useState((()=>{try{return"undefined"!=typeof localStorage?localStorage.getItem(x):null}catch{return null}})),[P,j]=t.useState((()=>{try{if("undefined"==typeof localStorage)return!1;const e=localStorage.getItem(f),t=localStorage.getItem(c),n=localStorage.getItem(u);return!e&&!(!t||!n)}catch{return!1}})),[B,L]=t.useState(null),[H,U]=t.useState(!1),[O,$]=t.useState(0);t.useEffect((()=>{W&&P&&j(!1)}),[W,P]),t.useEffect((()=>{W||(D&&z?(U(!1),L((e=>"Sign in required. Redirecting to home..."===e?null:e))):(L("Sign in required. Redirecting to home..."),U(!0)))}),[W,D,z]),t.useEffect((()=>{if(!H)return;const e=n.homeUrl||"https://wbaemrdevittisalwe01-fnapdpfme7bvduhh.westeurope-01.azurewebsites.net/";if(!e||"undefined"==typeof window)return;const t=setTimeout((()=>{window.location.href=e}),2500);return()=>clearTimeout(t)}),[H,n.homeUrl]),t.useEffect((()=>{if(!P)return;const e=setTimeout((()=>{L("Request timed out. Please try again."),j(!1)}),3e4);return()=>clearTimeout(e)}),[P]);const _=n.joinCallUrl||d;W&&String(_||"").replace(/\/?$/,"/");const Y=function(e){if(!e||"string"!=typeof e)return{};try{const t=e.split(".");if(3!==t.length)return{};const n=t[1].replace(/-/g,"+").replace(/_/g,"/"),o=n.padEnd(n.length+(4-n.length%4)%4,"=");return JSON.parse(atob(o))}catch{return{}}}(D),V=R||Y.name||Y.sub||"User",q=()=>(new Date).toISOString().split("T")[0],[X,G]=t.useState("upcoming"),[J,K]=t.useState([]),[Q,Z]=t.useState(null),[ee,te]=t.useState(!1),[ne,oe]=t.useState(null),[ae,ie]=t.useState(window.innerWidth<768),[le,re]=t.useState("today"),[de,pe]=t.useState("today"),[se,ce]=t.useState(!1),[ue,fe]=t.useState(!1),[me,xe]=t.useState("all"),[ge,he]=t.useState("asc"),[ye,Ee]=t.useState(""),[Fe,be]=t.useState(!1),[we,Se]=t.useState(!1),[ve,ke]=t.useState(!1),[Ce,Ie]=t.useState(null),[De,ze]=t.useState(null),[We,Me]=t.useState(!1),[Te,Ae]=t.useState(null),[Re,Ne]=t.useState((()=>({x:Math.max(20,"undefined"!=typeof window?window.innerWidth-y-20:300),y:80}))),[Pe,je]=t.useState({width:y,height:560}),[Be,Le]=t.useState(!1),[He,Ue]=t.useState({x:0,y:0}),[Oe,$e]=t.useState(!1),[_e,Ye]=t.useState(null),[Ve,qe]=t.useState({x:0,y:0,width:0,height:0});t.useState(!1);const[Xe,Ge]=t.useState(1),Je=J.filter((e=>{if(!ye.trim())return!0;const t=ye.toLowerCase(),n=(e.patientName||"").toLowerCase(),o=String(e.patientId||"").toLowerCase();return n.includes(t)||o.includes(t)})),Ke=20*(Xe-1),Qe=Ke+20,Ze=Je.slice(Ke,Qe),et=Math.ceil(Je.length/20),tt=Je.length,[nt,ot]=t.useState(q()),[at,it]=t.useState(q()),[lt,rt]=t.useState(),[dt,pt]=t.useState(),st=e=>e?.id||e?._id||e?.appointmentId||e?.patientId||JSON.stringify(e),ct=e=>e?.image?e.image:null,ut=e=>e?e.charAt(0).toUpperCase():"?",ft=e=>{if(!e)return"#4C4DDC";const t=["#4C4DDC","#1CC3CE","#FF6B6B","#4ECDC4","#45B7D1","#FFA07A","#98D8C8","#F7DC6F"];return t[e.charCodeAt(0)%t.length]},mt=()=>{const e="asc"===ge?"desc":"asc";he(e);const t=[...J].sort(((t,n)=>{const o=new Date(t.appointmentDate||t.date||0),a=new Date(n.appointmentDate||n.date||0);return"asc"===e?o-a:a-o}));K(t),Ge(1),t.length>0&&Z(t[0])},xt=t.useCallback((async e=>{if(!W)return;console.log(T,"fetchAppointments -> doctorIdFromLogin");const t=T,n=void 0!==e?e:me;te(!0),oe(null);try{const e={apiBaseUrl:w,hospitalId:S,doctorId:t,token:W},o=await p(X,nt,at,n,e);if(401===o.status||403===o.status){try{"undefined"!=typeof localStorage&&(localStorage.removeItem(f),localStorage.removeItem(m),localStorage.removeItem(x))}catch(e){}return M(null),A(null),N(null),$((e=>e+1)),void oe("Session expired. Re-authenticating...")}if(o.err)return void oe(String(o.err||"Failed to fetch appointments"));const a=o.data||o.appointments||o||[];K(Array.isArray(a)?a:[]),Array.isArray(a)&&a.length>0?Z(a[0]):Z(null)}catch(e){console.error("Error fetching appointments:",e),oe(e.message||"Failed to fetch appointments")}finally{te(!1)}}),[X,nt,at,me,w,S,T,W]),gt=e=>{Z(e)},ht=async()=>{if(Q&&W){Me(!0),Ae(null);try{const e={apiBaseUrl:w,hospitalId:S,doctorId:T,doctorName:R||V,appToken:W};console.log(Q,"selectedAppointment"),console.log(e,"callConfig");const t=await s(Q,e);if(401===t.status||403===t.status)return Ae("Session expired. Please try again."),void Me(!1);if(t.err||!t.data?.token)return Ae(String(t.err||"Failed to initiate call")),void Me(!1);const o=n.joinCallUrl||d,a=t.data.token?String(o||"").replace(/\/?$/,"/")+t.data.token:"";console.log("joinCallUrl",a),Ie(t.data.token),ze(a||""),be(!0),Se(!1),ke(!1),je({width:y,height:560}),Ne({x:Math.max(20,window.innerWidth-y-20),y:80})}catch(e){Ae(e.message||"Failed to initiate call")}finally{Ae(null),Me(!1)}}},yt=()=>{be(!1),Se(!1),ke(!1),Ie(null),ze(null),Ae(null),xt()},Et=()=>{ve&&ke(!1),Se(!we)},Ft=()=>{we&&Se(!1),ke(!ve)},bt=e=>{if(0!==e.button)return;if(e.target.closest("button"))return;e.currentTarget.setPointerCapture&&e.currentTarget.setPointerCapture(e.pointerId),Le(!0);const t=e.currentTarget.getBoundingClientRect();Ue({x:e.clientX-t.left,y:e.clientY-t.top})},wt=t.useCallback((e=>{if(!ve)if(Be){const t=e.clientX-He.x,n=e.clientY-He.y,o=window.innerWidth-Pe.width,a=window.innerHeight-Pe.height;Ne({x:Math.max(0,Math.min(t,o)),y:Math.max(0,Math.min(n,a))})}else if(Oe){const t=e.clientX-Ve.x,n=e.clientY-Ve.y;let o=Ve.width,a=Ve.height,i=Ve.posX,l=Ve.posY;const r=300,d=250,p=window.innerWidth-40,s=window.innerHeight-100;if("bottom-right"===_e)o=Math.min(Math.max(Ve.width+t,r),p),a=Math.min(Math.max(Ve.height+n,d),s),i+o>window.innerWidth&&(o=window.innerWidth-i),l+a>window.innerHeight&&(a=window.innerHeight-l);else if("bottom-left"===_e){o=Math.min(Math.max(Ve.width-t,r),p),i=Math.max(0,Ve.posX+t),0===i&&(o=Ve.posX+Ve.width),a=Math.min(Math.max(Ve.height+n,d),s),l+a>window.innerHeight&&(a=window.innerHeight-l)}else if("top-right"===_e){o=Math.min(Math.max(Ve.width+t,r),p),i+o>window.innerWidth&&(o=window.innerWidth-i);a=Math.min(Math.max(Ve.height-n,d),s),l=Math.max(0,Ve.posY+n),0===l&&(a=Ve.posY+Ve.height)}else if("top-left"===_e){o=Math.min(Math.max(Ve.width-t,r),p),i=Math.max(0,Ve.posX+t),0===i&&(o=Ve.posX+Ve.width);a=Math.min(Math.max(Ve.height-n,d),s),l=Math.max(0,Ve.posY+n),0===l&&(a=Ve.posY+Ve.height)}je({width:o,height:a}),Ne({x:i,y:l})}}),[Be,Oe,He,_e,Ve,Re,Pe,ve]),St=()=>{Le(!1),$e(!1),Ye(null)},vt=(e,t)=>{t.preventDefault(),t.stopPropagation(),t.currentTarget.setPointerCapture&&t.currentTarget.setPointerCapture(t.pointerId),$e(!0),Ye(e),qe({x:t.clientX,y:t.clientY,width:Pe.width,height:Pe.height,posX:Re.x,posY:Re.y})};t.useEffect((()=>{if(!Fe||ve)return;const e=()=>{if(!(window.innerWidth<768)){const e=we?350:Pe.width,t=we?60:Pe.height,n=window.innerWidth-40,o=window.innerHeight-100,a=Math.min(e,n),i=Math.min(t,o);a===Pe.width&&i===Pe.height||je({width:a,height:i});const l=window.innerWidth-a-20,r=window.innerHeight-i-20;Ne((e=>({x:Math.min(e.x,l),y:Math.min(e.y,r)})))}};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)}),[Fe,we,ve,Pe]),t.useEffect((()=>{if(!(D&&z&&(!W||O>0)))return;let e=!1;return j(!0),L(null),(async(e,t,n,o)=>{const a=`${e.replace(/\/$/,"")}/um/user/V1/sso/login?hospitalId=${encodeURIComponent(t)}`,i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({idToken:n,email:o})};return console.log("[getTokenFromSso] request",{url:a,body:{idToken:n?n.slice(0,50)+"...":null,email:o}}),fetch(a,i).then((e=>(console.log("[getTokenFromSso] response status",e.status,e.statusText),e.ok?e.json().then((e=>(console.log("[getTokenFromSso] success",{hasData:!!e,dataKeys:e?Object.keys(e):[],hasAccessToken:!!e?.data?.access_token}),e))):e.json().then((t=>{const n=t?.resultInfo?.message||"SSO login failed";return console.log("[getTokenFromSso] error body",t),{err:n,status:e.status}})).catch((()=>({err:"Something went wrong!",status:e.status})))))).catch((e=>(console.error("[getTokenFromSso] catch",e),{err:e.message||"Network error"})))})(w,S,D,z).then((t=>{if(e)return;const n=function(e){return!e||e.err?null:e.data?.access_token??e.data?.token??e.token??e.accessToken??null}(t);if(400===t.status)return L(t.err||"Invalid request. Redirecting to home..."),j(!1),void U(!0);if(t.err||!n){L(String(t.err||"Failed to get token")),M(null),A(null),N(null);try{"undefined"!=typeof localStorage&&(localStorage.removeItem(f),localStorage.removeItem(m),localStorage.removeItem(x))}catch(e){}}else{const e=function(e){if(!e?.data)return null;const t=e.data.doctor_id??e.data.doctorId??null;return console.log(t,"extractDoctorIdFromLoginResponse -> id"),null!=t?String(t):null}(t);console.log(e,"extractDoctorIdFromLoginResponse -> doctorId");const o=function(e){if(!e?.data)return null;const t=e.data.name??e.data.doctor_name??e.data.userName??null;return null!=t?String(t):null}(t);M(n),A(e),N(o),L(null),U(!1);try{"undefined"!=typeof localStorage&&(localStorage.setItem(f,n),e&&localStorage.setItem(m,e),o&&localStorage.setItem(x,o))}catch(e){}}})).catch((()=>{})).finally((()=>{e||j(!1)})),()=>{e=!0}}),[w,S,D,z,O]),t.useEffect((()=>{Ge(1)}),[X,le,nt,at,ye,me]),t.useEffect((()=>{!P&&W&&xt()}),[xt,W,P]),t.useEffect((()=>{const e=document.createElement("link");e.href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap",e.rel="stylesheet",document.head.appendChild(e);const t=document.createElement("style");t.innerHTML="\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n @media (max-width: 768px) {\n .appointments-grid {\n grid-template-columns: 1.5fr 1fr 0.8fr !important;\n }\n .appointments-header-grid {\n grid-template-columns: 1.5fr 1fr 0.8fr !important;\n }\n .hide-on-mobile {\n display: none !important;\n }\n }\n @media (max-width: 480px) {\n .appointments-header-grid {\n font-size: 10px !important;\n }\n .appointments-grid {\n font-size: 11px !important;\n }\n }\n ",document.head.appendChild(t);const n=()=>{ie(window.innerWidth<768)};return window.addEventListener("resize",n),()=>{document.head.removeChild(e),document.head.removeChild(t),window.removeEventListener("resize",n)}}),[]),t.useEffect((()=>{const e=e=>{!se||e.target.closest("button")||e.target.closest('input[type="date"]')||ce(!1),ue&&!e.target.closest("[data-appointment-type-picker]")&&fe(!1)};return document.addEventListener("click",e),()=>{document.removeEventListener("click",e)}}),[se,ue]);let kt='"Nunito", serif';const Ct=B||!W&&(!D||!z),It=B||"Sign in required. Redirecting to home...";let Dt;return Dt=P&&D&&z?a.default.createElement("div",{className:E,[F]:"teleconsult-appointments",style:{fontFamily:kt,background:"#F5F5F7",boxSizing:"border-box",height:"100%",minHeight:"100vh",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"24px"}},a.default.createElement("style",null,"@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }"),a.default.createElement("div",{style:{width:"40px",height:"40px",border:"3px solid #f3f3f3",borderTop:"3px solid #4C4DDC",borderRadius:"50%",animation:"spin 1s linear infinite",marginBottom:"16px"}}),a.default.createElement("p",{style:{fontSize:"14px",color:"#666",margin:0}},"Checking authorisation...")):a.default.createElement(a.default.Fragment,null,a.default.createElement("div",{className:E,[F]:"teleconsult-appointments",style:{fontFamily:kt,background:"#F5F5F7",boxSizing:"border-box",height:"100%",minHeight:"100vh",width:"100%",display:"flex",flexDirection:"column",overflow:"hidden"}},a.default.createElement("div",{style:{background:"#FFFFFF",padding:ae?"10px 12px":"12px 24px",display:"flex",justifyContent:"space-between",alignItems:"center",borderBottom:"1px solid #E5E5E5",flexWrap:"nowrap",gap:ae?"8px":"0"}},a.default.createElement("div",{style:{position:"relative",width:ae?"calc(100% - 90px)":"480px",maxWidth:ae?"none":"480px"}},a.default.createElement("input",{type:"text",placeholder:"Search by patient name or ID",value:ye,onChange:e=>Ee(e.target.value),style:{width:"100%",padding:ae?"8px 32px 8px 10px":"8px 36px 8px 14px",border:"1px solid #E5E5E5",borderRadius:"6px",fontSize:ae?"12px":"13px",fontFamily:kt,background:"#FFFFFF",outline:"none",boxSizing:"border-box"}}),ye&&a.default.createElement("button",{onClick:()=>Ee(""),style:{position:"absolute",right:"8px",top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",padding:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"#999",fontSize:"16px"},title:"Clear search"},"✕")),!1),a.default.createElement("div",{style:{padding:ae?"12px":"16px 24px",flex:1,minHeight:0,overflow:"hidden",display:"flex",flexDirection:"column"}},a.default.createElement("div",{style:{marginBottom:ae?"10px":"14px"}},a.default.createElement("h1",{style:{fontSize:ae?"18px":"22px",fontWeight:700,color:"#1a1a1a",margin:"0 0 2px 0"}},"Tele Consultation"),a.default.createElement("p",{style:{fontSize:ae?"11px":"12px",color:"#999",margin:0}},"Displaying All Tele Consultation Appointments")),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:ae?"flex-start":"center",marginBottom:ae?"10px":"14px",flexDirection:ae?"column":"row",gap:ae?"12px":"0"}},a.default.createElement("div",{style:{display:"flex",gap:"6px",flexWrap:"wrap",width:ae?"100%":"auto"}},a.default.createElement("button",{onClick:()=>G("upcoming"),style:{background:"upcoming"===X?"#4C4DDC":"#FFFFFF",padding:ae?"8px 10px":"9px 16px",border:"upcoming"===X?"none":"1px solid #E5E5E5",borderRadius:"6px",fontSize:ae?"10px":"13px",color:"upcoming"===X?"white":"#555555",fontWeight:600,fontFamily:kt,cursor:"pointer",flex:ae?"1 1 auto":"none",minWidth:ae?"0":"auto",transition:"all 0.3s ease",whiteSpace:"nowrap"}},"Upcoming Appointments"),a.default.createElement("button",{onClick:()=>G("completed"),style:{background:"completed"===X?"#4C4DDC":"#FFFFFF",padding:ae?"8px 10px":"9px 16px",border:"completed"===X?"none":"1px solid #E5E5E5",borderRadius:"6px",fontSize:ae?"10px":"13px",color:"completed"===X?"white":"#555555",fontWeight:600,fontFamily:kt,cursor:"pointer",flex:ae?"1 1 auto":"none",minWidth:ae?"0":"auto",transition:"all 0.3s ease",whiteSpace:"nowrap"}},"Completed Appointments"),a.default.createElement("button",{onClick:()=>G("cancelled"),style:{background:"cancelled"===X?"#4C4DDC":"#FFFFFF",padding:ae?"8px 10px":"9px 16px",border:"cancelled"===X?"none":"1px solid #E5E5E5",borderRadius:"6px",fontSize:ae?"10px":"13px",color:"cancelled"===X?"white":"#555555",fontWeight:600,fontFamily:kt,cursor:"pointer",flex:ae?"1 1 auto":"none",minWidth:ae?"0":"auto",transition:"all 0.3s ease",whiteSpace:"nowrap"}},"Cancelled Appointments")),a.default.createElement("div",{style:{display:"flex",gap:"8px",alignItems:"center",width:"auto",position:"relative",justifyContent:ae?"flex-start":"flex-end",flexWrap:"wrap"}},a.default.createElement("div",{style:{position:"relative"},"data-appointment-type-picker":!0},a.default.createElement("button",{onClick:()=>fe(!ue),style:{padding:"8px 12px",fontFamily:kt,fontWeight:600,border:"1px solid #E5E5E5",borderRadius:"6px",fontSize:ae?"11px":"13px",color:"#1a1a1a",background:"#FFFFFF",display:"flex",alignItems:"center",gap:ae?"4px":"6px",cursor:"pointer",flex:"none",minWidth:ae?"100px":"auto",justifyContent:"center"}},a.default.createElement("svg",{width:ae?"14":"16",height:ae?"14":"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a.default.createElement("path",{d:"M4.8 2A2.8 2.8 0 0 0 2 4.8v14.4A2.8 2.8 0 0 0 4.8 22h14.4a2.8 2.8 0 0 0 2.8-2.8V4.8A2.8 2.8 0 0 0 19.2 2H4.8z"}),a.default.createElement("path",{d:"M8 12h8M8 16h5"})),a.default.createElement("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"#4C4DDC"}},"all"===me?"All Appointment":"ONLINE"===me?"Online":"Physical"),a.default.createElement("svg",{width:ae?"8":"10",height:ae?"8":"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a.default.createElement("polyline",{points:"6 9 12 15 18 9"}))),ue&&a.default.createElement("div",{style:{position:"absolute",top:"100%",right:ae?"auto":0,left:ae?0:"auto",marginTop:"4px",background:"#FFFFFF",border:"1px solid #E5E5E5",borderRadius:"8px",boxShadow:"0 4px 16px rgba(0,0,0,0.15)",padding:"8px",zIndex:1e3,minWidth:ae?"240px":"200px",width:ae?"calc(100vw - 24px)":"auto",maxWidth:ae?"calc(100vw - 24px)":"240px"}},[{value:"all",label:"All Appointment"},{value:"ONLINE",label:"Online"},{value:"PHYSICAL",label:"Physical"}].map((e=>{let{value:t,label:n}=e;return a.default.createElement("button",{key:t,onClick:()=>{xe(t),fe(!1),xt(t)},style:{width:"100%",padding:"10px 12px",background:me===t?"#E8EEF4":"#FFFFFF",border:"none",borderRadius:"4px",fontSize:"13px",fontFamily:kt,cursor:"pointer",textAlign:"left",fontWeight:me===t?600:400,color:me===t?"#4C4DDC":"#1a1a1a",marginBottom:"4px",display:"flex",justifyContent:"space-between",alignItems:"center",transition:"all 0.2s ease"},onMouseEnter:e=>{me!==t&&(e.target.style.background="#F5F5F5")},onMouseLeave:e=>{me!==t&&(e.target.style.background="#FFFFFF")}},a.default.createElement("span",null,n),me===t&&a.default.createElement("span",{style:{color:"#4C4DDC",fontSize:"16px"}},"✓"))})))),a.default.createElement("button",{onClick:()=>{se||(rt(nt),pt(at),pe(le)),ce(!se)},style:{padding:"8px 12px",fontFamily:kt,fontWeight:600,border:"1px solid #E5E5E5",borderRadius:"6px",fontSize:ae?"11px":"13px",color:"#1a1a1a",background:"#FFFFFF",display:"flex",alignItems:"center",gap:ae?"4px":"6px",cursor:"pointer",flex:"none",minWidth:ae?"100px":"auto",justifyContent:"center"}},a.default.createElement("svg",{width:ae?"12":"14",height:ae?"12":"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a.default.createElement("rect",{x:"3",y:"4",width:"18",height:"18",rx:"2",ry:"2"}),a.default.createElement("line",{x1:"16",y1:"2",x2:"16",y2:"6"}),a.default.createElement("line",{x1:"8",y1:"2",x2:"8",y2:"6"}),a.default.createElement("line",{x1:"3",y1:"10",x2:"21",y2:"10"})),a.default.createElement("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},(()=>{switch(le){case"today":default:return"Today";case"tomorrow":return"Tomorrow";case"currentWeek":return"Current Week";case"thisMonth":return"This Month";case"currentYear":return"Current Year";case"custom":return ae?"Custom":`${nt} to ${at}`}})()),a.default.createElement("svg",{width:ae?"8":"10",height:ae?"8":"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},a.default.createElement("polyline",{points:"6 9 12 15 18 9"}))),se&&a.default.createElement("div",{style:{position:"absolute",top:"100%",right:ae?"auto":0,left:ae?0:"auto",marginTop:"4px",background:"#FFFFFF",border:"1px solid #E5E5E5",borderRadius:"8px",boxShadow:"0 4px 16px rgba(0,0,0,0.15)",padding:"8px",zIndex:1e3,minWidth:ae?"280px":"240px",width:ae?"calc(100vw - 24px)":"auto",maxWidth:ae?"calc(100vw - 24px)":"280px"}},a.default.createElement("div",{style:{marginBottom:"custom"===de?"12px":"0"}},["thisMonth","today","tomorrow","currentWeek","currentYear","custom"].map((e=>a.default.createElement("button",{key:e,onClick:()=>{if(pe(e),"custom"!==e){const t=(e=>{const t=new Date;let n,o;switch(e){case"today":default:n=o=q();break;case"tomorrow":const e=new Date(t);e.setDate(e.getDate()+1),n=o=e.toISOString().split("T")[0];break;case"currentWeek":const a=new Date(t),i=new Date(t),l=t.getDay(),r=0===l?-6:1-l;a.setDate(t.getDate()+r),i.setDate(a.getDate()+6),n=a.toISOString().split("T")[0],o=i.toISOString().split("T")[0];break;case"thisMonth":const d=new Date(t.getFullYear(),t.getMonth(),1),p=new Date(t.getFullYear(),t.getMonth()+1,0);n=d.toISOString().split("T")[0],o=p.toISOString().split("T")[0];break;case"currentYear":n=`${t.getFullYear()}-01-01`,o=`${t.getFullYear()}-12-31`}return{from:n,to:o}})(e);re(e),ot(t.from),it(t.to),rt(t.from),pt(t.to),ce(!1)}else rt(""),pt("")},style:{width:"100%",padding:"10px 12px",background:de===e?"#E8EEF4":"#FFFFFF",border:"none",borderRadius:"4px",fontSize:"13px",fontFamily:kt,cursor:"pointer",textAlign:"left",fontWeight:de===e?600:400,color:de===e?"#4C4DDC":"#1a1a1a",marginBottom:"4px",display:"flex",justifyContent:"space-between",alignItems:"center",transition:"all 0.2s ease"},onMouseEnter:t=>{de!==e&&(t.target.style.background="#F5F5F5")},onMouseLeave:t=>{de!==e&&(t.target.style.background="#FFFFFF")}},a.default.createElement("span",null,{thisMonth:"This Month",today:"Today",tomorrow:"Tomorrow",currentWeek:"Current Week",currentYear:"Current Year",custom:"Custom"}[e]),de===e&&a.default.createElement("span",{style:{color:"#4C4DDC",fontSize:"16px"}},"✓"))))),"custom"===de&&a.default.createElement("div",{style:{paddingTop:"8px",borderTop:"1px solid #E5E5E5"}},a.default.createElement("div",{style:{marginBottom:"8px"}},a.default.createElement("input",{type:"date",value:lt,onChange:e=>rt(e.target.value),placeholder:"Start Date",style:{width:"100%",padding:"10px 8px",border:"1px solid #E5E5E5",borderRadius:"4px",fontSize:"13px",fontFamily:kt,boxSizing:"border-box",cursor:"pointer"}})),a.default.createElement("div",{style:{marginBottom:"12px"}},a.default.createElement("input",{type:"date",value:dt,onChange:e=>pt(e.target.value),placeholder:"End Date",style:{width:"100%",padding:"10px 8px",border:"1px solid #E5E5E5",borderRadius:"4px",fontSize:"13px",fontFamily:kt,boxSizing:"border-box",cursor:"pointer"}})),a.default.createElement("div",{style:{display:"flex",gap:"8px"}},a.default.createElement("button",{onClick:()=>{pe(le),rt(nt),pt(at),ce(!1)},style:{flex:1,padding:"10px 12px",background:"#FFFFFF",color:"#4C4DDC",border:"1px solid #4C4DDC",borderRadius:"4px",fontSize:"13px",fontFamily:kt,fontWeight:600,cursor:"pointer"}},"Cancel"),a.default.createElement("button",{onClick:()=>{lt&&dt&&(re("custom"),ot(lt),it(dt),ce(!1))},style:{flex:1,padding:"10px 12px",background:"#4C4DDC",color:"#FFFFFF",border:"none",borderRadius:"4px",fontSize:"13px",fontFamily:kt,fontWeight:600,cursor:"pointer"}},"Submit")))))),a.default.createElement("div",{style:{display:"flex",flexDirection:ae?"column":"row",gap:ae?"12px":"14px",flex:1,minHeight:0,overflow:ae?"auto":"hidden"}},a.default.createElement("div",{style:{flex:ae?"none":"1 1 65%",width:ae?"100%":"auto",display:"flex",flexDirection:"column",minHeight:ae?"400px":0}},a.default.createElement("div",{style:{background:"#FFFFFF",borderRadius:"8px",boxShadow:"0 1px 4px rgba(0,0,0,0.08)",overflow:"hidden",display:"flex",flexDirection:"column",flex:ae?"none":1,minHeight:ae?"auto":0}},a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:ae?"12px 14px":"14px 18px",borderBottom:"1px solid #F1F1F1"}},a.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:ae?"6px":"8px"}},a.default.createElement("span",{style:{fontSize:ae?"14px":"15px",fontWeight:700,color:"#1a1a1a"}},"Appointments"),a.default.createElement("span",{style:{background:"#4C4DDC",color:"#fff",fontSize:ae?"10px":"11px",fontWeight:600,padding:ae?"2px 7px":"3px 8px",borderRadius:"12px"}},tt))),a.default.createElement("div",{className:"appointments-header-grid",style:{display:"grid",gridTemplateColumns:ae?"1.5fr 1fr 0.8fr":"2.5fr 1fr 1.5fr 0.8fr 1.2fr",gap:ae?"8px":"12px",padding:ae?"8px 12px":"10px 18px",background:"#F5F5F5",fontSize:ae?"10px":"12px",fontWeight:600,color:"#666"}},a.default.createElement("div",null,"Patients name"),!ae&&a.default.createElement("div",null,"Patient ID"),a.default.createElement("div",{onClick:mt,style:{display:"flex",alignItems:"center",gap:"3px",cursor:"pointer",userSelect:"none"}},"Date",a.default.createElement("span",{style:{opacity:.7,fontSize:"10px"}},"asc"===ge?"▲":"▼")),!ae&&a.default.createElement("div",null,"Slot"),!ae&&a.default.createElement("div",null,"Doctor")),a.default.createElement("div",{style:{overflow:"auto",flex:1}},P?a.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",padding:"40px",color:"#888"}},a.default.createElement("div",{style:{textAlign:"center"}},a.default.createElement("div",{style:{width:"40px",height:"40px",border:"3px solid #f3f3f3",borderTop:"3px solid #4C4DDC",borderRadius:"50%",animation:"spin 1s linear infinite",margin:"0 auto 10px"}}),"Getting token...")):ee?a.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",padding:"40px",color:"#888"}},a.default.createElement("div",{style:{textAlign:"center"}},a.default.createElement("div",{style:{width:"40px",height:"40px",border:"3px solid #f3f3f3",borderTop:"3px solid #4C4DDC",borderRadius:"50%",animation:"spin 1s linear infinite",margin:"0 auto 10px"}}),"Loading appointments...")):ne?a.default.createElement("div",{style:{padding:"40px",textAlign:"center",color:"#FF0000"}},a.default.createElement("div",{style:{fontSize:"16px",marginBottom:"8px"}},"⚠️ Error"),a.default.createElement("div",{style:{fontSize:"13px"}},ne),a.default.createElement("button",{onClick:xt,style:{marginTop:"16px",padding:"8px 16px",background:"#4C4DDC",color:"white",border:"none",borderRadius:"6px",cursor:"pointer",fontFamily:kt}},"Retry")):0===Ze.length?a.default.createElement("div",{style:{padding:"40px",textAlign:"center",color:"#888"}},a.default.createElement("div",{style:{fontSize:"16px",marginBottom:"8px"}},"📋"),a.default.createElement("div",{style:{fontSize:"13px"}},ye?`No appointments found for "${ye}"`:"No appointments found"),ye&&a.default.createElement("button",{onClick:()=>Ee(""),style:{marginTop:"12px",padding:"6px 12px",background:"#4C4DDC",color:"white",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"12px",fontFamily:kt}},"Clear Search")):Ze.map((e=>a.default.createElement("div",{key:st(e),role:"button",tabIndex:0,onClick:()=>gt(e),onKeyDown:t=>"Enter"===t.key&>(e),className:"appointments-grid",style:{display:"grid",gridTemplateColumns:ae?"1.5fr 1fr 0.8fr":"2.5fr 1fr 1.5fr 0.8fr 1.2fr",gap:ae?"8px":"12px",padding:ae?"10px 12px":"12px 18px",background:st(Q)===st(e)?"#E8EEF4":"#FFFFFF",borderTop:"1px solid #F1F1F1",alignItems:"center",cursor:"pointer",fontSize:ae?"11px":"13px"}},a.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:ae?"8px":"10px"}},ct(e)?a.default.createElement("img",{src:e.image,alt:"",style:{width:ae?"32px":"36px",height:ae?"32px":"36px",borderRadius:"50%",objectFit:"cover"}}):a.default.createElement("div",{style:{width:ae?"32px":"36px",height:ae?"32px":"36px",borderRadius:"50%",background:ft(e.patientName),display:"flex",alignItems:"center",justifyContent:"center",color:"#FFFFFF",fontWeight:600,fontSize:ae?"14px":"16px"}},ut(e.patientName)),a.default.createElement("div",null,a.default.createElement("div",{style:{fontWeight:600,color:"#1a1a1a",fontSize:ae?"11px":"13px"}},e.patientName),a.default.createElement("div",{style:{fontSize:ae?"9px":"11px",color:"#888"}},e.email))),!ae&&a.default.createElement("div",{style:{color:"#555",fontSize:"12px"}},e.patientId),a.default.createElement("div",{style:{color:"#555",fontSize:ae?"10px":"12px"}},(()=>{const t=e.appointmentDate||"",n=t.match(/\s(\d{1,2}:\d{2}(?:\s*(?:AM|PM))?)$/i);return n?a.default.createElement(a.default.Fragment,null,a.default.createElement("div",null,t.slice(0,n.index).trim()),a.default.createElement("div",{style:{fontSize:ae?"9px":"11px",color:"#888"}},n[1].trim())):a.default.createElement("div",null,t)})()),!ae&&a.default.createElement("div",{style:{color:"#555",fontSize:"12px"}},e.appointmentTime||"-"),!ae&&a.default.createElement("div",{style:{color:"#555",fontSize:"12px"}},e.doctorName||e.doctor||"-"))))),!ee&&!ne&&Ze.length>0&&a.default.createElement("div",{style:{padding:ae?"12px 14px":"14px 18px",borderTop:"1px solid #F1F1F1",display:"flex",justifyContent:"space-between",alignItems:"center",background:"#FFFFFF",flexWrap:ae?"wrap":"nowrap",gap:ae?"10px":"0"}},a.default.createElement("div",{style:{fontSize:ae?"11px":"12px",color:"#666"}},"Showing page ",Xe," of ",et," (",tt," total)"),a.default.createElement("div",{style:{display:"flex",gap:"6px",alignItems:"center"}},a.default.createElement("button",{onClick:()=>Ge((e=>Math.max(1,e-1))),disabled:1===Xe,style:{padding:ae?"6px 10px":"6px 12px",border:"1px solid #E5E5E5",borderRadius:"4px",background:1===Xe?"#F5F5F5":"#FFFFFF",color:1===Xe?"#999":"#1a1a1a",fontSize:ae?"11px":"12px",fontFamily:kt,fontWeight:600,cursor:1===Xe?"not-allowed":"pointer",opacity:1===Xe?.5:1}},"Previous"),a.default.createElement("div",{style:{display:"flex",gap:"4px"}},[...Array(Math.min(5,et))].map(((e,t)=>{let n;return n=et<=5||Xe<=3?t+1:Xe>=et-2?et-4+t:Xe-2+t,a.default.createElement("button",{key:n,onClick:()=>Ge(n),style:{padding:ae?"6px 10px":"6px 12px",border:Xe===n?"none":"1px solid #E5E5E5",borderRadius:"4px",background:Xe===n?"#4C4DDC":"#FFFFFF",color:Xe===n?"#FFFFFF":"#1a1a1a",fontSize:ae?"11px":"12px",fontFamily:kt,fontWeight:600,cursor:"pointer",minWidth:ae?"32px":"36px"}},n)}))),a.default.createElement("button",{onClick:()=>Ge((e=>Math.min(et,e+1))),disabled:Xe===et,style:{padding:ae?"6px 10px":"6px 12px",border:"1px solid #E5E5E5",borderRadius:"4px",background:Xe===et?"#F5F5F5":"#FFFFFF",color:Xe===et?"#999":"#1a1a1a",fontSize:ae?"11px":"12px",fontFamily:kt,fontWeight:600,cursor:Xe===et?"not-allowed":"pointer",opacity:Xe===et?.5:1}},"Next"))))),a.default.createElement("div",{style:{flex:ae?"none":"1 1 35%",width:ae?"100%":"auto",display:Q||!ae?"flex":"none",flexDirection:"column",minHeight:ae?"auto":0}},a.default.createElement("div",{style:{border:"1px solid #E5E5E5",borderRadius:"8px",overflow:"hidden",background:"#FFFFFF",boxShadow:"0 1px 4px rgba(0,0,0,0.08)",display:"flex",flexDirection:"column",flex:ae?"none":1,minHeight:ae?"auto":0}},Q?a.default.createElement(a.default.Fragment,null,a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:ae?"12px 14px":"16px 18px",background:"#E8EEF4",borderBottom:"1px solid #E5E5E5"}},a.default.createElement("div",null,a.default.createElement("div",{style:{color:"#002668",fontSize:ae?"14px":"16px",fontWeight:"700"}},Q.patientName||"N/A"),a.default.createElement("div",{style:{color:"#002668",fontSize:ae?"11px":"13px"}},Q.patientId||Q.mrn||"N/A")),a.default.createElement("div",null,ct(Q)?a.default.createElement("img",{style:{width:ae?"36px":"44px",height:ae?"36px":"44px",borderRadius:"50%",objectFit:"cover"},src:Q.image,alt:Q.patientName}):a.default.createElement("div",{style:{width:ae?"36px":"44px",height:ae?"36px":"44px",borderRadius:"50%",background:ft(Q.patientName),display:"flex",alignItems:"center",justifyContent:"center",color:"#FFFFFF",fontWeight:700,fontSize:ae?"16px":"20px"}},ut(Q.patientName)))),a.default.createElement("div",{style:{padding:ae?"12px 14px":"14px 18px",gap:ae?"10px":"12px",display:"flex",flexDirection:"column",background:"white",overflow:"auto",flex:1,position:"relative"}},a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Speciality"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ae?"12px":"13px"}},Q?.specialisation||Q?.speciality||"N/A")),a.default.createElement("div",{style:{textAlign:"right"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Appointment Type"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ae?"12px":"13px"}},Q?.type||Q?.appointmentType||"Online"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Appointment Date"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ae?"12px":"13px"}},Q?.date||Q?.appointmentDate||"N/A")),a.default.createElement("div",{style:{textAlign:"right"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Appointment Time"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ae?"12px":"13px"}},Q?.time||Q?.appointmentTime||"N/A"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Doctor"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ae?"12px":"13px"}},Q?.doctor||Q?.doctorName||"N/A"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Hospital"),a.default.createElement("div",{style:{fontWeight:"700",fontSize:ae?"12px":"13px"}},Q?.hospital||Q?.hospitalName||"N/A"))),a.default.createElement("div",{style:{display:"flex",justifyContent:"space-between"}},a.default.createElement("div",{style:{textAlign:"left"}},a.default.createElement("div",{style:{fontSize:ae?"10px":"11px",color:"#888",marginBottom:"3px"}},"Reason for Appointment"),a.default.createElement("div",{style:{fontWeight:"600",fontSize:ae?"11px":"12px",lineHeight:"1.4"}},Q?.reason||Q?.reasonForAppointment||"No reason provided"))),"upcoming"===X&&a.default.createElement("div",{style:{display:"flex",flexDirection:ae?"column":"row",gap:"6px",marginTop:"10px"}},a.default.createElement("button",{type:"button",onClick:ht,disabled:We,style:{flex:1,background:We?"#99e4e8":"#1CC3CE",color:"#FFFFFF",border:"1px solid #1CC3CE",borderRadius:"6px",padding:ae?"10px 8px":"8px 6px",fontFamily:kt,fontWeight:600,fontSize:ae?"11px":"12px",cursor:We?"not-allowed":"pointer"}},We?"Connecting...":"Join Call >")),"upcoming"===X&&Te&&a.default.createElement("div",{style:{fontSize:"11px",color:"#e53935",marginTop:"6px",textAlign:"center",width:"100%"}},"⚠️ ",Te))):a.default.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100%",padding:"40px",color:"#888",textAlign:"center"}},a.default.createElement("div",null,a.default.createElement("div",{style:{fontSize:"16px",marginBottom:"8px"}},"📋"),a.default.createElement("div",{style:{fontSize:"13px"}},"Select an appointment to view details"))))))),Fe&&a.default.createElement("div",{style:{position:"fixed",left:ve?"0":ae?"10px":`${Re.x}px`,top:ve?"0":ae?"70px":`${Re.y}px`,right:ve?"0":ae?"10px":"auto",bottom:ve?"0":"auto",width:ve?"100vw":ae?"calc(100vw - 20px)":we?"350px":`${Pe.width}px`,height:ve?"100vh":we?"auto":ae?"300px":`${Pe.height}px`,background:"#FFFFFF",borderRadius:ve?"0":"8px",boxShadow:"0 8px 24px rgba(0, 0, 0, 0.3)",zIndex:1e4,overflow:"hidden",display:"flex",flexDirection:"column",transition:Be||Oe?"none":"all 0.3s ease"}},a.default.createElement("div",{onPointerDown:ae||ve?void 0:bt,onPointerMove:ae||ve?void 0:wt,onPointerUp:ae||ve?void 0:St,onPointerCancel:ae||ve?void 0:St,style:{background:"linear-gradient(135deg, #4C4DDC 0%, #3A3BBD 100%)",color:"#FFFFFF",padding:ae?"8px 10px":"10px 12px",display:"flex",justifyContent:"space-between",alignItems:"center",cursor:ae||ve?"default":"move",userSelect:"none"}},a.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:ae?"6px":"8px",flex:1,minWidth:0}},a.default.createElement("div",{style:{width:ae?"6px":"8px",height:ae?"6px":"8px",borderRadius:"50%",background:"#FF4444",animation:"pulse 2s infinite",flexShrink:0}}),a.default.createElement("span",{style:{fontSize:ae?"11px":"13px",fontWeight:600,fontFamily:kt,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},"Video Call - ",Q?.patientName||"Patient")),a.default.createElement("div",{style:{display:"flex",gap:ae?"4px":"6px",alignItems:"center",flexShrink:0}},!ve&&a.default.createElement("button",{onClick:Et,style:{background:"rgba(255, 255, 255, 0.2)",border:"1px solid rgba(255, 255, 255, 0.3)",borderRadius:"6px",color:"#FFFFFF",cursor:"pointer",padding:ae?"5px 8px":"6px 10px",lineHeight:1,display:"flex",alignItems:"center",justifyContent:"center",minWidth:ae?"28px":"32px",height:ae?"28px":"32px",transition:"background 0.2s ease"},onMouseEnter:e=>e.target.style.background="rgba(255, 255, 255, 0.3)",onMouseLeave:e=>e.target.style.background="rgba(255, 255, 255, 0.2)",title:we?"Restore":"Minimize"},we?a.default.createElement("svg",{width:ae?"14":"16",height:ae?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("rect",{x:"3",y:"3",width:"10",height:"10",stroke:"white",strokeWidth:"1.8",fill:"none"})):a.default.createElement("svg",{width:ae?"14":"16",height:ae?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("line",{x1:"3",y1:"8",x2:"13",y2:"8",stroke:"white",strokeWidth:"1.8",strokeLinecap:"round"}))),a.default.createElement("button",{onClick:Ft,style:{background:"rgba(255, 255, 255, 0.2)",border:"1px solid rgba(255, 255, 255, 0.3)",borderRadius:"6px",color:"#FFFFFF",cursor:"pointer",padding:ae?"5px 8px":"6px 10px",lineHeight:1,display:"flex",alignItems:"center",justifyContent:"center",minWidth:ae?"28px":"32px",height:ae?"28px":"32px",transition:"background 0.2s ease"},onMouseEnter:e=>e.target.style.background="rgba(255, 255, 255, 0.3)",onMouseLeave:e=>e.target.style.background="rgba(255, 255, 255, 0.2)",title:ve?"Exit Fullscreen":"Fullscreen"},ve?a.default.createElement("svg",{width:ae?"14":"16",height:ae?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("path",{d:"M10 3H13V6M6 13H3V10M13 10V13H10M3 6V3H6",stroke:"white",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})):a.default.createElement("svg",{width:ae?"14":"16",height:ae?"14":"16",viewBox:"0 0 16 16",fill:"none"},a.default.createElement("path",{d:"M3 6V3H6M13 10V13H10M10 3H13V6M6 13H3V10",stroke:"white",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"}))),a.default.createElement("button",{onClick:yt,style:{background:"rgba(255, 255, 255, 0.2)",border:"1px solid rgba(255, 255, 255, 0.3)",borderRadius:"6px",color:"#FFFFFF",cursor:"pointer",padding:ae?"5px 8px":"6px 10px",lineHeight:1,display:"flex",alignItems:"center",justifyContent:"center",minWidth:ae?"28px":"32px",height:ae?"28px":"32px",fontWeight:"bold",fontSize:ae?"18px":"22px",transition:"background 0.2s ease"},onMouseEnter:e=>e.target.style.background="rgba(255, 255, 255, 0.3)",onMouseLeave:e=>e.target.style.background="rgba(255, 255, 255, 0.2)",title:"Close"},"×"))),!we&&a.default.createElement("div",{style:{flex:1,background:"#000000",position:"relative"}},a.default.createElement("iframe",{src:(()=>{if(!Ce)return"";const e=String(_||"").replace(/\/?$/,"/");return console.log("${base}token=${callToken}",`${e}token=${Ce}`),`${e}token=${Ce}`})(),style:{width:"100%",height:"100%",border:"none"},allow:"camera; microphone; display-capture; autoplay",allowFullScreen:!0,title:"Video Call"})),!ae&&!ve&&!we&&a.default.createElement(a.default.Fragment,null,a.default.createElement("div",{onPointerDown:e=>vt("top-left",e),onPointerMove:wt,onPointerUp:St,onPointerCancel:St,style:{position:"absolute",left:0,top:0,width:"16px",height:"16px",cursor:"nwse-resize",background:"transparent",zIndex:10001}}),a.default.createElement("div",{onPointerDown:e=>vt("top-right",e),onPointerMove:wt,onPointerUp:St,onPointerCancel:St,style:{position:"absolute",right:0,top:0,width:"16px",height:"16px",cursor:"nesw-resize",background:"transparent",zIndex:10001}}),a.default.createElement("div",{onPointerDown:e=>vt("bottom-left",e),onPointerMove:wt,onPointerUp:St,onPointerCancel:St,style:{position:"absolute",left:0,bottom:0,width:"16px",height:"16px",cursor:"nesw-resize",background:"transparent",zIndex:10001}}),a.default.createElement("div",{onPointerDown:e=>vt("bottom-right",e),onPointerMove:wt,onPointerUp:St,onPointerCancel:St,style:{position:"absolute",right:0,bottom:0,width:"16px",height:"16px",cursor:"nwse-resize",background:"transparent",zIndex:10001}})),a.default.createElement("style",null,"\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n "))),Ct&&a.default.createElement("div",{style:{position:"fixed",inset:0,zIndex:1e5,display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",background:"rgba(0,0,0,0.4)",boxSizing:"border-box"}},a.default.createElement("div",{style:{fontFamily:kt,maxWidth:"400px",width:"100%",padding:"32px 24px",background:"#FFFFFF",borderRadius:"12px",boxShadow:"0 8px 32px rgba(0,0,0,0.2)",textAlign:"center"}},a.default.createElement("div",{style:{fontSize:"48px",marginBottom:"16px"}},"🔒"),a.default.createElement("h2",{style:{fontSize:"20px",fontWeight:700,color:"#1a1a1a",margin:"0 0 8px 0"}},B?"Not authorised":"Sign in required"),a.default.createElement("p",{style:{fontSize:"14px",color:"#666",margin:0,lineHeight:1.5}},It),a.default.createElement("p",{style:{fontSize:"13px",color:"#999",marginTop:"16px",marginBottom:0}},"Redirecting to login...")))),a.default.createElement(b,null,Dt)};let S=null;const v={showWidget:(e,t)=>{S||(S=document.createElement("div"),document.body.appendChild(S));const n=()=>a.default.createElement(a.default.Fragment,null,a.default.createElement(w,{config:e}));i.default.render(a.default.createElement(n,null),S)},closePopup:()=>{S&&(i.default.unmountComponentAtNode(S),S=null)}};window.BookingSDK=v,e.AppointmentPage=w,e.PIH_APPOINTMENT_WIDGET_CLASS=E,e.default=v,Object.defineProperty(e,"__esModule",{value:!0})}));
|
|
@@ -14,8 +14,7 @@ var _apiConfig = require("../constants/apiConfig");
|
|
|
14
14
|
* @param {object} config - Optional configuration { apiBaseUrl, hospitalId, doctorId }
|
|
15
15
|
* @returns {Promise} Appointments data
|
|
16
16
|
*/
|
|
17
|
-
const getAppointmentsByStatus = async function (status, fromDate, toDate) {
|
|
18
|
-
let type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'ONLINE';
|
|
17
|
+
const getAppointmentsByStatus = async function (status, fromDate, toDate, type) {
|
|
19
18
|
let config = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
20
19
|
// Map status to API format
|
|
21
20
|
let apiStatus = (status || "").toUpperCase();
|
|
@@ -23,7 +22,7 @@ const getAppointmentsByStatus = async function (status, fromDate, toDate) {
|
|
|
23
22
|
apiStatus = "IN_PROGRESS";
|
|
24
23
|
}
|
|
25
24
|
const baseURL = config.apiBaseUrl;
|
|
26
|
-
const hospitalId = config.hospitalId
|
|
25
|
+
const hospitalId = config.hospitalId;
|
|
27
26
|
const doctorId = config.doctorId;
|
|
28
27
|
const token = config.token || '';
|
|
29
28
|
const params = {
|
|
@@ -31,9 +30,11 @@ const getAppointmentsByStatus = async function (status, fromDate, toDate) {
|
|
|
31
30
|
doctorId,
|
|
32
31
|
fromDate,
|
|
33
32
|
toDate,
|
|
34
|
-
statuses: apiStatus
|
|
35
|
-
type
|
|
33
|
+
statuses: apiStatus
|
|
36
34
|
};
|
|
35
|
+
if (type && String(type).toUpperCase() !== "ALL") {
|
|
36
|
+
params.appointmentType = String(type).toUpperCase();
|
|
37
|
+
}
|
|
37
38
|
const url = `${baseURL}${_apiConfig.API_PATHS.APPOINTMENTS}`;
|
|
38
39
|
|
|
39
40
|
// Return raw response (including status) so caller can detect 401 and re-login
|
|
@@ -80,7 +81,7 @@ const initiateConsultation = async function (appointment) {
|
|
|
80
81
|
const body = {
|
|
81
82
|
patientId: String(appointment.patientId || ""),
|
|
82
83
|
primaryPatientId: String(appointment.primaryPatientId || appointment.patientId || ""),
|
|
83
|
-
hospitalId: config.hospitalId
|
|
84
|
+
hospitalId: config.hospitalId,
|
|
84
85
|
doctorId: String(config.doctorId),
|
|
85
86
|
patientName: appointment.patientName || appointment.name || "",
|
|
86
87
|
doctorName: appointment.doctorName || config.doctorName,
|
package/package.json
CHANGED
|
@@ -26,6 +26,7 @@ const STORAGE_KEY_APP_TOKEN = "pih_appointment_appToken";
|
|
|
26
26
|
const STORAGE_KEY_DOCTOR_ID = "pih_appointment_doctorId";
|
|
27
27
|
const STORAGE_KEY_USER_NAME = "pih_appointment_userName";
|
|
28
28
|
const STORAGE_KEY_API_BASE_URL = "pih_appointment_apiBaseUrl";
|
|
29
|
+
const STORAGE_KEY_HOSPITAL_ID = "pih_appointment_hospitalId";
|
|
29
30
|
|
|
30
31
|
const DEFAULT_PIP_WIDTH = 720;
|
|
31
32
|
const DEFAULT_PIP_HEIGHT = 560;
|
|
@@ -105,8 +106,15 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
105
106
|
return null;
|
|
106
107
|
}
|
|
107
108
|
});
|
|
109
|
+
const [storedHospitalId, setStoredHospitalId] = useState(() => {
|
|
110
|
+
try {
|
|
111
|
+
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_HOSPITAL_ID) : null;
|
|
112
|
+
} catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
108
116
|
const apiBaseUrl = config.apiBaseUrl || storedApiBaseUrl || API_BASE_URL;
|
|
109
|
-
const hospitalId = config.hospitalId ||
|
|
117
|
+
const hospitalId = config.hospitalId || storedHospitalId;
|
|
110
118
|
|
|
111
119
|
// idToken/email: config first, then localStorage. When Flutter (or parent) passes a new token, we use it and re-login.
|
|
112
120
|
const [storedIdToken, setStoredIdToken] = useState(() => {
|
|
@@ -153,8 +161,12 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
153
161
|
localStorage.setItem(STORAGE_KEY_API_BASE_URL, config.apiBaseUrl.trim());
|
|
154
162
|
setStoredApiBaseUrl(config.apiBaseUrl.trim());
|
|
155
163
|
}
|
|
164
|
+
if (config.hospitalId != null && String(config.hospitalId).trim()) {
|
|
165
|
+
localStorage.setItem(STORAGE_KEY_HOSPITAL_ID, String(config.hospitalId).trim());
|
|
166
|
+
setStoredHospitalId(String(config.hospitalId).trim());
|
|
167
|
+
}
|
|
156
168
|
} catch (e) {}
|
|
157
|
-
}, [config.idToken, config.token, config.email, config.apiBaseUrl]);
|
|
169
|
+
}, [config.idToken, config.token, config.email, config.apiBaseUrl, config.hospitalId]);
|
|
158
170
|
|
|
159
171
|
const [appToken, setAppToken] = useState(() => {
|
|
160
172
|
try {
|
|
@@ -305,6 +317,8 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
305
317
|
const [selectedDate, setSelectedDate] = useState("today"); // today, tomorrow, week, month, year, custom
|
|
306
318
|
const [dateOption, setDateOption] = useState("today"); // Currently selected option in dropdown
|
|
307
319
|
const [showDatePicker, setShowDatePicker] = useState(false);
|
|
320
|
+
const [showAppointmentTypePicker, setShowAppointmentTypePicker] = useState(false);
|
|
321
|
+
const [appointmentTypeFilter, setAppointmentTypeFilter] = useState("all"); // 'all' | 'ONLINE' | 'PHYSICAL'
|
|
308
322
|
const [sortOrder, setSortOrder] = useState("asc"); // asc or desc for date sorting
|
|
309
323
|
const [searchQuery, setSearchQuery] = useState(""); // Search query for filtering
|
|
310
324
|
|
|
@@ -411,10 +425,11 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
411
425
|
}
|
|
412
426
|
};
|
|
413
427
|
|
|
414
|
-
const fetchAppointments = useCallback(async () => {
|
|
428
|
+
const fetchAppointments = useCallback(async (overrideType) => {
|
|
415
429
|
if (!appToken) return;
|
|
416
430
|
console.log(doctorIdFromLogin, 'fetchAppointments -> doctorIdFromLogin')
|
|
417
431
|
const doctorId = doctorIdFromLogin;
|
|
432
|
+
const typeToUse = overrideType !== undefined ? overrideType : appointmentTypeFilter;
|
|
418
433
|
setLoading(true);
|
|
419
434
|
setError(null);
|
|
420
435
|
try {
|
|
@@ -424,7 +439,7 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
424
439
|
doctorId,
|
|
425
440
|
token: appToken,
|
|
426
441
|
};
|
|
427
|
-
const response = await getAppointmentsByStatus(activeTab, fromDate, toDate,
|
|
442
|
+
const response = await getAppointmentsByStatus(activeTab, fromDate, toDate, typeToUse, serviceConfig);
|
|
428
443
|
if (response.status === 401 || response.status === 403) {
|
|
429
444
|
// Token expired — clear stored token and trigger re-login (SSO effect will fire)
|
|
430
445
|
try {
|
|
@@ -458,7 +473,7 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
458
473
|
} finally {
|
|
459
474
|
setLoading(false);
|
|
460
475
|
}
|
|
461
|
-
}, [activeTab, fromDate, toDate, apiBaseUrl, hospitalId, doctorIdFromLogin, appToken]);
|
|
476
|
+
}, [activeTab, fromDate, toDate, appointmentTypeFilter, apiBaseUrl, hospitalId, doctorIdFromLogin, appToken]);
|
|
462
477
|
|
|
463
478
|
// Handle appointment selection - no API call, just show data from list
|
|
464
479
|
const handleAppointmentSelect = (appointment) => {
|
|
@@ -475,6 +490,7 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
475
490
|
localStorage.removeItem(STORAGE_KEY_DOCTOR_ID);
|
|
476
491
|
localStorage.removeItem(STORAGE_KEY_USER_NAME);
|
|
477
492
|
localStorage.removeItem(STORAGE_KEY_API_BASE_URL);
|
|
493
|
+
localStorage.removeItem(STORAGE_KEY_HOSPITAL_ID);
|
|
478
494
|
}
|
|
479
495
|
} catch (e) {}
|
|
480
496
|
setShowProfileDropdown(false);
|
|
@@ -761,7 +777,7 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
761
777
|
// Reset page to 1 when filters change
|
|
762
778
|
useEffect(() => {
|
|
763
779
|
setCurrentPage(1);
|
|
764
|
-
}, [activeTab, selectedDate, fromDate, toDate, searchQuery]);
|
|
780
|
+
}, [activeTab, selectedDate, fromDate, toDate, searchQuery, appointmentTypeFilter]);
|
|
765
781
|
|
|
766
782
|
// Fetch appointments when we have appToken (tab/date change triggers refetch via fetchAppointments deps)
|
|
767
783
|
useEffect(() => {
|
|
@@ -821,19 +837,22 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
821
837
|
};
|
|
822
838
|
}, []);
|
|
823
839
|
|
|
824
|
-
// Close date picker when clicking outside
|
|
840
|
+
// Close date picker and appointment type picker when clicking outside
|
|
825
841
|
useEffect(() => {
|
|
826
842
|
const handleClickOutside = (event) => {
|
|
827
843
|
if (showDatePicker && !event.target.closest('button') && !event.target.closest('input[type="date"]')) {
|
|
828
844
|
setShowDatePicker(false);
|
|
829
845
|
}
|
|
846
|
+
if (showAppointmentTypePicker && !event.target.closest('[data-appointment-type-picker]')) {
|
|
847
|
+
setShowAppointmentTypePicker(false);
|
|
848
|
+
}
|
|
830
849
|
};
|
|
831
850
|
|
|
832
851
|
document.addEventListener("click", handleClickOutside);
|
|
833
852
|
return () => {
|
|
834
853
|
document.removeEventListener("click", handleClickOutside);
|
|
835
854
|
};
|
|
836
|
-
}, [showDatePicker]);
|
|
855
|
+
}, [showDatePicker, showAppointmentTypePicker]);
|
|
837
856
|
|
|
838
857
|
let fontFamily = '"Nunito", serif';
|
|
839
858
|
|
|
@@ -1176,8 +1195,104 @@ const AppointmentPage = ({ config = {} }) => {
|
|
|
1176
1195
|
</button>
|
|
1177
1196
|
</div>
|
|
1178
1197
|
|
|
1179
|
-
{/* Date Filter */}
|
|
1180
|
-
<div style={{ display: "flex", gap: "8px", alignItems: "center", width: isMobile ? "auto" : "auto", position: "relative", justifyContent: isMobile ? "flex-start" : "flex-end" }}>
|
|
1198
|
+
{/* Date Filter + Type of Appointment Filter */}
|
|
1199
|
+
<div style={{ display: "flex", gap: "8px", alignItems: "center", width: isMobile ? "auto" : "auto", position: "relative", justifyContent: isMobile ? "flex-start" : "flex-end", flexWrap: "wrap" }}>
|
|
1200
|
+
{/* Type of Appointment Filter */}
|
|
1201
|
+
<div style={{ position: "relative" }} data-appointment-type-picker>
|
|
1202
|
+
<button
|
|
1203
|
+
onClick={() => setShowAppointmentTypePicker(!showAppointmentTypePicker)}
|
|
1204
|
+
style={{
|
|
1205
|
+
padding: isMobile ? "8px 12px" : "8px 12px",
|
|
1206
|
+
fontFamily,
|
|
1207
|
+
fontWeight: 600,
|
|
1208
|
+
border: "1px solid #E5E5E5",
|
|
1209
|
+
borderRadius: "6px",
|
|
1210
|
+
fontSize: isMobile ? "11px" : "13px",
|
|
1211
|
+
color: "#1a1a1a",
|
|
1212
|
+
background: "#FFFFFF",
|
|
1213
|
+
display: "flex",
|
|
1214
|
+
alignItems: "center",
|
|
1215
|
+
gap: isMobile ? "4px" : "6px",
|
|
1216
|
+
cursor: "pointer",
|
|
1217
|
+
flex: "none",
|
|
1218
|
+
minWidth: isMobile ? "100px" : "auto",
|
|
1219
|
+
justifyContent: "center",
|
|
1220
|
+
}}
|
|
1221
|
+
>
|
|
1222
|
+
<svg width={isMobile ? "14" : "16"} height={isMobile ? "14" : "16"} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
1223
|
+
<path d="M4.8 2A2.8 2.8 0 0 0 2 4.8v14.4A2.8 2.8 0 0 0 4.8 22h14.4a2.8 2.8 0 0 0 2.8-2.8V4.8A2.8 2.8 0 0 0 19.2 2H4.8z" />
|
|
1224
|
+
<path d="M8 12h8M8 16h5" />
|
|
1225
|
+
</svg>
|
|
1226
|
+
<span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: "#4C4DDC" }}>
|
|
1227
|
+
{appointmentTypeFilter === "all" ? "All Appointment" : appointmentTypeFilter === "ONLINE" ? "Online" : "Physical"}
|
|
1228
|
+
</span>
|
|
1229
|
+
<svg width={isMobile ? "8" : "10"} height={isMobile ? "8" : "10"} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
1230
|
+
<polyline points="6 9 12 15 18 9" />
|
|
1231
|
+
</svg>
|
|
1232
|
+
</button>
|
|
1233
|
+
{showAppointmentTypePicker && (
|
|
1234
|
+
<div
|
|
1235
|
+
style={{
|
|
1236
|
+
position: "absolute",
|
|
1237
|
+
top: "100%",
|
|
1238
|
+
right: isMobile ? "auto" : 0,
|
|
1239
|
+
left: isMobile ? 0 : "auto",
|
|
1240
|
+
marginTop: "4px",
|
|
1241
|
+
background: "#FFFFFF",
|
|
1242
|
+
border: "1px solid #E5E5E5",
|
|
1243
|
+
borderRadius: "8px",
|
|
1244
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.15)",
|
|
1245
|
+
padding: "8px",
|
|
1246
|
+
zIndex: 1000,
|
|
1247
|
+
minWidth: isMobile ? "240px" : "200px",
|
|
1248
|
+
width: isMobile ? "calc(100vw - 24px)" : "auto",
|
|
1249
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "240px",
|
|
1250
|
+
}}
|
|
1251
|
+
>
|
|
1252
|
+
{[
|
|
1253
|
+
{ value: "all", label: "All Appointment" },
|
|
1254
|
+
{ value: "ONLINE", label: "Online" },
|
|
1255
|
+
{ value: "PHYSICAL", label: "Physical" },
|
|
1256
|
+
].map(({ value, label }) => (
|
|
1257
|
+
<button
|
|
1258
|
+
key={value}
|
|
1259
|
+
onClick={() => {
|
|
1260
|
+
setAppointmentTypeFilter(value);
|
|
1261
|
+
setShowAppointmentTypePicker(false);
|
|
1262
|
+
fetchAppointments(value);
|
|
1263
|
+
}}
|
|
1264
|
+
style={{
|
|
1265
|
+
width: "100%",
|
|
1266
|
+
padding: "10px 12px",
|
|
1267
|
+
background: appointmentTypeFilter === value ? "#E8EEF4" : "#FFFFFF",
|
|
1268
|
+
border: "none",
|
|
1269
|
+
borderRadius: "4px",
|
|
1270
|
+
fontSize: "13px",
|
|
1271
|
+
fontFamily,
|
|
1272
|
+
cursor: "pointer",
|
|
1273
|
+
textAlign: "left",
|
|
1274
|
+
fontWeight: appointmentTypeFilter === value ? 600 : 400,
|
|
1275
|
+
color: appointmentTypeFilter === value ? "#4C4DDC" : "#1a1a1a",
|
|
1276
|
+
marginBottom: "4px",
|
|
1277
|
+
display: "flex",
|
|
1278
|
+
justifyContent: "space-between",
|
|
1279
|
+
alignItems: "center",
|
|
1280
|
+
transition: "all 0.2s ease",
|
|
1281
|
+
}}
|
|
1282
|
+
onMouseEnter={(e) => {
|
|
1283
|
+
if (appointmentTypeFilter !== value) e.target.style.background = "#F5F5F5";
|
|
1284
|
+
}}
|
|
1285
|
+
onMouseLeave={(e) => {
|
|
1286
|
+
if (appointmentTypeFilter !== value) e.target.style.background = "#FFFFFF";
|
|
1287
|
+
}}
|
|
1288
|
+
>
|
|
1289
|
+
<span>{label}</span>
|
|
1290
|
+
{appointmentTypeFilter === value && <span style={{ color: "#4C4DDC", fontSize: "16px" }}>✓</span>}
|
|
1291
|
+
</button>
|
|
1292
|
+
))}
|
|
1293
|
+
</div>
|
|
1294
|
+
)}
|
|
1295
|
+
</div>
|
|
1181
1296
|
{/* Date Filter */}
|
|
1182
1297
|
<button
|
|
1183
1298
|
onClick={() => {
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
* @param {object} config - Optional configuration { apiBaseUrl, hospitalId, doctorId }
|
|
14
14
|
* @returns {Promise} Appointments data
|
|
15
15
|
*/
|
|
16
|
-
export const getAppointmentsByStatus = async (status, fromDate, toDate, type
|
|
16
|
+
export const getAppointmentsByStatus = async (status, fromDate, toDate, type, config = {}) => {
|
|
17
17
|
// Map status to API format
|
|
18
18
|
let apiStatus = (status || "").toUpperCase();
|
|
19
19
|
|
|
@@ -22,11 +22,14 @@ export const getAppointmentsByStatus = async (status, fromDate, toDate, type = '
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const baseURL = config.apiBaseUrl;
|
|
25
|
-
const hospitalId = config.hospitalId
|
|
25
|
+
const hospitalId = config.hospitalId;
|
|
26
26
|
const doctorId = config.doctorId;
|
|
27
27
|
const token = config.token || '';
|
|
28
28
|
|
|
29
|
-
const params = { hospitalId, doctorId, fromDate, toDate, statuses: apiStatus
|
|
29
|
+
const params = { hospitalId, doctorId, fromDate, toDate, statuses: apiStatus };
|
|
30
|
+
if (type && String(type).toUpperCase() !== "ALL") {
|
|
31
|
+
params.appointmentType = String(type).toUpperCase();
|
|
32
|
+
}
|
|
30
33
|
const url = `${baseURL}${API_PATHS.APPOINTMENTS}`;
|
|
31
34
|
|
|
32
35
|
// Return raw response (including status) so caller can detect 401 and re-login
|
|
@@ -73,7 +76,7 @@ export const initiateConsultation = async (appointment, config = {}) => {
|
|
|
73
76
|
const body = {
|
|
74
77
|
patientId: String(appointment.patientId || ""),
|
|
75
78
|
primaryPatientId: String(appointment.primaryPatientId || appointment.patientId || ""),
|
|
76
|
-
hospitalId: config.hospitalId
|
|
79
|
+
hospitalId: config.hospitalId,
|
|
77
80
|
doctorId: String(config.doctorId),
|
|
78
81
|
patientName: appointment.patientName || appointment.name || "",
|
|
79
82
|
doctorName: appointment.doctorName || config.doctorName,
|