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.
@@ -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 || _apiConfig.DEFAULT_PARAMS.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, 'PHYSICAL', serviceConfig);
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 || DEFAULT_PARAMS.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 || DEFAULT_PARAMS.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 || DEFAULT_PARAMS.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, 'PHYSICAL', serviceConfig);
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&&gt(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 || _apiConfig.DEFAULT_PARAMS.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 || _apiConfig.DEFAULT_PARAMS.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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pih-appointment-widget",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "main": "dist/App.js",
5
5
  "module": "dist/App.js",
6
6
  "exports": {
@@ -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 || DEFAULT_PARAMS.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, 'PHYSICAL', serviceConfig);
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 = 'ONLINE', config = {}) => {
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 || DEFAULT_PARAMS.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, type };
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 || DEFAULT_PARAMS.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,