pih-appointment-widget 0.0.34 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -70
- package/babel.config.js +5 -5
- package/dist/App.js +9 -10
- package/dist/Example.js +2 -1
- package/dist/components/AppointmentPage.js +59 -80
- package/dist/components/ICD10Assistant.js +898 -0
- package/dist/constants/apiConfig.js +2 -1
- package/dist/doctor-appointments-widget.umd.js +137 -122
- package/dist/doctor-appointments-widget.umd.min.js +1 -1
- package/dist/hooks/useClipboard.js +41 -0
- package/dist/pih-appointment-widget.umd.js +120 -115
- package/dist/pih-appointment-widget.umd.min.js +1 -1
- package/dist/services/appointmentService.js +20 -20
- package/dist/services/httpService.js +18 -14
- package/dist/services/icdService.js +87 -0
- package/package.json +67 -67
- package/public/index.html +43 -43
- package/public/manifest.json +25 -25
- package/public/robots.txt +3 -3
- package/rollup.config.js +43 -43
- package/src/App.js +48 -48
- package/src/Example.js +14 -11
- package/src/components/AppointmentPage.js +2498 -2498
- package/src/components/ICD10Assistant.jsx +855 -0
- package/src/constants/apiConfig.js +29 -28
- package/src/hooks/useClipboard.js +35 -0
- package/src/index.js +6 -6
- package/src/services/appointmentService.js +92 -92
- package/src/services/httpService.js +103 -103
- package/src/services/icdService.js +76 -0
package/README.md
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
# Getting Started with Create React App
|
|
2
|
-
|
|
3
|
-
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
|
4
|
-
|
|
5
|
-
## Available Scripts
|
|
6
|
-
|
|
7
|
-
In the project directory, you can run:
|
|
8
|
-
|
|
9
|
-
### `npm start`
|
|
10
|
-
|
|
11
|
-
Runs the app in the development mode.\
|
|
12
|
-
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
|
13
|
-
|
|
14
|
-
The page will reload when you make changes.\
|
|
15
|
-
You may also see any lint errors in the console.
|
|
16
|
-
|
|
17
|
-
### `npm test`
|
|
18
|
-
|
|
19
|
-
Launches the test runner in the interactive watch mode.\
|
|
20
|
-
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
|
21
|
-
|
|
22
|
-
### `npm run build`
|
|
23
|
-
|
|
24
|
-
Builds the app for production to the `build` folder.\
|
|
25
|
-
It correctly bundles React in production mode and optimizes the build for the best performance.
|
|
26
|
-
|
|
27
|
-
The build is minified and the filenames include the hashes.\
|
|
28
|
-
Your app is ready to be deployed!
|
|
29
|
-
|
|
30
|
-
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
|
31
|
-
|
|
32
|
-
### `npm run eject`
|
|
33
|
-
|
|
34
|
-
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
|
35
|
-
|
|
36
|
-
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
|
37
|
-
|
|
38
|
-
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
|
39
|
-
|
|
40
|
-
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
|
41
|
-
|
|
42
|
-
## Learn More
|
|
43
|
-
|
|
44
|
-
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
|
45
|
-
|
|
46
|
-
To learn React, check out the [React documentation](https://reactjs.org/).
|
|
47
|
-
|
|
48
|
-
### Code Splitting
|
|
49
|
-
|
|
50
|
-
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
|
51
|
-
|
|
52
|
-
### Analyzing the Bundle Size
|
|
53
|
-
|
|
54
|
-
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
|
55
|
-
|
|
56
|
-
### Making a Progressive Web App
|
|
57
|
-
|
|
58
|
-
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
|
59
|
-
|
|
60
|
-
### Advanced Configuration
|
|
61
|
-
|
|
62
|
-
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
|
63
|
-
|
|
64
|
-
### Deployment
|
|
65
|
-
|
|
66
|
-
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
|
67
|
-
|
|
68
|
-
### `npm run build` fails to minify
|
|
69
|
-
|
|
70
|
-
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
|
1
|
+
# Getting Started with Create React App
|
|
2
|
+
|
|
3
|
+
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
|
4
|
+
|
|
5
|
+
## Available Scripts
|
|
6
|
+
|
|
7
|
+
In the project directory, you can run:
|
|
8
|
+
|
|
9
|
+
### `npm start`
|
|
10
|
+
|
|
11
|
+
Runs the app in the development mode.\
|
|
12
|
+
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
|
13
|
+
|
|
14
|
+
The page will reload when you make changes.\
|
|
15
|
+
You may also see any lint errors in the console.
|
|
16
|
+
|
|
17
|
+
### `npm test`
|
|
18
|
+
|
|
19
|
+
Launches the test runner in the interactive watch mode.\
|
|
20
|
+
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
|
21
|
+
|
|
22
|
+
### `npm run build`
|
|
23
|
+
|
|
24
|
+
Builds the app for production to the `build` folder.\
|
|
25
|
+
It correctly bundles React in production mode and optimizes the build for the best performance.
|
|
26
|
+
|
|
27
|
+
The build is minified and the filenames include the hashes.\
|
|
28
|
+
Your app is ready to be deployed!
|
|
29
|
+
|
|
30
|
+
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
|
31
|
+
|
|
32
|
+
### `npm run eject`
|
|
33
|
+
|
|
34
|
+
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
|
35
|
+
|
|
36
|
+
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
|
37
|
+
|
|
38
|
+
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
|
39
|
+
|
|
40
|
+
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
|
41
|
+
|
|
42
|
+
## Learn More
|
|
43
|
+
|
|
44
|
+
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
|
45
|
+
|
|
46
|
+
To learn React, check out the [React documentation](https://reactjs.org/).
|
|
47
|
+
|
|
48
|
+
### Code Splitting
|
|
49
|
+
|
|
50
|
+
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
|
51
|
+
|
|
52
|
+
### Analyzing the Bundle Size
|
|
53
|
+
|
|
54
|
+
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
|
55
|
+
|
|
56
|
+
### Making a Progressive Web App
|
|
57
|
+
|
|
58
|
+
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
|
59
|
+
|
|
60
|
+
### Advanced Configuration
|
|
61
|
+
|
|
62
|
+
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
|
63
|
+
|
|
64
|
+
### Deployment
|
|
65
|
+
|
|
66
|
+
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
|
67
|
+
|
|
68
|
+
### `npm run build` fails to minify
|
|
69
|
+
|
|
70
|
+
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
package/babel.config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
presets: [
|
|
3
|
-
'@babel/preset-env',
|
|
4
|
-
'@babel/preset-react'
|
|
5
|
-
],
|
|
1
|
+
module.exports = {
|
|
2
|
+
presets: [
|
|
3
|
+
'@babel/preset-env',
|
|
4
|
+
'@babel/preset-react'
|
|
5
|
+
],
|
|
6
6
|
};
|
package/dist/App.js
CHANGED
|
@@ -19,21 +19,20 @@ exports.default = void 0;
|
|
|
19
19
|
var _react = _interopRequireDefault(require("react"));
|
|
20
20
|
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
21
21
|
var _AppointmentPage = _interopRequireWildcard(require("./components/AppointmentPage.js"));
|
|
22
|
-
function
|
|
23
|
-
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
22
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
24
23
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
25
24
|
let bookingWidgetInstance = null;
|
|
26
25
|
|
|
27
26
|
// SDK for embedding appointment widget
|
|
28
27
|
const BookingSDK = {
|
|
29
|
-
/**
|
|
30
|
-
* Show appointment widget with configuration
|
|
31
|
-
* @param {object} config - Configuration object
|
|
32
|
-
* @param {string} config.apiBaseUrl - Base URL for API
|
|
33
|
-
* @param {string} config.hospitalId - Hospital ID
|
|
34
|
-
* @param {number} config.doctorId - Doctor ID
|
|
35
|
-
* @param {string} config.joinCallUrl - Video call URL
|
|
36
|
-
* @param {function} onAction - Optional callback for actions
|
|
28
|
+
/**
|
|
29
|
+
* Show appointment widget with configuration
|
|
30
|
+
* @param {object} config - Configuration object
|
|
31
|
+
* @param {string} config.apiBaseUrl - Base URL for API
|
|
32
|
+
* @param {string} config.hospitalId - Hospital ID
|
|
33
|
+
* @param {number} config.doctorId - Doctor ID
|
|
34
|
+
* @param {string} config.joinCallUrl - Video call URL
|
|
35
|
+
* @param {function} onAction - Optional callback for actions
|
|
37
36
|
*/
|
|
38
37
|
showWidget: (config, onAction) => {
|
|
39
38
|
if (!bookingWidgetInstance) {
|
package/dist/Example.js
CHANGED
|
@@ -5,8 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _AppointmentPage = _interopRequireDefault(require("./components/AppointmentPage.js"));
|
|
8
|
+
var _ICD10Assistant = _interopRequireDefault(require("./components/ICD10Assistant.jsx"));
|
|
8
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
10
|
const Example = () => {
|
|
10
|
-
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_AppointmentPage.default, null));
|
|
11
|
+
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_AppointmentPage.default, null), /*#__PURE__*/React.createElement(_ICD10Assistant.default, null));
|
|
11
12
|
};
|
|
12
13
|
var _default = exports.default = Example;
|
|
@@ -8,8 +8,10 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _appointmentService = require("../services/appointmentService");
|
|
9
9
|
var _httpService = require("../services/httpService");
|
|
10
10
|
var _apiConfig = require("../constants/apiConfig");
|
|
11
|
-
function
|
|
12
|
-
function
|
|
11
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
12
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
13
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
15
|
// Decode JWT payload (no verification; for display only). Returns {} on invalid/missing.
|
|
14
16
|
function getJwtPayload(token) {
|
|
15
17
|
if (!token || typeof token !== "string") return {};
|
|
@@ -19,7 +21,7 @@ function getJwtPayload(token) {
|
|
|
19
21
|
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
20
22
|
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
21
23
|
return JSON.parse(atob(padded));
|
|
22
|
-
} catch {
|
|
24
|
+
} catch (_unused) {
|
|
23
25
|
return {};
|
|
24
26
|
}
|
|
25
27
|
}
|
|
@@ -39,26 +41,32 @@ const PIH_APPOINTMENT_WIDGET_DATA_ATTR = "data-pih-widget";
|
|
|
39
41
|
|
|
40
42
|
// Extract from SSO login response (not from appToken JWT — these are only in login response)
|
|
41
43
|
function extractAppToken(response) {
|
|
44
|
+
var _ref, _ref2, _ref3, _response$data$access, _response$data, _response$data2;
|
|
42
45
|
if (!response || response.err) return null;
|
|
43
|
-
return response.data
|
|
46
|
+
return (_ref = (_ref2 = (_ref3 = (_response$data$access = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.access_token) !== null && _response$data$access !== void 0 ? _response$data$access : (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.token) !== null && _ref3 !== void 0 ? _ref3 : response.token) !== null && _ref2 !== void 0 ? _ref2 : response.accessToken) !== null && _ref !== void 0 ? _ref : null;
|
|
44
47
|
}
|
|
45
48
|
function extractDoctorIdFromLoginResponse(response) {
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
var _ref4, _response$data$doctor;
|
|
50
|
+
if (!(response !== null && response !== void 0 && response.data)) return null;
|
|
51
|
+
const id = (_ref4 = (_response$data$doctor = response.data.doctor_id) !== null && _response$data$doctor !== void 0 ? _response$data$doctor : response.data.doctorId) !== null && _ref4 !== void 0 ? _ref4 : null;
|
|
48
52
|
console.log(id, 'extractDoctorIdFromLoginResponse -> id');
|
|
49
53
|
return id != null ? String(id) : null;
|
|
50
54
|
}
|
|
51
55
|
function extractUserNameFromLoginResponse(response) {
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
var _ref5, _ref6, _response$data$name;
|
|
57
|
+
if (!(response !== null && response !== void 0 && response.data)) return null;
|
|
58
|
+
const name = (_ref5 = (_ref6 = (_response$data$name = response.data.name) !== null && _response$data$name !== void 0 ? _response$data$name : response.data.doctor_name) !== null && _ref6 !== void 0 ? _ref6 : response.data.userName) !== null && _ref5 !== void 0 ? _ref5 : null;
|
|
54
59
|
return name != null ? String(name) : null;
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
// Error boundary so a render error never shows a blank screen
|
|
58
63
|
class AppointmentErrorBoundary extends _react.Component {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
constructor() {
|
|
65
|
+
super(...arguments);
|
|
66
|
+
_defineProperty(this, "state", {
|
|
67
|
+
hasError: false
|
|
68
|
+
});
|
|
69
|
+
}
|
|
62
70
|
static getDerivedStateFromError() {
|
|
63
71
|
return {
|
|
64
72
|
hasError: true
|
|
@@ -115,21 +123,21 @@ class AppointmentErrorBoundary extends _react.Component {
|
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
// SDK Component - accepts configuration from parent app
|
|
118
|
-
const AppointmentPage =
|
|
126
|
+
const AppointmentPage = _ref7 => {
|
|
119
127
|
let {
|
|
120
128
|
config = {}
|
|
121
|
-
} =
|
|
129
|
+
} = _ref7;
|
|
122
130
|
const [storedApiBaseUrl, setStoredApiBaseUrl] = (0, _react.useState)(() => {
|
|
123
131
|
try {
|
|
124
132
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_API_BASE_URL) : null;
|
|
125
|
-
} catch {
|
|
133
|
+
} catch (_unused2) {
|
|
126
134
|
return null;
|
|
127
135
|
}
|
|
128
136
|
});
|
|
129
137
|
const [storedHospitalId, setStoredHospitalId] = (0, _react.useState)(() => {
|
|
130
138
|
try {
|
|
131
139
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_HOSPITAL_ID) : null;
|
|
132
|
-
} catch {
|
|
140
|
+
} catch (_unused3) {
|
|
133
141
|
return null;
|
|
134
142
|
}
|
|
135
143
|
});
|
|
@@ -140,14 +148,14 @@ const AppointmentPage = _ref => {
|
|
|
140
148
|
const [storedIdToken, setStoredIdToken] = (0, _react.useState)(() => {
|
|
141
149
|
try {
|
|
142
150
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_ID_TOKEN) : null;
|
|
143
|
-
} catch {
|
|
151
|
+
} catch (_unused4) {
|
|
144
152
|
return null;
|
|
145
153
|
}
|
|
146
154
|
});
|
|
147
155
|
const [storedEmail, setStoredEmail] = (0, _react.useState)(() => {
|
|
148
156
|
try {
|
|
149
157
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_EMAIL) : null;
|
|
150
|
-
} catch {
|
|
158
|
+
} catch (_unused5) {
|
|
151
159
|
return null;
|
|
152
160
|
}
|
|
153
161
|
});
|
|
@@ -192,21 +200,21 @@ const AppointmentPage = _ref => {
|
|
|
192
200
|
const [appToken, setAppToken] = (0, _react.useState)(() => {
|
|
193
201
|
try {
|
|
194
202
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_APP_TOKEN) : null;
|
|
195
|
-
} catch {
|
|
203
|
+
} catch (_unused6) {
|
|
196
204
|
return null;
|
|
197
205
|
}
|
|
198
206
|
});
|
|
199
207
|
const [doctorIdFromLogin, setDoctorIdFromLogin] = (0, _react.useState)(() => {
|
|
200
208
|
try {
|
|
201
209
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_DOCTOR_ID) : null;
|
|
202
|
-
} catch {
|
|
210
|
+
} catch (_unused7) {
|
|
203
211
|
return null;
|
|
204
212
|
}
|
|
205
213
|
});
|
|
206
214
|
const [userName, setUserName] = (0, _react.useState)(() => {
|
|
207
215
|
try {
|
|
208
216
|
return typeof localStorage !== "undefined" ? localStorage.getItem(STORAGE_KEY_USER_NAME) : null;
|
|
209
|
-
} catch {
|
|
217
|
+
} catch (_unused8) {
|
|
210
218
|
return null;
|
|
211
219
|
}
|
|
212
220
|
});
|
|
@@ -217,7 +225,7 @@ const AppointmentPage = _ref => {
|
|
|
217
225
|
const hasId = localStorage.getItem(STORAGE_KEY_ID_TOKEN);
|
|
218
226
|
const hasEmail = localStorage.getItem(STORAGE_KEY_EMAIL);
|
|
219
227
|
return !hasApp && !!(hasId && hasEmail);
|
|
220
|
-
} catch {
|
|
228
|
+
} catch (_unused9) {
|
|
221
229
|
return false;
|
|
222
230
|
}
|
|
223
231
|
});
|
|
@@ -279,7 +287,7 @@ const AppointmentPage = _ref => {
|
|
|
279
287
|
const y = date.getFullYear();
|
|
280
288
|
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
281
289
|
const d = String(date.getDate()).padStart(2, "0");
|
|
282
|
-
return
|
|
290
|
+
return "".concat(y, "-").concat(m, "-").concat(d);
|
|
283
291
|
};
|
|
284
292
|
const getDateRange = option => {
|
|
285
293
|
const today = new Date();
|
|
@@ -310,8 +318,8 @@ const AppointmentPage = _ref => {
|
|
|
310
318
|
to = formatLocalDate(lastOfMonth);
|
|
311
319
|
break;
|
|
312
320
|
case "currentYear":
|
|
313
|
-
from =
|
|
314
|
-
to =
|
|
321
|
+
from = "".concat(today.getFullYear(), "-01-01");
|
|
322
|
+
to = "".concat(today.getFullYear(), "-12-31");
|
|
315
323
|
break;
|
|
316
324
|
default:
|
|
317
325
|
from = to = getTodayDate();
|
|
@@ -336,7 +344,7 @@ const AppointmentPage = _ref => {
|
|
|
336
344
|
case "currentYear":
|
|
337
345
|
return "Current Year";
|
|
338
346
|
case "custom":
|
|
339
|
-
return isMobile ? "Custom" :
|
|
347
|
+
return isMobile ? "Custom" : "".concat(fromDate, " to ").concat(toDate);
|
|
340
348
|
default:
|
|
341
349
|
return "Today";
|
|
342
350
|
}
|
|
@@ -421,12 +429,12 @@ const AppointmentPage = _ref => {
|
|
|
421
429
|
|
|
422
430
|
// Helper to get unique identifier from appointment
|
|
423
431
|
const getAppointmentId = appointment => {
|
|
424
|
-
return appointment
|
|
432
|
+
return (appointment === null || appointment === void 0 ? void 0 : appointment.id) || (appointment === null || appointment === void 0 ? void 0 : appointment._id) || (appointment === null || appointment === void 0 ? void 0 : appointment.appointmentId) || (appointment === null || appointment === void 0 ? void 0 : appointment.patientId) || JSON.stringify(appointment);
|
|
425
433
|
};
|
|
426
434
|
|
|
427
435
|
// Generate avatar with first letter if no image
|
|
428
436
|
const getPatientAvatar = appointment => {
|
|
429
|
-
if (appointment
|
|
437
|
+
if (appointment !== null && appointment !== void 0 && appointment.image) {
|
|
430
438
|
return appointment.image;
|
|
431
439
|
}
|
|
432
440
|
// Return null to use the letter avatar component
|
|
@@ -547,8 +555,8 @@ const AppointmentPage = _ref => {
|
|
|
547
555
|
// Returns true if the current time is within 2 hours after the appointment's scheduled slot time.
|
|
548
556
|
// Handles date format: "Sun, 15 Mar 2026" and time format: "12:15 PM"
|
|
549
557
|
const isWithinJoinWindow = appointment => {
|
|
550
|
-
const dateStr = appointment
|
|
551
|
-
const timeStr = appointment
|
|
558
|
+
const dateStr = (appointment === null || appointment === void 0 ? void 0 : appointment.date) || (appointment === null || appointment === void 0 ? void 0 : appointment.appointmentDate);
|
|
559
|
+
const timeStr = (appointment === null || appointment === void 0 ? void 0 : appointment.time) || (appointment === null || appointment === void 0 ? void 0 : appointment.appointmentTime);
|
|
552
560
|
if (!dateStr || !timeStr) return false;
|
|
553
561
|
try {
|
|
554
562
|
// Parse "12:15 PM" or "9:30 AM" into 24-hour h/m values
|
|
@@ -568,11 +576,11 @@ const AppointmentPage = _ref => {
|
|
|
568
576
|
}
|
|
569
577
|
if (isNaN(h) || isNaN(m)) return false;
|
|
570
578
|
// "Sun, 15 Mar 2026 12:15:00" — space-separated; JS parses RFC-like date strings correctly
|
|
571
|
-
const appointmentDate = new Date(
|
|
579
|
+
const appointmentDate = new Date("".concat(dateStr, " ").concat(String(h).padStart(2, "0"), ":").concat(String(m).padStart(2, "0"), ":00"));
|
|
572
580
|
if (isNaN(appointmentDate.getTime())) return false;
|
|
573
581
|
const windowEnd = new Date(appointmentDate.getTime() + 2 * 60 * 60 * 1000);
|
|
574
582
|
return new Date() <= windowEnd;
|
|
575
|
-
} catch {
|
|
583
|
+
} catch (_unused0) {
|
|
576
584
|
return false;
|
|
577
585
|
}
|
|
578
586
|
};
|
|
@@ -583,6 +591,7 @@ const AppointmentPage = _ref => {
|
|
|
583
591
|
setCallLoading(true);
|
|
584
592
|
setCallError(null);
|
|
585
593
|
try {
|
|
594
|
+
var _response$data3;
|
|
586
595
|
const callConfig = {
|
|
587
596
|
apiBaseUrl,
|
|
588
597
|
hospitalId,
|
|
@@ -610,7 +619,7 @@ const AppointmentPage = _ref => {
|
|
|
610
619
|
setCallError("Session expired. Re-authenticating...");
|
|
611
620
|
return;
|
|
612
621
|
}
|
|
613
|
-
if (response.err || !response.data
|
|
622
|
+
if (response.err || !((_response$data3 = response.data) !== null && _response$data3 !== void 0 && _response$data3.token)) {
|
|
614
623
|
setCallError(String(response.err || "Failed to initiate call"));
|
|
615
624
|
return;
|
|
616
625
|
}
|
|
@@ -859,7 +868,7 @@ const AppointmentPage = _ref => {
|
|
|
859
868
|
}
|
|
860
869
|
}).catch(err => {
|
|
861
870
|
if (!cancelled) {
|
|
862
|
-
setTokenError(err
|
|
871
|
+
setTokenError((err === null || err === void 0 ? void 0 : err.message) || "Authentication failed. Please try again.");
|
|
863
872
|
setAppToken(null);
|
|
864
873
|
}
|
|
865
874
|
}).finally(() => {
|
|
@@ -891,32 +900,7 @@ const AppointmentPage = _ref => {
|
|
|
891
900
|
|
|
892
901
|
// Add responsive styles and animations
|
|
893
902
|
const style = document.createElement("style");
|
|
894
|
-
style.innerHTML =
|
|
895
|
-
@keyframes spin {
|
|
896
|
-
0% { transform: rotate(0deg); }
|
|
897
|
-
100% { transform: rotate(360deg); }
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
@media (max-width: 768px) {
|
|
901
|
-
.appointments-grid {
|
|
902
|
-
grid-template-columns: 1.5fr 1fr 0.8fr !important;
|
|
903
|
-
}
|
|
904
|
-
.appointments-header-grid {
|
|
905
|
-
grid-template-columns: 1.5fr 1fr 0.8fr !important;
|
|
906
|
-
}
|
|
907
|
-
.hide-on-mobile {
|
|
908
|
-
display: none !important;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
@media (max-width: 480px) {
|
|
912
|
-
.appointments-header-grid {
|
|
913
|
-
font-size: 10px !important;
|
|
914
|
-
}
|
|
915
|
-
.appointments-grid {
|
|
916
|
-
font-size: 11px !important;
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
`;
|
|
903
|
+
style.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 ";
|
|
920
904
|
document.head.appendChild(style);
|
|
921
905
|
|
|
922
906
|
// Handle window resize
|
|
@@ -969,7 +953,7 @@ const AppointmentPage = _ref => {
|
|
|
969
953
|
justifyContent: "center",
|
|
970
954
|
padding: "24px"
|
|
971
955
|
}
|
|
972
|
-
}, /*#__PURE__*/_react.default.createElement("style", null,
|
|
956
|
+
}, /*#__PURE__*/_react.default.createElement("style", null, "@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }"), /*#__PURE__*/_react.default.createElement("div", {
|
|
973
957
|
style: {
|
|
974
958
|
width: "40px",
|
|
975
959
|
height: "40px",
|
|
@@ -1728,7 +1712,7 @@ const AppointmentPage = _ref => {
|
|
|
1728
1712
|
style: {
|
|
1729
1713
|
fontSize: "13px"
|
|
1730
1714
|
}
|
|
1731
|
-
}, searchQuery ?
|
|
1715
|
+
}, searchQuery ? "No appointments found for \"".concat(searchQuery, "\"") : "No appointments found"), searchQuery && /*#__PURE__*/_react.default.createElement("button", {
|
|
1732
1716
|
onClick: () => setSearchQuery(""),
|
|
1733
1717
|
style: {
|
|
1734
1718
|
marginTop: "12px",
|
|
@@ -2007,7 +1991,7 @@ const AppointmentPage = _ref => {
|
|
|
2007
1991
|
fontWeight: "700",
|
|
2008
1992
|
fontSize: isMobile ? "12px" : "13px"
|
|
2009
1993
|
}
|
|
2010
|
-
}, selectedAppointment
|
|
1994
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.specialisation) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.speciality) || "N/A")), /*#__PURE__*/_react.default.createElement("div", {
|
|
2011
1995
|
style: {
|
|
2012
1996
|
textAlign: "right"
|
|
2013
1997
|
}
|
|
@@ -2022,7 +2006,7 @@ const AppointmentPage = _ref => {
|
|
|
2022
2006
|
fontWeight: "700",
|
|
2023
2007
|
fontSize: isMobile ? "12px" : "13px"
|
|
2024
2008
|
}
|
|
2025
|
-
}, selectedAppointment
|
|
2009
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.type) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.appointmentType) || "Online"))), /*#__PURE__*/_react.default.createElement("div", {
|
|
2026
2010
|
style: {
|
|
2027
2011
|
display: "flex",
|
|
2028
2012
|
justifyContent: "space-between"
|
|
@@ -2042,7 +2026,7 @@ const AppointmentPage = _ref => {
|
|
|
2042
2026
|
fontWeight: "700",
|
|
2043
2027
|
fontSize: isMobile ? "12px" : "13px"
|
|
2044
2028
|
}
|
|
2045
|
-
}, selectedAppointment
|
|
2029
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.date) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.appointmentDate) || "N/A")), /*#__PURE__*/_react.default.createElement("div", {
|
|
2046
2030
|
style: {
|
|
2047
2031
|
textAlign: "right"
|
|
2048
2032
|
}
|
|
@@ -2057,7 +2041,7 @@ const AppointmentPage = _ref => {
|
|
|
2057
2041
|
fontWeight: "700",
|
|
2058
2042
|
fontSize: isMobile ? "12px" : "13px"
|
|
2059
2043
|
}
|
|
2060
|
-
}, selectedAppointment
|
|
2044
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.time) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.appointmentTime) || "N/A"))), /*#__PURE__*/_react.default.createElement("div", {
|
|
2061
2045
|
style: {
|
|
2062
2046
|
display: "flex",
|
|
2063
2047
|
justifyContent: "space-between"
|
|
@@ -2077,7 +2061,7 @@ const AppointmentPage = _ref => {
|
|
|
2077
2061
|
fontWeight: "700",
|
|
2078
2062
|
fontSize: isMobile ? "12px" : "13px"
|
|
2079
2063
|
}
|
|
2080
|
-
}, selectedAppointment
|
|
2064
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.doctor) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.doctorName) || "N/A"))), /*#__PURE__*/_react.default.createElement("div", {
|
|
2081
2065
|
style: {
|
|
2082
2066
|
display: "flex",
|
|
2083
2067
|
justifyContent: "space-between"
|
|
@@ -2097,7 +2081,7 @@ const AppointmentPage = _ref => {
|
|
|
2097
2081
|
fontWeight: "700",
|
|
2098
2082
|
fontSize: isMobile ? "12px" : "13px"
|
|
2099
2083
|
}
|
|
2100
|
-
}, selectedAppointment
|
|
2084
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.hospital) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.hospitalName) || "N/A"))), /*#__PURE__*/_react.default.createElement("div", {
|
|
2101
2085
|
style: {
|
|
2102
2086
|
display: "flex",
|
|
2103
2087
|
justifyContent: "space-between"
|
|
@@ -2118,7 +2102,7 @@ const AppointmentPage = _ref => {
|
|
|
2118
2102
|
fontSize: isMobile ? "11px" : "12px",
|
|
2119
2103
|
lineHeight: "1.4"
|
|
2120
2104
|
}
|
|
2121
|
-
}, selectedAppointment
|
|
2105
|
+
}, (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.reason) || (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.reasonForAppointment) || "No reason provided"))), (activeTab === "upcoming" || activeTab === "completed" && isWithinJoinWindow(selectedAppointment)) && /*#__PURE__*/_react.default.createElement("div", {
|
|
2122
2106
|
style: {
|
|
2123
2107
|
display: "flex",
|
|
2124
2108
|
flexDirection: isMobile ? "column" : "row",
|
|
@@ -2171,12 +2155,12 @@ const AppointmentPage = _ref => {
|
|
|
2171
2155
|
}, "Select an appointment to view details"))))))), showPipVideo && /*#__PURE__*/_react.default.createElement("div", {
|
|
2172
2156
|
style: {
|
|
2173
2157
|
position: "fixed",
|
|
2174
|
-
left: isPipFullscreen ? "0" : isMobile ? "10px" :
|
|
2175
|
-
top: isPipFullscreen ? "0" : isMobile ? "70px" :
|
|
2158
|
+
left: isPipFullscreen ? "0" : isMobile ? "10px" : "".concat(pipPosition.x, "px"),
|
|
2159
|
+
top: isPipFullscreen ? "0" : isMobile ? "70px" : "".concat(pipPosition.y, "px"),
|
|
2176
2160
|
right: isPipFullscreen ? "0" : isMobile ? "10px" : "auto",
|
|
2177
2161
|
bottom: isPipFullscreen ? "0" : "auto",
|
|
2178
|
-
width: isPipFullscreen ? "100vw" : isMobile ? "calc(100vw - 20px)" : isPipMinimized ? "350px" :
|
|
2179
|
-
height: isPipFullscreen ? "100vh" : isPipMinimized ? "auto" : isMobile ? "300px" :
|
|
2162
|
+
width: isPipFullscreen ? "100vw" : isMobile ? "calc(100vw - 20px)" : isPipMinimized ? "350px" : "".concat(pipSize.width, "px"),
|
|
2163
|
+
height: isPipFullscreen ? "100vh" : isPipMinimized ? "auto" : isMobile ? "300px" : "".concat(pipSize.height, "px"),
|
|
2180
2164
|
background: "#FFFFFF",
|
|
2181
2165
|
borderRadius: isPipFullscreen ? "0" : "8px",
|
|
2182
2166
|
boxShadow: "0 8px 24px rgba(0, 0, 0, 0.3)",
|
|
@@ -2227,7 +2211,7 @@ const AppointmentPage = _ref => {
|
|
|
2227
2211
|
textOverflow: "ellipsis",
|
|
2228
2212
|
whiteSpace: "nowrap"
|
|
2229
2213
|
}
|
|
2230
|
-
}, "Video Call - ", selectedAppointment
|
|
2214
|
+
}, "Video Call - ", (selectedAppointment === null || selectedAppointment === void 0 ? void 0 : selectedAppointment.patientName) || "Patient")), /*#__PURE__*/_react.default.createElement("div", {
|
|
2231
2215
|
style: {
|
|
2232
2216
|
display: "flex",
|
|
2233
2217
|
gap: isMobile ? "4px" : "6px",
|
|
@@ -2356,7 +2340,7 @@ const AppointmentPage = _ref => {
|
|
|
2356
2340
|
src: (() => {
|
|
2357
2341
|
if (!callToken) return "";
|
|
2358
2342
|
const base = String(joinCallUrlBase || "");
|
|
2359
|
-
return
|
|
2343
|
+
return "".concat(base).concat(callToken);
|
|
2360
2344
|
})(),
|
|
2361
2345
|
style: {
|
|
2362
2346
|
width: "100%",
|
|
@@ -2427,12 +2411,7 @@ const AppointmentPage = _ref => {
|
|
|
2427
2411
|
background: "transparent",
|
|
2428
2412
|
zIndex: 10001
|
|
2429
2413
|
}
|
|
2430
|
-
})), /*#__PURE__*/_react.default.createElement("style", null,
|
|
2431
|
-
@keyframes pulse {
|
|
2432
|
-
0%, 100% { opacity: 1; }
|
|
2433
|
-
50% { opacity: 0.5; }
|
|
2434
|
-
}
|
|
2435
|
-
`))), showAuthError && /*#__PURE__*/_react.default.createElement("div", {
|
|
2414
|
+
})), /*#__PURE__*/_react.default.createElement("style", null, "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n "))), showAuthError && /*#__PURE__*/_react.default.createElement("div", {
|
|
2436
2415
|
style: {
|
|
2437
2416
|
position: "fixed",
|
|
2438
2417
|
inset: 0,
|