pih-appointment-widget 0.0.38 → 0.0.39
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 +10 -9
- package/dist/components/AppointmentPage.js +87 -62
- package/dist/components/ICD10Assistant.js +43 -46
- package/dist/doctor-appointments-widget.umd.js +115 -119
- package/dist/doctor-appointments-widget.umd.min.js +1 -1
- package/dist/hooks/useClipboard.js +3 -3
- package/dist/pih-appointment-widget.umd.js +185 -191
- package/dist/pih-appointment-widget.umd.min.js +1 -1
- package/dist/services/appointmentService.js +20 -20
- package/dist/services/httpService.js +14 -18
- package/dist/services/icdService.js +21 -23
- 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 +50 -50
- package/src/Example.js +14 -14
- package/src/assets/icons/icdIcons.js +23 -23
- package/src/components/AppointmentPage.js +2502 -2498
- package/src/components/ICD10Assistant.jsx +923 -923
- package/src/constants/apiConfig.js +29 -29
- package/src/hooks/useClipboard.js +35 -35
- 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 -76
|
@@ -8,11 +8,12 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _icdService = require("../services/icdService");
|
|
9
9
|
var _useClipboard = require("../hooks/useClipboard");
|
|
10
10
|
var _icdIcons = require("../assets/icons/icdIcons");
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
|
+
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; }
|
|
13
|
+
/**
|
|
14
|
+
* ICD10Assistant.jsx
|
|
15
|
+
* AI-powered ICD-10 coding assistant panel.
|
|
16
|
+
* Floats as a pill button; expands into a full panel on click.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
@@ -61,12 +62,12 @@ function Badge(_ref) {
|
|
|
61
62
|
}, children);
|
|
62
63
|
}
|
|
63
64
|
function Spinner() {
|
|
64
|
-
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("style", null,
|
|
65
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("style", null, `@keyframes icd-spin{to{transform:rotate(360deg)}}`), /*#__PURE__*/_react.default.createElement("div", {
|
|
65
66
|
style: {
|
|
66
67
|
width: 20,
|
|
67
68
|
height: 20,
|
|
68
69
|
border: "2.5px solid #d1d5db",
|
|
69
|
-
borderTop:
|
|
70
|
+
borderTop: `2.5px solid ${C.primary}`,
|
|
70
71
|
borderRadius: "50%",
|
|
71
72
|
animation: "icd-spin 0.8s linear infinite",
|
|
72
73
|
flexShrink: 0
|
|
@@ -84,7 +85,7 @@ function CopyButton(_ref2) {
|
|
|
84
85
|
const copied = copiedKey === copyKey;
|
|
85
86
|
return /*#__PURE__*/_react.default.createElement("button", {
|
|
86
87
|
onClick: () => copy(text, copyKey),
|
|
87
|
-
title: copied ? "Copied!" :
|
|
88
|
+
title: copied ? "Copied!" : `Copy ${label}`,
|
|
88
89
|
style: {
|
|
89
90
|
display: "inline-flex",
|
|
90
91
|
alignItems: "center",
|
|
@@ -93,7 +94,7 @@ function CopyButton(_ref2) {
|
|
|
93
94
|
fontSize: 11,
|
|
94
95
|
fontWeight: 600,
|
|
95
96
|
fontFamily: FONT,
|
|
96
|
-
border:
|
|
97
|
+
border: `1px solid ${copied ? C.success : C.border}`,
|
|
97
98
|
borderRadius: 5,
|
|
98
99
|
background: copied ? C.successLight : C.white,
|
|
99
100
|
color: copied ? C.success : C.muted,
|
|
@@ -101,7 +102,7 @@ function CopyButton(_ref2) {
|
|
|
101
102
|
transition: "all 0.15s ease",
|
|
102
103
|
whiteSpace: "nowrap"
|
|
103
104
|
}
|
|
104
|
-
}, copied ? "✓ Copied" :
|
|
105
|
+
}, copied ? "✓ Copied" : `⎘ ${label}`);
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
// ─── Result Card ──────────────────────────────────────────────────────────────
|
|
@@ -112,11 +113,11 @@ function ResultCard(_ref3) {
|
|
|
112
113
|
copy,
|
|
113
114
|
copiedKey
|
|
114
115
|
} = _ref3;
|
|
115
|
-
const cardCopyKey =
|
|
116
|
-
const fullText =
|
|
116
|
+
const cardCopyKey = `card-${index}`;
|
|
117
|
+
const fullText = `${match.code} — ${match.description}${match.reason ? `\nNote: ${match.reason}` : ""}`;
|
|
117
118
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
118
119
|
style: {
|
|
119
|
-
border:
|
|
120
|
+
border: `1px solid ${C.border}`,
|
|
120
121
|
borderRadius: 10,
|
|
121
122
|
padding: "14px 16px",
|
|
122
123
|
background: C.white,
|
|
@@ -174,10 +175,10 @@ function HistoryChip(_ref4) {
|
|
|
174
175
|
} = _ref4;
|
|
175
176
|
return /*#__PURE__*/_react.default.createElement("button", {
|
|
176
177
|
onClick: () => onClick(item.query),
|
|
177
|
-
title:
|
|
178
|
+
title: `Re-run: ${item.query}`,
|
|
178
179
|
style: {
|
|
179
180
|
padding: "4px 10px",
|
|
180
|
-
border:
|
|
181
|
+
border: `1px solid ${C.border}`,
|
|
181
182
|
borderRadius: 999,
|
|
182
183
|
fontSize: 11,
|
|
183
184
|
fontFamily: FONT,
|
|
@@ -250,10 +251,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
250
251
|
const debounceRef = (0, _react.useRef)(null);
|
|
251
252
|
const inputRef = (0, _react.useRef)(null);
|
|
252
253
|
(0, _react.useEffect)(() => {
|
|
253
|
-
setTimeout(() =>
|
|
254
|
-
var _inputRef$current;
|
|
255
|
-
return (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
256
|
-
}, 80);
|
|
254
|
+
setTimeout(() => inputRef.current?.focus(), 80);
|
|
257
255
|
}, []);
|
|
258
256
|
const search = (0, _react.useCallback)(async term => {
|
|
259
257
|
if (term.length < 2) {
|
|
@@ -266,7 +264,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
266
264
|
const data = await (0, _icdService.getICDSuggestions)(term, _icdService.ICD_MODE.ICD_ONLY);
|
|
267
265
|
const codes = (data.matches || []).map(m => [m.code, m.description]);
|
|
268
266
|
setResults(codes);
|
|
269
|
-
setStatus(codes.length === 0 ? "No matching codes found." :
|
|
267
|
+
setStatus(codes.length === 0 ? "No matching codes found." : `Showing ${codes.length} result${codes.length !== 1 ? "s" : ""}`);
|
|
270
268
|
} catch (err) {
|
|
271
269
|
setStatus(err.message || "Could not fetch results. Check your connection.");
|
|
272
270
|
setResults([]);
|
|
@@ -302,9 +300,9 @@ function NLMLookupPanel(_ref6) {
|
|
|
302
300
|
overflow: "hidden",
|
|
303
301
|
animation: "icd-slide-in 0.2s ease"
|
|
304
302
|
}
|
|
305
|
-
}, /*#__PURE__*/_react.default.createElement("style", null,
|
|
303
|
+
}, /*#__PURE__*/_react.default.createElement("style", null, `@keyframes icd-slide-in{from{opacity:0;transform:translateY(20px) scale(0.97)}to{opacity:1;transform:translateY(0) scale(1)}}`), /*#__PURE__*/_react.default.createElement("div", {
|
|
306
304
|
style: {
|
|
307
|
-
background:
|
|
305
|
+
background: `linear-gradient(135deg, ${C.primary} 0%, ${C.teal} 100%)`,
|
|
308
306
|
padding: "14px 18px",
|
|
309
307
|
flexShrink: 0
|
|
310
308
|
}
|
|
@@ -379,7 +377,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
379
377
|
padding: "10px 14px",
|
|
380
378
|
fontSize: 14,
|
|
381
379
|
fontFamily: FONT,
|
|
382
|
-
border:
|
|
380
|
+
border: `1.5px solid ${C.border}`,
|
|
383
381
|
borderRadius: 8,
|
|
384
382
|
outline: "none",
|
|
385
383
|
boxSizing: "border-box",
|
|
@@ -393,7 +391,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
393
391
|
fontSize: 11,
|
|
394
392
|
color: "#aaa",
|
|
395
393
|
lineHeight: 1.6,
|
|
396
|
-
borderLeft:
|
|
394
|
+
borderLeft: `3px solid ${C.border}`,
|
|
397
395
|
paddingLeft: 8
|
|
398
396
|
}
|
|
399
397
|
}, /*#__PURE__*/_react.default.createElement("strong", null, "Note:"), " Use short, specific keywords for better results, or try", " ", /*#__PURE__*/_react.default.createElement("button", {
|
|
@@ -418,7 +416,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
418
416
|
}, status), status === "No matching codes found." && results.length === 0 && /*#__PURE__*/_react.default.createElement("div", {
|
|
419
417
|
style: {
|
|
420
418
|
background: C.warnLight,
|
|
421
|
-
border:
|
|
419
|
+
border: `1px solid #fcd34d`,
|
|
422
420
|
borderRadius: 10,
|
|
423
421
|
padding: "14px 16px",
|
|
424
422
|
display: "flex",
|
|
@@ -473,7 +471,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
473
471
|
alignItems: "center",
|
|
474
472
|
gap: 12,
|
|
475
473
|
padding: "10px 14px",
|
|
476
|
-
border:
|
|
474
|
+
border: `1px solid ${C.border}`,
|
|
477
475
|
borderRadius: 8,
|
|
478
476
|
cursor: "pointer",
|
|
479
477
|
background: C.white,
|
|
@@ -509,7 +507,7 @@ function NLMLookupPanel(_ref6) {
|
|
|
509
507
|
style: {
|
|
510
508
|
flexShrink: 0,
|
|
511
509
|
padding: "10px 18px",
|
|
512
|
-
borderTop:
|
|
510
|
+
borderTop: `1px solid ${C.border}`,
|
|
513
511
|
background: C.bg,
|
|
514
512
|
fontSize: 11,
|
|
515
513
|
color: "#aaa",
|
|
@@ -538,7 +536,7 @@ function FloatingButton(_ref8) {
|
|
|
538
536
|
padding: "10px 18px",
|
|
539
537
|
borderRadius: 999,
|
|
540
538
|
border: "none",
|
|
541
|
-
background:
|
|
539
|
+
background: `linear-gradient(135deg, ${C.primary} 0%, ${C.teal} 100%)`,
|
|
542
540
|
color: C.white,
|
|
543
541
|
fontFamily: FONT,
|
|
544
542
|
fontWeight: 700,
|
|
@@ -569,7 +567,6 @@ function FloatingButton(_ref8) {
|
|
|
569
567
|
// ─── Panel ────────────────────────────────────────────────────────────────────
|
|
570
568
|
// Defined OUTSIDE the main component so its DOM is never torn down on re-render.
|
|
571
569
|
function Panel(_ref9) {
|
|
572
|
-
var _result$matches;
|
|
573
570
|
let {
|
|
574
571
|
panelRef,
|
|
575
572
|
textareaRef,
|
|
@@ -589,7 +586,7 @@ function Panel(_ref9) {
|
|
|
589
586
|
mode,
|
|
590
587
|
onModeChange
|
|
591
588
|
} = _ref9;
|
|
592
|
-
const allCodesText =
|
|
589
|
+
const allCodesText = result?.matches?.map(m => `${m.code} — ${m.description}`).join("\n") || "";
|
|
593
590
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
594
591
|
style: {
|
|
595
592
|
position: "fixed",
|
|
@@ -608,9 +605,14 @@ function Panel(_ref9) {
|
|
|
608
605
|
animation: "icd-slide-in 0.2s ease"
|
|
609
606
|
},
|
|
610
607
|
ref: panelRef
|
|
611
|
-
}, /*#__PURE__*/_react.default.createElement("style", null,
|
|
612
|
-
|
|
613
|
-
|
|
608
|
+
}, /*#__PURE__*/_react.default.createElement("style", null, `
|
|
609
|
+
@keyframes icd-slide-in {
|
|
610
|
+
from { opacity: 0; transform: translateY(20px) scale(0.97); }
|
|
611
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
612
|
+
}
|
|
613
|
+
`), /*#__PURE__*/_react.default.createElement("div", {
|
|
614
|
+
style: {
|
|
615
|
+
background: `linear-gradient(135deg, ${C.primary} 0%, ${C.teal} 100%)`,
|
|
614
616
|
padding: "14px 18px",
|
|
615
617
|
flexShrink: 0
|
|
616
618
|
}
|
|
@@ -706,7 +708,7 @@ function Panel(_ref9) {
|
|
|
706
708
|
style: {
|
|
707
709
|
width: "100%",
|
|
708
710
|
padding: "10px 12px",
|
|
709
|
-
border:
|
|
711
|
+
border: `1.5px solid ${C.border}`,
|
|
710
712
|
borderRadius: 8,
|
|
711
713
|
fontSize: 13,
|
|
712
714
|
fontFamily: FONT,
|
|
@@ -754,7 +756,7 @@ function Panel(_ref9) {
|
|
|
754
756
|
justifyContent: "center",
|
|
755
757
|
gap: 8,
|
|
756
758
|
padding: "10px 16px",
|
|
757
|
-
background: !query.trim() || loading ? "#d1d5db" :
|
|
759
|
+
background: !query.trim() || loading ? "#d1d5db" : `linear-gradient(135deg, ${C.primary} 0%, ${C.primaryDark} 100%)`,
|
|
758
760
|
color: C.white,
|
|
759
761
|
border: "none",
|
|
760
762
|
borderRadius: 8,
|
|
@@ -769,7 +771,7 @@ function Panel(_ref9) {
|
|
|
769
771
|
style: {
|
|
770
772
|
padding: "10px 14px",
|
|
771
773
|
background: C.bg,
|
|
772
|
-
border:
|
|
774
|
+
border: `1px solid ${C.border}`,
|
|
773
775
|
borderRadius: 8,
|
|
774
776
|
fontSize: 13,
|
|
775
777
|
fontWeight: 600,
|
|
@@ -780,7 +782,7 @@ function Panel(_ref9) {
|
|
|
780
782
|
}, "Clear")), error && /*#__PURE__*/_react.default.createElement("div", {
|
|
781
783
|
style: {
|
|
782
784
|
background: C.errorLight,
|
|
783
|
-
border:
|
|
785
|
+
border: `1px solid #fca5a5`,
|
|
784
786
|
borderRadius: 8,
|
|
785
787
|
padding: "10px 14px",
|
|
786
788
|
fontSize: 13,
|
|
@@ -864,7 +866,7 @@ function Panel(_ref9) {
|
|
|
864
866
|
style: {
|
|
865
867
|
flexShrink: 0,
|
|
866
868
|
padding: "12px 18px",
|
|
867
|
-
borderTop:
|
|
869
|
+
borderTop: `1px solid ${C.border}`,
|
|
868
870
|
background: C.bg,
|
|
869
871
|
fontSize: 11,
|
|
870
872
|
color: "#aaa",
|
|
@@ -893,10 +895,7 @@ function ICD10Assistant() {
|
|
|
893
895
|
// Focus textarea when panel opens
|
|
894
896
|
(0, _react.useEffect)(() => {
|
|
895
897
|
if (open && textareaRef.current) {
|
|
896
|
-
setTimeout(() =>
|
|
897
|
-
var _textareaRef$current;
|
|
898
|
-
return (_textareaRef$current = textareaRef.current) === null || _textareaRef$current === void 0 ? void 0 : _textareaRef$current.focus();
|
|
899
|
-
}, 80);
|
|
898
|
+
setTimeout(() => textareaRef.current?.focus(), 80);
|
|
900
899
|
}
|
|
901
900
|
}, [open]);
|
|
902
901
|
|
|
@@ -939,18 +938,16 @@ function ICD10Assistant() {
|
|
|
939
938
|
}
|
|
940
939
|
}, [handleSubmit]);
|
|
941
940
|
const handleClear = (0, _react.useCallback)(() => {
|
|
942
|
-
var _textareaRef$current2;
|
|
943
941
|
setQuery("");
|
|
944
942
|
setResult(null);
|
|
945
943
|
setError(null);
|
|
946
|
-
|
|
944
|
+
textareaRef.current?.focus();
|
|
947
945
|
}, []);
|
|
948
946
|
const handleHistoryClick = (0, _react.useCallback)(q => {
|
|
949
|
-
var _textareaRef$current3;
|
|
950
947
|
setQuery(q);
|
|
951
948
|
setResult(null);
|
|
952
949
|
setError(null);
|
|
953
|
-
|
|
950
|
+
textareaRef.current?.focus();
|
|
954
951
|
}, []);
|
|
955
952
|
const handleQueryChange = (0, _react.useCallback)(e => setQuery(e.target.value), []);
|
|
956
953
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, !open && /*#__PURE__*/_react.default.createElement(FloatingButton, {
|