formanitor 0.0.31 → 0.0.33
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 +475 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.mjs +472 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -23,6 +23,13 @@ import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
|
23
23
|
import nlp from 'compromise';
|
|
24
24
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
25
25
|
|
|
26
|
+
// src/core/marMedicationOrdersMeta.ts
|
|
27
|
+
var MAR_MEDICATION_ORDERS_META_KEY = "mar_medication_orders";
|
|
28
|
+
function fieldMetaRequestsMarMedicationOrdersButton(meta) {
|
|
29
|
+
if (!meta || typeof meta !== "object") return false;
|
|
30
|
+
return meta[MAR_MEDICATION_ORDERS_META_KEY] === true;
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
// src/core/validate.ts
|
|
27
34
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
28
35
|
function validateField(value, field) {
|
|
@@ -423,7 +430,7 @@ var FormStore = class {
|
|
|
423
430
|
result[field.id] = parts.length > 0 ? parts.join("\n\n") : null;
|
|
424
431
|
return;
|
|
425
432
|
}
|
|
426
|
-
if (field.type === "image_upload" || field.type === "signature") {
|
|
433
|
+
if (field.type === "image_upload" || field.type === "media_upload" || field.type === "signature") {
|
|
427
434
|
const raw = values[field.id];
|
|
428
435
|
if (raw !== void 0 && raw !== null && raw !== "") {
|
|
429
436
|
const key = typeof raw === "string" ? raw : raw.s3_key || raw.value || null;
|
|
@@ -2151,6 +2158,162 @@ var ImageUploadWidget = ({ fieldId }) => {
|
|
|
2151
2158
|
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
2152
2159
|
] });
|
|
2153
2160
|
};
|
|
2161
|
+
function urlLooksLikePdf(url) {
|
|
2162
|
+
return /\.pdf($|\?)/i.test(url) || url.toLowerCase().includes("application/pdf");
|
|
2163
|
+
}
|
|
2164
|
+
function isAcceptedMediaFile(file) {
|
|
2165
|
+
if (file.type.startsWith("image/")) return true;
|
|
2166
|
+
if (file.type === "application/pdf") return true;
|
|
2167
|
+
if (file.name.toLowerCase().endsWith(".pdf")) return true;
|
|
2168
|
+
return false;
|
|
2169
|
+
}
|
|
2170
|
+
var MediaUploadWidget = ({ fieldId }) => {
|
|
2171
|
+
const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
|
|
2172
|
+
const store = useFormStore();
|
|
2173
|
+
const { state } = useForm();
|
|
2174
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
2175
|
+
const [preview, setPreview] = useState(null);
|
|
2176
|
+
const [previewIsPdf, setPreviewIsPdf] = useState(false);
|
|
2177
|
+
const fileInputRef = useRef(null);
|
|
2178
|
+
const pendingPreviewKindRef = useRef(null);
|
|
2179
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
2180
|
+
if (!fieldDef) return null;
|
|
2181
|
+
const uploadHandler = store.getUploadHandler();
|
|
2182
|
+
if (!uploadHandler) {
|
|
2183
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2184
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
2185
|
+
fieldDef.label,
|
|
2186
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
2187
|
+
] }),
|
|
2188
|
+
/* @__PURE__ */ jsx("div", { className: "border-2 border-red-300 rounded-lg p-4 bg-red-50", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600", children: "Upload handler not configured. Please provide an onUpload function in FormProvider config." }) })
|
|
2189
|
+
] });
|
|
2190
|
+
}
|
|
2191
|
+
React15__default.useEffect(() => {
|
|
2192
|
+
if (value && typeof value === "string") {
|
|
2193
|
+
setPreview(value);
|
|
2194
|
+
if (pendingPreviewKindRef.current) {
|
|
2195
|
+
setPreviewIsPdf(pendingPreviewKindRef.current === "pdf");
|
|
2196
|
+
pendingPreviewKindRef.current = null;
|
|
2197
|
+
} else {
|
|
2198
|
+
setPreviewIsPdf(urlLooksLikePdf(value));
|
|
2199
|
+
}
|
|
2200
|
+
} else {
|
|
2201
|
+
setPreview(null);
|
|
2202
|
+
setPreviewIsPdf(false);
|
|
2203
|
+
}
|
|
2204
|
+
}, [value]);
|
|
2205
|
+
const handleFileSelect = async (event) => {
|
|
2206
|
+
const file = event.target.files?.[0];
|
|
2207
|
+
if (!file) return;
|
|
2208
|
+
if (!isAcceptedMediaFile(file)) {
|
|
2209
|
+
alert("Please select an image or PDF file");
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
const maxSize = 10 * 1024 * 1024;
|
|
2213
|
+
if (file.size > maxSize) {
|
|
2214
|
+
alert("File size must be less than 10MB");
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
const isPdf = file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf");
|
|
2218
|
+
setIsUploading(true);
|
|
2219
|
+
setTouched();
|
|
2220
|
+
store.incrementPendingUploads();
|
|
2221
|
+
try {
|
|
2222
|
+
const previewUrl = URL.createObjectURL(file);
|
|
2223
|
+
setPreview(previewUrl);
|
|
2224
|
+
setPreviewIsPdf(isPdf);
|
|
2225
|
+
const s3Key = await uploadHandler(file, file.name);
|
|
2226
|
+
pendingPreviewKindRef.current = isPdf ? "pdf" : "image";
|
|
2227
|
+
setValue(s3Key);
|
|
2228
|
+
} catch (error2) {
|
|
2229
|
+
console.error("Upload failed:", error2);
|
|
2230
|
+
const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
|
|
2231
|
+
alert(errorMessage);
|
|
2232
|
+
setPreview(null);
|
|
2233
|
+
setPreviewIsPdf(false);
|
|
2234
|
+
} finally {
|
|
2235
|
+
setIsUploading(false);
|
|
2236
|
+
store.decrementPendingUploads();
|
|
2237
|
+
}
|
|
2238
|
+
};
|
|
2239
|
+
const handleRemove = () => {
|
|
2240
|
+
pendingPreviewKindRef.current = null;
|
|
2241
|
+
setValue(null);
|
|
2242
|
+
setPreview(null);
|
|
2243
|
+
setPreviewIsPdf(false);
|
|
2244
|
+
if (fileInputRef.current) {
|
|
2245
|
+
fileInputRef.current.value = "";
|
|
2246
|
+
}
|
|
2247
|
+
setTouched();
|
|
2248
|
+
};
|
|
2249
|
+
const handleUploadClick = () => {
|
|
2250
|
+
fileInputRef.current?.click();
|
|
2251
|
+
};
|
|
2252
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2253
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
2254
|
+
fieldDef.label,
|
|
2255
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
2256
|
+
] }),
|
|
2257
|
+
/* @__PURE__ */ jsx("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-4", children: preview ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2258
|
+
previewIsPdf ? /* @__PURE__ */ jsx(
|
|
2259
|
+
"iframe",
|
|
2260
|
+
{
|
|
2261
|
+
src: preview,
|
|
2262
|
+
title: "Uploaded PDF",
|
|
2263
|
+
className: "w-full max-h-48 min-h-36 rounded-lg border border-gray-200 bg-white"
|
|
2264
|
+
}
|
|
2265
|
+
) : /* @__PURE__ */ jsx(
|
|
2266
|
+
"img",
|
|
2267
|
+
{
|
|
2268
|
+
src: preview,
|
|
2269
|
+
alt: "Uploaded image",
|
|
2270
|
+
className: "max-w-full max-h-48 mx-auto rounded-lg"
|
|
2271
|
+
}
|
|
2272
|
+
),
|
|
2273
|
+
/* @__PURE__ */ jsx(
|
|
2274
|
+
Button,
|
|
2275
|
+
{
|
|
2276
|
+
type: "button",
|
|
2277
|
+
variant: "destructive",
|
|
2278
|
+
size: "sm",
|
|
2279
|
+
className: "absolute top-2 right-2",
|
|
2280
|
+
onClick: handleRemove,
|
|
2281
|
+
disabled: disabled || isUploading,
|
|
2282
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
2283
|
+
}
|
|
2284
|
+
)
|
|
2285
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
2286
|
+
/* @__PURE__ */ jsx(Image, { className: "h-12 w-12 mx-auto text-gray-400 mb-4" }),
|
|
2287
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mb-4", children: "Click to upload an image or PDF, or drag and drop" }),
|
|
2288
|
+
/* @__PURE__ */ jsxs(
|
|
2289
|
+
Button,
|
|
2290
|
+
{
|
|
2291
|
+
type: "button",
|
|
2292
|
+
variant: "outline",
|
|
2293
|
+
onClick: handleUploadClick,
|
|
2294
|
+
disabled: disabled || isUploading,
|
|
2295
|
+
children: [
|
|
2296
|
+
/* @__PURE__ */ jsx(Upload, { className: "h-4 w-4 mr-2" }),
|
|
2297
|
+
isUploading ? "Uploading..." : "Choose Image"
|
|
2298
|
+
]
|
|
2299
|
+
}
|
|
2300
|
+
)
|
|
2301
|
+
] }) }),
|
|
2302
|
+
/* @__PURE__ */ jsx(
|
|
2303
|
+
"input",
|
|
2304
|
+
{
|
|
2305
|
+
ref: fileInputRef,
|
|
2306
|
+
type: "file",
|
|
2307
|
+
accept: "image/*,application/pdf",
|
|
2308
|
+
onChange: handleFileSelect,
|
|
2309
|
+
className: "hidden",
|
|
2310
|
+
disabled: disabled || isUploading
|
|
2311
|
+
}
|
|
2312
|
+
),
|
|
2313
|
+
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description }),
|
|
2314
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
2315
|
+
] });
|
|
2316
|
+
};
|
|
2154
2317
|
var distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
2155
2318
|
var smoothPoint = (prev, curr, smoothing = 0.75) => {
|
|
2156
2319
|
if (!prev) return curr;
|
|
@@ -7383,6 +7546,206 @@ var OrthopedicExamWidget = ({ fieldId }) => {
|
|
|
7383
7546
|
) : null
|
|
7384
7547
|
] });
|
|
7385
7548
|
};
|
|
7549
|
+
var MarMedicationOrdersWidget = ({ fieldId }) => {
|
|
7550
|
+
const { fieldDef, value, setTouched, error, disabled, touched } = useField(fieldId);
|
|
7551
|
+
const { state } = useForm();
|
|
7552
|
+
const handlers = useFieldHandlers(fieldId);
|
|
7553
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
7554
|
+
const onOpen = useCallback(async () => {
|
|
7555
|
+
await handlers.onOpenMedicationOrders?.();
|
|
7556
|
+
setTouched();
|
|
7557
|
+
}, [handlers, setTouched]);
|
|
7558
|
+
if (!fieldDef || fieldDef.type !== "textarea") return null;
|
|
7559
|
+
const textDef = fieldDef;
|
|
7560
|
+
const height = textDef.height;
|
|
7561
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
7562
|
+
const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
|
|
7563
|
+
const labelClass = theme?.labelClassName;
|
|
7564
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7565
|
+
fieldDef.label,
|
|
7566
|
+
" ",
|
|
7567
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
7568
|
+
] });
|
|
7569
|
+
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, children: labelContent });
|
|
7570
|
+
const text = typeof value === "string" ? value : value == null ? "" : String(value);
|
|
7571
|
+
const hasHandler = typeof handlers.onOpenMedicationOrders === "function";
|
|
7572
|
+
return /* @__PURE__ */ jsxs("div", { className: wrapperClass, children: [
|
|
7573
|
+
labelEl,
|
|
7574
|
+
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: fieldDef.description }),
|
|
7575
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between sm:gap-3", children: [
|
|
7576
|
+
/* @__PURE__ */ jsx(
|
|
7577
|
+
"div",
|
|
7578
|
+
{
|
|
7579
|
+
id: fieldId,
|
|
7580
|
+
className: cn(
|
|
7581
|
+
"min-h-[80px] flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm whitespace-pre-wrap",
|
|
7582
|
+
showError && "border-red-500",
|
|
7583
|
+
!text && "text-muted-foreground"
|
|
7584
|
+
),
|
|
7585
|
+
style: height != null ? { minHeight: height } : void 0,
|
|
7586
|
+
"aria-readonly": "true",
|
|
7587
|
+
children: text || fieldDef.placeholder || "No medication orders added."
|
|
7588
|
+
}
|
|
7589
|
+
),
|
|
7590
|
+
/* @__PURE__ */ jsx(
|
|
7591
|
+
Button,
|
|
7592
|
+
{
|
|
7593
|
+
type: "button",
|
|
7594
|
+
variant: "default",
|
|
7595
|
+
disabled: disabled || !hasHandler,
|
|
7596
|
+
onClick: onOpen,
|
|
7597
|
+
className: "shrink-0 sm:mt-0",
|
|
7598
|
+
children: "Add medication orders"
|
|
7599
|
+
}
|
|
7600
|
+
)
|
|
7601
|
+
] }),
|
|
7602
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
7603
|
+
] });
|
|
7604
|
+
};
|
|
7605
|
+
function parseFieldValue(value) {
|
|
7606
|
+
if (value == null) return { orders: [], display_lines: [] };
|
|
7607
|
+
if (Array.isArray(value)) {
|
|
7608
|
+
return {
|
|
7609
|
+
orders: value,
|
|
7610
|
+
display_lines: value.map(() => null)
|
|
7611
|
+
};
|
|
7612
|
+
}
|
|
7613
|
+
if (typeof value === "object") {
|
|
7614
|
+
const v = value;
|
|
7615
|
+
const orders = Array.isArray(v.orders) ? v.orders : [];
|
|
7616
|
+
const rawLines = Array.isArray(v.display_lines) ? v.display_lines : Array.isArray(v.displayLines) ? v.displayLines : [];
|
|
7617
|
+
const display_lines = orders.map((_, i) => rawLines[i] ?? null);
|
|
7618
|
+
return { orders, display_lines };
|
|
7619
|
+
}
|
|
7620
|
+
return { orders: [], display_lines: [] };
|
|
7621
|
+
}
|
|
7622
|
+
function normalizePrescription(res) {
|
|
7623
|
+
const pharmacyOrderId = res.pharmacy_order_id ?? void 0;
|
|
7624
|
+
const orders = Array.isArray(res.orders) ? res.orders : [];
|
|
7625
|
+
const linesRaw = Array.isArray(res.display_lines) ? res.display_lines : [];
|
|
7626
|
+
const mapped = orders.filter((o) => o && typeof o.id === "string").map((o) => ({
|
|
7627
|
+
id: o.id,
|
|
7628
|
+
item_id: o.item_id == null ? void 0 : String(o.item_id),
|
|
7629
|
+
item_name: o.item_name ?? void 0,
|
|
7630
|
+
generic_name: o.generic_name ?? void 0,
|
|
7631
|
+
dose: o.dose == null ? void 0 : String(o.dose),
|
|
7632
|
+
route: o.route ?? void 0,
|
|
7633
|
+
frequency: o.frequency ?? void 0,
|
|
7634
|
+
admin_times: Array.isArray(o.admin_times) ? o.admin_times : void 0,
|
|
7635
|
+
meal_sleep_timing: o.meal_sleep_timing ?? void 0,
|
|
7636
|
+
start_date: o.start_date ?? void 0,
|
|
7637
|
+
end_date: o.end_date ?? void 0,
|
|
7638
|
+
order_type: o.order_type ?? void 0,
|
|
7639
|
+
status: o.status ?? void 0,
|
|
7640
|
+
notes: o.notes ?? null,
|
|
7641
|
+
pharmacy_order_id: pharmacyOrderId
|
|
7642
|
+
}));
|
|
7643
|
+
const display_lines = mapped.map((_, i) => linesRaw[i] ?? null);
|
|
7644
|
+
return { orders: mapped, display_lines };
|
|
7645
|
+
}
|
|
7646
|
+
function formatDuration(start, end) {
|
|
7647
|
+
if (!start && !end) return null;
|
|
7648
|
+
if (start && end) return `${start} \u2192 ${end}`;
|
|
7649
|
+
return start ? `Start: ${start}` : `End: ${end}`;
|
|
7650
|
+
}
|
|
7651
|
+
var DischargeMedicationOrdersWidget = ({ fieldId }) => {
|
|
7652
|
+
const { fieldDef, value, setValue, setTouched, error, disabled, touched, visible } = useField(fieldId);
|
|
7653
|
+
const { state } = useForm();
|
|
7654
|
+
const handlers = useFieldHandlers(fieldId);
|
|
7655
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
7656
|
+
const { orders, display_lines } = useMemo(() => parseFieldValue(value), [value]);
|
|
7657
|
+
const onAdd = useCallback(async () => {
|
|
7658
|
+
setTouched();
|
|
7659
|
+
const fn = handlers.onOpenDischargeMedicationOrders;
|
|
7660
|
+
if (!fn) return;
|
|
7661
|
+
const res = await fn();
|
|
7662
|
+
if (!res || typeof res !== "object") return;
|
|
7663
|
+
const normalized = normalizePrescription(res);
|
|
7664
|
+
setValue({
|
|
7665
|
+
orders: normalized.orders,
|
|
7666
|
+
display_lines: normalized.display_lines
|
|
7667
|
+
});
|
|
7668
|
+
}, [handlers.onOpenDischargeMedicationOrders, setTouched, setValue]);
|
|
7669
|
+
const onDelete = useCallback(
|
|
7670
|
+
(id) => {
|
|
7671
|
+
setTouched();
|
|
7672
|
+
const idx = orders.findIndex((o) => o.id === id);
|
|
7673
|
+
if (idx === -1) return;
|
|
7674
|
+
setValue({
|
|
7675
|
+
orders: orders.filter((o) => o.id !== id),
|
|
7676
|
+
display_lines: display_lines.filter((_, i) => i !== idx)
|
|
7677
|
+
});
|
|
7678
|
+
},
|
|
7679
|
+
[orders, display_lines, setTouched, setValue]
|
|
7680
|
+
);
|
|
7681
|
+
if (!visible || !fieldDef) return null;
|
|
7682
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
7683
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7684
|
+
/* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium", children: [
|
|
7685
|
+
fieldDef.label,
|
|
7686
|
+
" ",
|
|
7687
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
7688
|
+
] }),
|
|
7689
|
+
/* @__PURE__ */ jsx(Button, { type: "button", onClick: onAdd, disabled: disabled || !handlers.onOpenDischargeMedicationOrders, children: "Add medicine" })
|
|
7690
|
+
] }),
|
|
7691
|
+
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: fieldDef.description }),
|
|
7692
|
+
orders.length === 0 ? /* @__PURE__ */ jsx(
|
|
7693
|
+
"div",
|
|
7694
|
+
{
|
|
7695
|
+
className: cn(
|
|
7696
|
+
"rounded-md border border-input bg-background px-3 py-3 text-sm text-muted-foreground",
|
|
7697
|
+
showError && "border-red-500"
|
|
7698
|
+
),
|
|
7699
|
+
children: "No medicines added."
|
|
7700
|
+
}
|
|
7701
|
+
) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: orders.map((o, rowIdx) => {
|
|
7702
|
+
const line = display_lines[rowIdx];
|
|
7703
|
+
const duration = formatDuration(o.start_date, o.end_date);
|
|
7704
|
+
const header = typeof line?.name === "string" && line.name.trim() || o.item_name || "Medicine";
|
|
7705
|
+
const sub = o.generic_name ? o.generic_name : null;
|
|
7706
|
+
const line1 = [o.dose && `Dose: ${o.dose}`, o.route && `Route: ${o.route}`].filter(Boolean).join(" \u2022 ");
|
|
7707
|
+
const line2 = [
|
|
7708
|
+
o.frequency && `Freq: ${o.frequency}`,
|
|
7709
|
+
o.meal_sleep_timing && `Meal/Sleep: ${o.meal_sleep_timing}`,
|
|
7710
|
+
o.admin_times?.length ? `Times: ${o.admin_times.join(", ")}` : null
|
|
7711
|
+
].filter(Boolean).join(" \u2022 ");
|
|
7712
|
+
const line3 = [
|
|
7713
|
+
duration ? `Duration: ${duration}` : null,
|
|
7714
|
+
o.order_type ? `Type: ${o.order_type}` : null,
|
|
7715
|
+
o.status ? `Status: ${o.status}` : null
|
|
7716
|
+
].filter(Boolean).join(" \u2022 ");
|
|
7717
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-input bg-background p-3", children: [
|
|
7718
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
7719
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
7720
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-sm truncate", children: header }),
|
|
7721
|
+
sub && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: sub })
|
|
7722
|
+
] }),
|
|
7723
|
+
/* @__PURE__ */ jsx(
|
|
7724
|
+
Button,
|
|
7725
|
+
{
|
|
7726
|
+
type: "button",
|
|
7727
|
+
variant: "ghost",
|
|
7728
|
+
className: "h-8 w-8 p-0 text-destructive",
|
|
7729
|
+
onClick: () => onDelete(o.id),
|
|
7730
|
+
"aria-label": "Delete medicine",
|
|
7731
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
7732
|
+
}
|
|
7733
|
+
)
|
|
7734
|
+
] }),
|
|
7735
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-1 text-xs text-muted-foreground", children: [
|
|
7736
|
+
line1 && /* @__PURE__ */ jsx("div", { children: line1 }),
|
|
7737
|
+
line2 && /* @__PURE__ */ jsx("div", { children: line2 }),
|
|
7738
|
+
line3 && /* @__PURE__ */ jsx("div", { children: line3 }),
|
|
7739
|
+
o.notes && /* @__PURE__ */ jsxs("div", { className: "text-foreground/80", children: [
|
|
7740
|
+
"Notes: ",
|
|
7741
|
+
o.notes
|
|
7742
|
+
] })
|
|
7743
|
+
] })
|
|
7744
|
+
] }, o.id);
|
|
7745
|
+
}) }),
|
|
7746
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
7747
|
+
] });
|
|
7748
|
+
};
|
|
7386
7749
|
var FieldRenderer = ({ fieldId }) => {
|
|
7387
7750
|
const { fieldDef, visible } = useField(fieldId);
|
|
7388
7751
|
if (!visible || !fieldDef) {
|
|
@@ -7396,6 +7759,9 @@ function renderWidget(fieldId, fieldDef) {
|
|
|
7396
7759
|
case "number":
|
|
7397
7760
|
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
7398
7761
|
case "textarea":
|
|
7762
|
+
if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
|
|
7763
|
+
return /* @__PURE__ */ jsx(MarMedicationOrdersWidget, { fieldId });
|
|
7764
|
+
}
|
|
7399
7765
|
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
7400
7766
|
case "richtext":
|
|
7401
7767
|
return /* @__PURE__ */ jsx(RichTextWidget, { fieldId });
|
|
@@ -7415,12 +7781,16 @@ function renderWidget(fieldId, fieldDef) {
|
|
|
7415
7781
|
return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
|
|
7416
7782
|
case "image_upload":
|
|
7417
7783
|
return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
|
|
7784
|
+
case "media_upload":
|
|
7785
|
+
return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
|
|
7418
7786
|
case "signature":
|
|
7419
7787
|
return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
|
|
7420
7788
|
case "editable_table":
|
|
7421
7789
|
return /* @__PURE__ */ jsx(EditableTableWidget, { fieldId });
|
|
7422
7790
|
case "medications":
|
|
7423
7791
|
return /* @__PURE__ */ jsx(AddMedicationWidget, { fieldId });
|
|
7792
|
+
case "discharge_medication_orders":
|
|
7793
|
+
return /* @__PURE__ */ jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
7424
7794
|
case "investigations":
|
|
7425
7795
|
return /* @__PURE__ */ jsx(AddInvestigationWidget, { fieldId });
|
|
7426
7796
|
case "procedures":
|
|
@@ -7822,6 +8192,55 @@ var ReadOnlyImageUpload = ({
|
|
|
7822
8192
|
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description })
|
|
7823
8193
|
] });
|
|
7824
8194
|
};
|
|
8195
|
+
function urlLooksLikePdf2(url) {
|
|
8196
|
+
return /\.pdf($|\?)/i.test(url) || url.toLowerCase().includes("application/pdf");
|
|
8197
|
+
}
|
|
8198
|
+
var ReadOnlyMediaUpload = ({
|
|
8199
|
+
fieldDef,
|
|
8200
|
+
value
|
|
8201
|
+
}) => {
|
|
8202
|
+
const [useIframe, setUseIframe] = useState(false);
|
|
8203
|
+
let url = null;
|
|
8204
|
+
if (typeof value === "string") {
|
|
8205
|
+
url = value;
|
|
8206
|
+
} else if (value && typeof value === "object") {
|
|
8207
|
+
const typed = value;
|
|
8208
|
+
url = typed.presigned_url || typed.value || typed.s3_key || null;
|
|
8209
|
+
}
|
|
8210
|
+
useEffect(() => {
|
|
8211
|
+
setUseIframe(false);
|
|
8212
|
+
}, [url]);
|
|
8213
|
+
const showAsPdf = url && (urlLooksLikePdf2(url) || useIframe);
|
|
8214
|
+
if (!url) {
|
|
8215
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8216
|
+
/* @__PURE__ */ jsx(Label, { children: fieldDef.label }),
|
|
8217
|
+
/* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg p-4 bg-gray-50", children: /* @__PURE__ */ jsxs("div", { className: "text-center py-4", children: [
|
|
8218
|
+
/* @__PURE__ */ jsx(Image, { className: "h-8 w-8 mx-auto text-gray-400 mb-2" }),
|
|
8219
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No file uploaded" })
|
|
8220
|
+
] }) })
|
|
8221
|
+
] });
|
|
8222
|
+
}
|
|
8223
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8224
|
+
/* @__PURE__ */ jsx(Label, { children: fieldDef.label }),
|
|
8225
|
+
/* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg p-4 bg-white", children: showAsPdf ? /* @__PURE__ */ jsx(
|
|
8226
|
+
"iframe",
|
|
8227
|
+
{
|
|
8228
|
+
src: url,
|
|
8229
|
+
title: `${fieldDef.label} PDF`,
|
|
8230
|
+
className: "w-full max-h-48 min-h-36 rounded-lg border border-gray-200 bg-white"
|
|
8231
|
+
}
|
|
8232
|
+
) : /* @__PURE__ */ jsx(
|
|
8233
|
+
"img",
|
|
8234
|
+
{
|
|
8235
|
+
src: url,
|
|
8236
|
+
alt: `${fieldDef.label} upload`,
|
|
8237
|
+
className: "max-w-full max-h-48 mx-auto rounded-lg",
|
|
8238
|
+
onError: () => setUseIframe(true)
|
|
8239
|
+
}
|
|
8240
|
+
) }),
|
|
8241
|
+
fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description })
|
|
8242
|
+
] });
|
|
8243
|
+
};
|
|
7825
8244
|
var ReadOnlySignature = ({
|
|
7826
8245
|
fieldDef,
|
|
7827
8246
|
value
|
|
@@ -7999,6 +8418,53 @@ var ReadOnlyReferral = ({ fieldDef, value }) => {
|
|
|
7999
8418
|
}) })
|
|
8000
8419
|
] });
|
|
8001
8420
|
};
|
|
8421
|
+
function isOrderArray(value) {
|
|
8422
|
+
return Array.isArray(value) && value.every(
|
|
8423
|
+
(v) => v != null && typeof v === "object" && typeof v.id === "string"
|
|
8424
|
+
);
|
|
8425
|
+
}
|
|
8426
|
+
function formatDuration2(start, end) {
|
|
8427
|
+
if (!start && !end) return null;
|
|
8428
|
+
if (start && end) return `${start} \u2192 ${end}`;
|
|
8429
|
+
return start ? `Start: ${start}` : `End: ${end}`;
|
|
8430
|
+
}
|
|
8431
|
+
var ReadOnlyDischargeMedicationOrders = ({ fieldDef, value }) => {
|
|
8432
|
+
const orders = useMemo(() => isOrderArray(value) ? value : [], [value]);
|
|
8433
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8434
|
+
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium text-gray-700", children: fieldDef.label }),
|
|
8435
|
+
orders.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem]", children: /* @__PURE__ */ jsx("span", { className: "text-gray-400 italic", children: "No medicines added" }) }) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: orders.map((o) => {
|
|
8436
|
+
const duration = formatDuration2(o.start_date, o.end_date);
|
|
8437
|
+
const header = o.item_name ?? "Medicine";
|
|
8438
|
+
const sub = o.generic_name ? o.generic_name : null;
|
|
8439
|
+
const line1 = [o.dose && `Dose: ${o.dose}`, o.route && `Route: ${o.route}`].filter(Boolean).join(" \u2022 ");
|
|
8440
|
+
const line2 = [
|
|
8441
|
+
o.frequency && `Freq: ${o.frequency}`,
|
|
8442
|
+
o.meal_sleep_timing && `Meal/Sleep: ${o.meal_sleep_timing}`,
|
|
8443
|
+
o.admin_times?.length ? `Times: ${o.admin_times.join(", ")}` : null
|
|
8444
|
+
].filter(Boolean).join(" \u2022 ");
|
|
8445
|
+
const line3 = [
|
|
8446
|
+
duration ? `Duration: ${duration}` : null,
|
|
8447
|
+
o.order_type ? `Type: ${o.order_type}` : null,
|
|
8448
|
+
o.status ? `Status: ${o.status}` : null
|
|
8449
|
+
].filter(Boolean).join(" \u2022 ");
|
|
8450
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-gray-200 bg-gray-50 p-3", children: [
|
|
8451
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
8452
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-sm truncate text-gray-900", children: header }),
|
|
8453
|
+
sub && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 mt-0.5 truncate", children: sub })
|
|
8454
|
+
] }),
|
|
8455
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-1 text-xs text-gray-600", children: [
|
|
8456
|
+
line1 && /* @__PURE__ */ jsx("div", { children: line1 }),
|
|
8457
|
+
line2 && /* @__PURE__ */ jsx("div", { children: line2 }),
|
|
8458
|
+
line3 && /* @__PURE__ */ jsx("div", { children: line3 }),
|
|
8459
|
+
o.notes && /* @__PURE__ */ jsxs("div", { className: "text-gray-800/90", children: [
|
|
8460
|
+
"Notes: ",
|
|
8461
|
+
o.notes
|
|
8462
|
+
] })
|
|
8463
|
+
] })
|
|
8464
|
+
] }, o.id);
|
|
8465
|
+
}) })
|
|
8466
|
+
] });
|
|
8467
|
+
};
|
|
8002
8468
|
var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
8003
8469
|
if (!fieldDef) return null;
|
|
8004
8470
|
switch (fieldDef.type) {
|
|
@@ -8023,12 +8489,16 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
|
8023
8489
|
return /* @__PURE__ */ jsx(ReadOnlyRepeatable, { fieldDef, value });
|
|
8024
8490
|
case "image_upload":
|
|
8025
8491
|
return /* @__PURE__ */ jsx(ReadOnlyImageUpload, { fieldDef, value });
|
|
8492
|
+
case "media_upload":
|
|
8493
|
+
return /* @__PURE__ */ jsx(ReadOnlyMediaUpload, { fieldDef, value });
|
|
8026
8494
|
case "signature":
|
|
8027
8495
|
return /* @__PURE__ */ jsx(ReadOnlySignature, { fieldDef, value });
|
|
8028
8496
|
case "editable_table":
|
|
8029
8497
|
return /* @__PURE__ */ jsx(ReadOnlyTable, { fieldDef, value });
|
|
8030
8498
|
case "referral":
|
|
8031
8499
|
return /* @__PURE__ */ jsx(ReadOnlyReferral, { fieldDef, value });
|
|
8500
|
+
case "discharge_medication_orders":
|
|
8501
|
+
return /* @__PURE__ */ jsx(ReadOnlyDischargeMedicationOrders, { fieldDef, value });
|
|
8032
8502
|
case "static_text": {
|
|
8033
8503
|
const def = fieldDef;
|
|
8034
8504
|
const size = def.size ?? "regular";
|
|
@@ -8230,6 +8700,6 @@ function createUploadHandler(options) {
|
|
|
8230
8700
|
};
|
|
8231
8701
|
}
|
|
8232
8702
|
|
|
8233
|
-
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
|
8703
|
+
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MAR_MEDICATION_ORDERS_META_KEY, MediaUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, fieldMetaRequestsMarMedicationOrdersButton, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
|
|
8234
8704
|
//# sourceMappingURL=index.mjs.map
|
|
8235
8705
|
//# sourceMappingURL=index.mjs.map
|