formanitor 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +422 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +421 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -17,6 +17,7 @@ var reactTable = require('@tanstack/react-table');
|
|
|
17
17
|
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
18
18
|
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
19
19
|
var nlp = require('compromise');
|
|
20
|
+
var SliderPrimitive = require('@radix-ui/react-slider');
|
|
20
21
|
|
|
21
22
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
23
|
|
|
@@ -46,6 +47,7 @@ var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitiv
|
|
|
46
47
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
47
48
|
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
48
49
|
var nlp__default = /*#__PURE__*/_interopDefault(nlp);
|
|
50
|
+
var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
|
|
49
51
|
|
|
50
52
|
// src/core/validate.ts
|
|
51
53
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -6399,6 +6401,389 @@ var OphthalDiagnosisWidget = ({ fieldId }) => {
|
|
|
6399
6401
|
] })
|
|
6400
6402
|
] });
|
|
6401
6403
|
};
|
|
6404
|
+
var Slider = React11__namespace.forwardRef(({ className, trackClassName, thumbClassName, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6405
|
+
SliderPrimitive__namespace.Root,
|
|
6406
|
+
{
|
|
6407
|
+
ref,
|
|
6408
|
+
className: cn(
|
|
6409
|
+
"relative flex w-full touch-none select-none items-center",
|
|
6410
|
+
className
|
|
6411
|
+
),
|
|
6412
|
+
...props,
|
|
6413
|
+
children: [
|
|
6414
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6415
|
+
SliderPrimitive__namespace.Track,
|
|
6416
|
+
{
|
|
6417
|
+
className: cn(
|
|
6418
|
+
"relative h-2 w-full grow overflow-hidden rounded-full bg-gray-200",
|
|
6419
|
+
trackClassName
|
|
6420
|
+
),
|
|
6421
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Range, { className: "absolute h-full bg-primary" })
|
|
6422
|
+
}
|
|
6423
|
+
),
|
|
6424
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6425
|
+
SliderPrimitive__namespace.Thumb,
|
|
6426
|
+
{
|
|
6427
|
+
className: cn(
|
|
6428
|
+
"block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
6429
|
+
thumbClassName
|
|
6430
|
+
)
|
|
6431
|
+
}
|
|
6432
|
+
)
|
|
6433
|
+
]
|
|
6434
|
+
}
|
|
6435
|
+
));
|
|
6436
|
+
Slider.displayName = SliderPrimitive__namespace.Root.displayName;
|
|
6437
|
+
var CONCERNS = [
|
|
6438
|
+
{ id: "knee", label: "Knee" },
|
|
6439
|
+
{ id: "shoulder", label: "Shoulder" },
|
|
6440
|
+
{ id: "spine", label: "Spine" },
|
|
6441
|
+
{ id: "musculoskeletal_pain", label: "Musculoskeletal pain" },
|
|
6442
|
+
{ id: "hip", label: "Hip" },
|
|
6443
|
+
{ id: "trauma", label: "Trauma" },
|
|
6444
|
+
{ id: "other", label: "Other" }
|
|
6445
|
+
];
|
|
6446
|
+
var SIDE_PARTS = ["knee", "shoulder", "hip"];
|
|
6447
|
+
var REMINDERS = {
|
|
6448
|
+
knee: [
|
|
6449
|
+
"Inspect for swelling, deformity, scars.",
|
|
6450
|
+
"Palpate joint line, patella, and ligaments.",
|
|
6451
|
+
"Assess active/passive flexion and extension.",
|
|
6452
|
+
"Check stability (ACL/PCL/MCL/LCL) if appropriate."
|
|
6453
|
+
],
|
|
6454
|
+
shoulder: [
|
|
6455
|
+
"Inspect for asymmetry, wasting, deformity.",
|
|
6456
|
+
"Palpate AC joint, bicipital groove, cuff insertions.",
|
|
6457
|
+
"Assess active/passive ROM (flex/abd/ER/IR).",
|
|
6458
|
+
"Consider impingement/cuff tests if indicated."
|
|
6459
|
+
],
|
|
6460
|
+
hip: [
|
|
6461
|
+
"Inspect gait and standing alignment.",
|
|
6462
|
+
"Palpate greater trochanter and groin tenderness.",
|
|
6463
|
+
"Assess ROM (flex/ext/abd/add/IR/ER).",
|
|
6464
|
+
"Consider special tests (FABER/FADIR) if indicated."
|
|
6465
|
+
],
|
|
6466
|
+
spine: [
|
|
6467
|
+
"Inspect posture and spinal alignment.",
|
|
6468
|
+
"Palpate spinous/paraspinal tenderness.",
|
|
6469
|
+
"Assess ROM (flex/ext/lat bend/rotation).",
|
|
6470
|
+
"Document neuro screen if radicular symptoms."
|
|
6471
|
+
],
|
|
6472
|
+
musculoskeletal_pain: [
|
|
6473
|
+
"Localize pain and radiation; identify triggers/relievers.",
|
|
6474
|
+
"Inspect for swelling, erythema, deformity.",
|
|
6475
|
+
"Assess function and weight-bearing/ADLs impact."
|
|
6476
|
+
],
|
|
6477
|
+
trauma: [
|
|
6478
|
+
"Inspect for deformity, wounds, bruising.",
|
|
6479
|
+
"Check distal neurovascular status.",
|
|
6480
|
+
"Assess joint stability only if safe."
|
|
6481
|
+
],
|
|
6482
|
+
other: [
|
|
6483
|
+
"Clarify the concern and affected region.",
|
|
6484
|
+
"Document red flags (night pain, fever, weight loss)."
|
|
6485
|
+
]
|
|
6486
|
+
};
|
|
6487
|
+
var defaultValue = () => ({
|
|
6488
|
+
concerns: [],
|
|
6489
|
+
sides: {},
|
|
6490
|
+
painScore: 0,
|
|
6491
|
+
physicalExam: { inspection: "", palpation: "", rangeOfMotion: "" },
|
|
6492
|
+
reminders: { dismissed: false, position: { top: 96, right: 24 } }
|
|
6493
|
+
});
|
|
6494
|
+
var OrthopedicExamWidget = ({ fieldId }) => {
|
|
6495
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
6496
|
+
const { state } = useForm();
|
|
6497
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
6498
|
+
const safeValue = React11.useMemo(() => {
|
|
6499
|
+
if (!value || typeof value !== "object") return defaultValue();
|
|
6500
|
+
const v = value;
|
|
6501
|
+
const concerns = Array.isArray(v.concerns) ? v.concerns : [];
|
|
6502
|
+
const painScore = typeof v.painScore === "number" ? v.painScore : 0;
|
|
6503
|
+
const physicalExam = v.physicalExam ?? defaultValue().physicalExam;
|
|
6504
|
+
const reminders = v.reminders ?? defaultValue().reminders;
|
|
6505
|
+
return {
|
|
6506
|
+
concerns,
|
|
6507
|
+
sides: v.sides ?? {},
|
|
6508
|
+
painScore: Math.min(10, Math.max(0, Math.round(painScore))),
|
|
6509
|
+
physicalExam: {
|
|
6510
|
+
inspection: physicalExam.inspection ?? "",
|
|
6511
|
+
palpation: physicalExam.palpation ?? "",
|
|
6512
|
+
rangeOfMotion: physicalExam.rangeOfMotion ?? ""
|
|
6513
|
+
},
|
|
6514
|
+
reminders: {
|
|
6515
|
+
dismissed: !!reminders.dismissed,
|
|
6516
|
+
position: reminders.position ?? { top: 96, right: 24 }
|
|
6517
|
+
}
|
|
6518
|
+
};
|
|
6519
|
+
}, [value]);
|
|
6520
|
+
const [panelOpen, setPanelOpen] = React11.useState(false);
|
|
6521
|
+
const draggingRef = React11.useRef(null);
|
|
6522
|
+
const prevConcernsLengthRef = React11.useRef(safeValue.concerns.length);
|
|
6523
|
+
const reminderSections = React11.useMemo(() => {
|
|
6524
|
+
return safeValue.concerns.map((id) => ({
|
|
6525
|
+
id,
|
|
6526
|
+
label: CONCERNS.find((c) => c.id === id)?.label ?? id,
|
|
6527
|
+
points: REMINDERS[id] ?? []
|
|
6528
|
+
})).filter((s) => s.points.length > 0);
|
|
6529
|
+
}, [safeValue.concerns]);
|
|
6530
|
+
const hasReminders = reminderSections.length > 0;
|
|
6531
|
+
React11.useEffect(() => {
|
|
6532
|
+
const prevLen = prevConcernsLengthRef.current;
|
|
6533
|
+
const currLen = safeValue.concerns.length;
|
|
6534
|
+
prevConcernsLengthRef.current = currLen;
|
|
6535
|
+
if (currLen === 0) {
|
|
6536
|
+
if (safeValue.reminders.dismissed) {
|
|
6537
|
+
setValue({ ...safeValue, reminders: { ...safeValue.reminders, dismissed: false } });
|
|
6538
|
+
}
|
|
6539
|
+
setPanelOpen(false);
|
|
6540
|
+
return;
|
|
6541
|
+
}
|
|
6542
|
+
if (prevLen === 0 && currLen > 0 && !safeValue.reminders.dismissed) {
|
|
6543
|
+
setPanelOpen(true);
|
|
6544
|
+
}
|
|
6545
|
+
}, [safeValue, setValue]);
|
|
6546
|
+
React11.useEffect(() => {
|
|
6547
|
+
const onMove = (e) => {
|
|
6548
|
+
if (!draggingRef.current) return;
|
|
6549
|
+
const { startX, startY, startTop, startRight } = draggingRef.current;
|
|
6550
|
+
const dx = e.clientX - startX;
|
|
6551
|
+
const dy = e.clientY - startY;
|
|
6552
|
+
const nextPos = { top: startTop + dy, right: startRight - dx };
|
|
6553
|
+
setValue({
|
|
6554
|
+
...safeValue,
|
|
6555
|
+
reminders: {
|
|
6556
|
+
...safeValue.reminders,
|
|
6557
|
+
position: nextPos
|
|
6558
|
+
}
|
|
6559
|
+
});
|
|
6560
|
+
};
|
|
6561
|
+
const onUp = () => {
|
|
6562
|
+
draggingRef.current = null;
|
|
6563
|
+
};
|
|
6564
|
+
window.addEventListener("mousemove", onMove);
|
|
6565
|
+
window.addEventListener("mouseup", onUp);
|
|
6566
|
+
return () => {
|
|
6567
|
+
window.removeEventListener("mousemove", onMove);
|
|
6568
|
+
window.removeEventListener("mouseup", onUp);
|
|
6569
|
+
};
|
|
6570
|
+
}, [safeValue, setValue]);
|
|
6571
|
+
const update = (next) => {
|
|
6572
|
+
setValue(next);
|
|
6573
|
+
setTouched();
|
|
6574
|
+
};
|
|
6575
|
+
const toggleConcern = (id) => {
|
|
6576
|
+
const selected = safeValue.concerns.includes(id);
|
|
6577
|
+
const nextConcerns = selected ? safeValue.concerns.filter((c) => c !== id) : [...safeValue.concerns, id];
|
|
6578
|
+
const nextSides = { ...safeValue.sides };
|
|
6579
|
+
if (!nextConcerns.includes("knee")) delete nextSides.knee;
|
|
6580
|
+
if (!nextConcerns.includes("shoulder")) delete nextSides.shoulder;
|
|
6581
|
+
if (!nextConcerns.includes("hip")) delete nextSides.hip;
|
|
6582
|
+
update({ ...safeValue, concerns: nextConcerns, sides: nextSides });
|
|
6583
|
+
};
|
|
6584
|
+
const toggleSide = (part, side) => {
|
|
6585
|
+
const current = safeValue.sides?.[part];
|
|
6586
|
+
const nextSides = { ...safeValue.sides };
|
|
6587
|
+
if (current === side) {
|
|
6588
|
+
delete nextSides[part];
|
|
6589
|
+
} else {
|
|
6590
|
+
nextSides[part] = side;
|
|
6591
|
+
}
|
|
6592
|
+
update({ ...safeValue, sides: nextSides });
|
|
6593
|
+
};
|
|
6594
|
+
const setPainScore = (score) => {
|
|
6595
|
+
update({ ...safeValue, painScore: Math.min(10, Math.max(0, Math.round(score))) });
|
|
6596
|
+
};
|
|
6597
|
+
const setPhysicalExam = (key, text) => {
|
|
6598
|
+
update({
|
|
6599
|
+
...safeValue,
|
|
6600
|
+
physicalExam: {
|
|
6601
|
+
...safeValue.physicalExam,
|
|
6602
|
+
[key]: text
|
|
6603
|
+
}
|
|
6604
|
+
});
|
|
6605
|
+
};
|
|
6606
|
+
const showSidePanel = SIDE_PARTS.some((p) => safeValue.concerns.includes(p));
|
|
6607
|
+
if (!fieldDef) return null;
|
|
6608
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `space-y-4 relative ${disabled ? "opacity-60 pointer-events-none" : ""}`, children: [
|
|
6609
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs(Label, { className: "text-sm font-medium", children: [
|
|
6610
|
+
fieldDef.label,
|
|
6611
|
+
fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-1", children: "*" }) : null
|
|
6612
|
+
] }) }),
|
|
6613
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
6614
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold text-muted-foreground", children: "Concern" }),
|
|
6615
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: CONCERNS.map((c) => {
|
|
6616
|
+
const active = safeValue.concerns.includes(c.id);
|
|
6617
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6618
|
+
Button,
|
|
6619
|
+
{
|
|
6620
|
+
type: "button",
|
|
6621
|
+
size: "sm",
|
|
6622
|
+
variant: active ? "default" : "outline",
|
|
6623
|
+
className: "h-6 rounded-full px-3 py-1 text-xs",
|
|
6624
|
+
onClick: () => toggleConcern(c.id),
|
|
6625
|
+
children: c.label
|
|
6626
|
+
},
|
|
6627
|
+
c.id
|
|
6628
|
+
);
|
|
6629
|
+
}) })
|
|
6630
|
+
] }),
|
|
6631
|
+
showSidePanel ? /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 space-y-3 border-dashed", children: [
|
|
6632
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold text-muted-foreground", children: "Side (Left / Right / Both)" }),
|
|
6633
|
+
SIDE_PARTS.map((part) => {
|
|
6634
|
+
if (!safeValue.concerns.includes(part)) return null;
|
|
6635
|
+
const current = safeValue.sides?.[part];
|
|
6636
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
6637
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium capitalize", children: part }),
|
|
6638
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", children: ["left", "right", "both"].map((s) => {
|
|
6639
|
+
const active = current === s;
|
|
6640
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6641
|
+
Button,
|
|
6642
|
+
{
|
|
6643
|
+
type: "button",
|
|
6644
|
+
size: "sm",
|
|
6645
|
+
variant: active ? "default" : "outline",
|
|
6646
|
+
className: "text-[11px] px-2 py-1 h-7",
|
|
6647
|
+
onClick: () => toggleSide(part, s),
|
|
6648
|
+
children: s.charAt(0).toUpperCase() + s.slice(1)
|
|
6649
|
+
},
|
|
6650
|
+
s
|
|
6651
|
+
);
|
|
6652
|
+
}) })
|
|
6653
|
+
] }, part);
|
|
6654
|
+
})
|
|
6655
|
+
] }) : null,
|
|
6656
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
6657
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
6658
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-muted-foreground", children: "Pain score" }),
|
|
6659
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-mono", children: [
|
|
6660
|
+
safeValue.painScore,
|
|
6661
|
+
" / 10"
|
|
6662
|
+
] })
|
|
6663
|
+
] }),
|
|
6664
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6665
|
+
Slider,
|
|
6666
|
+
{
|
|
6667
|
+
min: 0,
|
|
6668
|
+
max: 10,
|
|
6669
|
+
step: 1,
|
|
6670
|
+
value: [safeValue.painScore],
|
|
6671
|
+
onValueChange: (v) => setPainScore(v[0] ?? 0),
|
|
6672
|
+
trackClassName: "!bg-gray-400",
|
|
6673
|
+
thumbClassName: "!bg-white !border-white"
|
|
6674
|
+
}
|
|
6675
|
+
)
|
|
6676
|
+
] }),
|
|
6677
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-3", children: [
|
|
6678
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
6679
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs", children: "Inspection" }),
|
|
6680
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6681
|
+
Textarea,
|
|
6682
|
+
{
|
|
6683
|
+
rows: 4,
|
|
6684
|
+
value: safeValue.physicalExam.inspection,
|
|
6685
|
+
onChange: (e) => setPhysicalExam("inspection", e.target.value),
|
|
6686
|
+
placeholder: "Gait, posture, deformity, swelling, scars...",
|
|
6687
|
+
className: "text-xs"
|
|
6688
|
+
}
|
|
6689
|
+
)
|
|
6690
|
+
] }),
|
|
6691
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
6692
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs", children: "Palpation" }),
|
|
6693
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6694
|
+
Textarea,
|
|
6695
|
+
{
|
|
6696
|
+
rows: 4,
|
|
6697
|
+
value: safeValue.physicalExam.palpation,
|
|
6698
|
+
onChange: (e) => setPhysicalExam("palpation", e.target.value),
|
|
6699
|
+
placeholder: "Tenderness, warmth, crepitus, effusion...",
|
|
6700
|
+
className: "text-xs"
|
|
6701
|
+
}
|
|
6702
|
+
)
|
|
6703
|
+
] }),
|
|
6704
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
6705
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs", children: "Range of motion" }),
|
|
6706
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6707
|
+
Textarea,
|
|
6708
|
+
{
|
|
6709
|
+
rows: 4,
|
|
6710
|
+
value: safeValue.physicalExam.rangeOfMotion,
|
|
6711
|
+
onChange: (e) => setPhysicalExam("rangeOfMotion", e.target.value),
|
|
6712
|
+
placeholder: "Flexion/extension, rotation, abduction/adduction...",
|
|
6713
|
+
className: "text-xs"
|
|
6714
|
+
}
|
|
6715
|
+
)
|
|
6716
|
+
] })
|
|
6717
|
+
] }),
|
|
6718
|
+
showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error }) : null,
|
|
6719
|
+
safeValue.concerns.length > 0 && hasReminders ? panelOpen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6720
|
+
"div",
|
|
6721
|
+
{
|
|
6722
|
+
style: {
|
|
6723
|
+
position: "fixed",
|
|
6724
|
+
top: safeValue.reminders.position?.top ?? 96,
|
|
6725
|
+
right: safeValue.reminders.position?.right ?? 24,
|
|
6726
|
+
zIndex: 40
|
|
6727
|
+
},
|
|
6728
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "w-80 shadow-lg border-primary/30 bg-background/95 backdrop-blur-sm", children: [
|
|
6729
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6730
|
+
"div",
|
|
6731
|
+
{
|
|
6732
|
+
className: "flex items-center justify-between px-3 py-2 border-b cursor-move bg-primary/5",
|
|
6733
|
+
onMouseDown: (e) => {
|
|
6734
|
+
e.preventDefault();
|
|
6735
|
+
draggingRef.current = {
|
|
6736
|
+
startX: e.clientX,
|
|
6737
|
+
startY: e.clientY,
|
|
6738
|
+
startTop: safeValue.reminders.position?.top ?? 96,
|
|
6739
|
+
startRight: safeValue.reminders.position?.right ?? 24
|
|
6740
|
+
};
|
|
6741
|
+
},
|
|
6742
|
+
children: [
|
|
6743
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-primary", children: "Exam reminders" }),
|
|
6744
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6745
|
+
"button",
|
|
6746
|
+
{
|
|
6747
|
+
type: "button",
|
|
6748
|
+
className: "text-[10px] uppercase tracking-wide text-muted-foreground hover:text-destructive",
|
|
6749
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
6750
|
+
onClick: () => setPanelOpen(false),
|
|
6751
|
+
children: "Close"
|
|
6752
|
+
}
|
|
6753
|
+
)
|
|
6754
|
+
]
|
|
6755
|
+
}
|
|
6756
|
+
),
|
|
6757
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 max-h-64 overflow-auto space-y-3", children: reminderSections.map(({ id, label, points }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
6758
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold text-primary mb-1", children: label }),
|
|
6759
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside space-y-1 text-[11px] text-muted-foreground", children: points.map((p) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: p }, p)) })
|
|
6760
|
+
] }, id)) })
|
|
6761
|
+
] })
|
|
6762
|
+
}
|
|
6763
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6764
|
+
"div",
|
|
6765
|
+
{
|
|
6766
|
+
style: {
|
|
6767
|
+
position: "fixed",
|
|
6768
|
+
top: safeValue.reminders.position?.top ?? 96,
|
|
6769
|
+
right: safeValue.reminders.position?.right ?? 24,
|
|
6770
|
+
zIndex: 40
|
|
6771
|
+
},
|
|
6772
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6773
|
+
Button,
|
|
6774
|
+
{
|
|
6775
|
+
type: "button",
|
|
6776
|
+
variant: "outline",
|
|
6777
|
+
size: "sm",
|
|
6778
|
+
className: "rounded-full px-3 py-1 text-xs border-primary/30 bg-background/95 backdrop-blur-sm shadow-md",
|
|
6779
|
+
onClick: () => setPanelOpen(true),
|
|
6780
|
+
children: "Exam reminders"
|
|
6781
|
+
}
|
|
6782
|
+
)
|
|
6783
|
+
}
|
|
6784
|
+
) : null
|
|
6785
|
+
] });
|
|
6786
|
+
};
|
|
6402
6787
|
var FieldRenderer = ({ fieldId }) => {
|
|
6403
6788
|
const { fieldDef, visible } = useField(fieldId);
|
|
6404
6789
|
if (!visible || !fieldDef) {
|
|
@@ -6455,6 +6840,8 @@ var FieldRenderer = ({ fieldId }) => {
|
|
|
6455
6840
|
return /* @__PURE__ */ jsxRuntime.jsx(OphthalmologyWidget, { fieldId });
|
|
6456
6841
|
case "ophthal_diagnosis":
|
|
6457
6842
|
return /* @__PURE__ */ jsxRuntime.jsx(OphthalDiagnosisWidget, { fieldId });
|
|
6843
|
+
case "orthopedic_exam":
|
|
6844
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OrthopedicExamWidget, { fieldId });
|
|
6458
6845
|
case "static_text": {
|
|
6459
6846
|
const def = fieldDef;
|
|
6460
6847
|
const size = def.size ?? "regular";
|
|
@@ -6974,6 +7361,39 @@ var ReadOnlyCheckbox = ({ fieldDef, value }) => {
|
|
|
6974
7361
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem] flex items-center", children: loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 italic", children: "Loading..." }) : displayText })
|
|
6975
7362
|
] });
|
|
6976
7363
|
};
|
|
7364
|
+
function normalizeValue2(value) {
|
|
7365
|
+
if (!value || !Array.isArray(value)) return [];
|
|
7366
|
+
return value.map((item) => {
|
|
7367
|
+
if (item && typeof item === "object" && "specialization" in item) {
|
|
7368
|
+
return {
|
|
7369
|
+
specialization: String(item.specialization),
|
|
7370
|
+
is_urgent: Boolean(item.is_urgent)
|
|
7371
|
+
};
|
|
7372
|
+
}
|
|
7373
|
+
return { specialization: String(item), is_urgent: false };
|
|
7374
|
+
});
|
|
7375
|
+
}
|
|
7376
|
+
var ReadOnlyReferral = ({ fieldDef, value }) => {
|
|
7377
|
+
if (!fieldDef) return null;
|
|
7378
|
+
const items = normalizeValue2(value);
|
|
7379
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
7380
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium text-gray-700", children: fieldDef.label }),
|
|
7381
|
+
items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem]", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 italic", children: "No value" }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1.5", children: items.map((item, i) => {
|
|
7382
|
+
const isUrgent = item.is_urgent;
|
|
7383
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7384
|
+
"span",
|
|
7385
|
+
{
|
|
7386
|
+
className: isUrgent ? "inline-flex items-center gap-1 px-2 py-0.5 bg-red-100 text-red-800 border border-red-300 rounded-full text-xs font-medium" : "inline-flex items-center gap-1 px-2 py-0.5 bg-blue-100 text-blue-800 rounded-full text-xs font-medium",
|
|
7387
|
+
children: [
|
|
7388
|
+
isUrgent && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 bg-red-600 text-white text-[10px] font-bold px-1 py-0.5 rounded", children: "U" }),
|
|
7389
|
+
item.specialization
|
|
7390
|
+
]
|
|
7391
|
+
},
|
|
7392
|
+
i
|
|
7393
|
+
);
|
|
7394
|
+
}) })
|
|
7395
|
+
] });
|
|
7396
|
+
};
|
|
6977
7397
|
var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
6978
7398
|
if (!fieldDef) return null;
|
|
6979
7399
|
switch (fieldDef.type) {
|
|
@@ -7002,6 +7422,8 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
|
7002
7422
|
return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlySignature, { fieldDef, value });
|
|
7003
7423
|
case "editable_table":
|
|
7004
7424
|
return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyTable, { fieldDef, value });
|
|
7425
|
+
case "referral":
|
|
7426
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyReferral, { fieldDef, value });
|
|
7005
7427
|
case "static_text": {
|
|
7006
7428
|
const def = fieldDef;
|
|
7007
7429
|
const size = def.size ?? "regular";
|