formanitor 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/dist/index.cjs +1521 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -2
- package/dist/index.d.ts +38 -2
- package/dist/index.mjs +1521 -165
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -62,6 +62,15 @@ function validateField(value, field) {
|
|
|
62
62
|
return `Must be at most ${rules.max}`;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
+
if (field.type === "slider") {
|
|
66
|
+
const num = Number(value);
|
|
67
|
+
if (isNaN(num)) return "Must be a valid number";
|
|
68
|
+
const s = field;
|
|
69
|
+
const min = s.min ?? 0;
|
|
70
|
+
const max = s.max ?? 10;
|
|
71
|
+
if (num < min) return `Must be at least ${min}`;
|
|
72
|
+
if (num > max) return `Must be at most ${max}`;
|
|
73
|
+
}
|
|
65
74
|
if (typeof value === "string") {
|
|
66
75
|
if (rules.minLength !== void 0 && value.length < rules.minLength) {
|
|
67
76
|
return `Must be at least ${rules.minLength} characters`;
|
|
@@ -200,6 +209,227 @@ function applyPrefill(currentValues, fields, prefilledData = {}) {
|
|
|
200
209
|
return newValues;
|
|
201
210
|
}
|
|
202
211
|
|
|
212
|
+
// src/core/generalSurgeryPathway.ts
|
|
213
|
+
var defaultGeneralSurgerySmartHistory = () => ({
|
|
214
|
+
pain: {
|
|
215
|
+
site: "",
|
|
216
|
+
onset: "",
|
|
217
|
+
character: "",
|
|
218
|
+
radiation: "",
|
|
219
|
+
associated: "",
|
|
220
|
+
timing: "",
|
|
221
|
+
exacerbating: "",
|
|
222
|
+
severity: 0
|
|
223
|
+
},
|
|
224
|
+
swelling: { duration: "", sizeProgression: "", painfulPainless: "", checks: [] },
|
|
225
|
+
gi: { appetite: "", weightLoss: "", bowelHabits: "", checks: [] },
|
|
226
|
+
breast: { lumpDuration: "", nippleDischarge: "", checks: [] },
|
|
227
|
+
ano: { checks: [] },
|
|
228
|
+
thyroid: { swellingDuration: "", checks: [] },
|
|
229
|
+
systemic: ""
|
|
230
|
+
});
|
|
231
|
+
var defaultGeneralSurgeryExamination = () => ({
|
|
232
|
+
general: [],
|
|
233
|
+
regions: [],
|
|
234
|
+
abdomen: {
|
|
235
|
+
inspection: [],
|
|
236
|
+
palpation: [],
|
|
237
|
+
percussion: [],
|
|
238
|
+
massNotes: "",
|
|
239
|
+
bowelSounds: "none"
|
|
240
|
+
},
|
|
241
|
+
hernia: { site: "", reducible: false, coughImpulse: false, tenderness: false },
|
|
242
|
+
breast: { lumpSizeCm: "", mobile: false, skinInvolvement: false, axillaryNodes: false },
|
|
243
|
+
thyroid: { size: "", mobileDeglutition: false, nodules: false, cervicalNodes: false },
|
|
244
|
+
anorectal: { inspection: "", dreDone: false, proctoscopyDone: false, notes: "" },
|
|
245
|
+
limb: { dilatedVeins: false, ulcer: false, oedema: false }
|
|
246
|
+
});
|
|
247
|
+
var ALL_GS_CONDITIONS = [
|
|
248
|
+
"hernia",
|
|
249
|
+
"appendicitis",
|
|
250
|
+
"gallbladder",
|
|
251
|
+
"breast",
|
|
252
|
+
"thyroid",
|
|
253
|
+
"piles",
|
|
254
|
+
"varicose",
|
|
255
|
+
"ulcer"
|
|
256
|
+
];
|
|
257
|
+
var defaultGeneralSurgeryGrading = () => ({
|
|
258
|
+
hernia: 0,
|
|
259
|
+
appendicitis: 0,
|
|
260
|
+
gallbladder: 0,
|
|
261
|
+
breast: 0,
|
|
262
|
+
thyroid: 0,
|
|
263
|
+
piles: 0,
|
|
264
|
+
varicose: 0,
|
|
265
|
+
ulcer: 0
|
|
266
|
+
});
|
|
267
|
+
var GS_CONDITION_TRIGGERS = {
|
|
268
|
+
hernia: { regions: ["hernia", "abdomen"], chips: ["swelling_lump", "obstruction"] },
|
|
269
|
+
appendicitis: { regions: ["abdomen"], chips: ["pain", "obstruction"] },
|
|
270
|
+
gallbladder: { regions: ["abdomen"], chips: ["pain"] },
|
|
271
|
+
breast: { regions: ["breast"], chips: ["breast", "swelling_lump"] },
|
|
272
|
+
thyroid: { regions: ["thyroid"], chips: ["thyroid", "swelling_lump"] },
|
|
273
|
+
piles: { regions: ["anorectal"], chips: ["anorectal", "bleeding"] },
|
|
274
|
+
varicose: { regions: ["limb"], chips: ["swelling_lump"] },
|
|
275
|
+
ulcer: { regions: ["limb", "anorectal"], chips: ["ulcer_wound", "discharge"] }
|
|
276
|
+
};
|
|
277
|
+
var GS_CONDITION_LABELS = {
|
|
278
|
+
hernia: "Hernia",
|
|
279
|
+
appendicitis: "Appendicitis",
|
|
280
|
+
gallbladder: "Gallbladder disease",
|
|
281
|
+
breast: "Breast lump (BIRADS)",
|
|
282
|
+
thyroid: "Thyroid nodule (TIRADS)",
|
|
283
|
+
piles: "Haemorrhoids",
|
|
284
|
+
varicose: "Varicose veins (CEAP)",
|
|
285
|
+
ulcer: "Ulcer / wound"
|
|
286
|
+
};
|
|
287
|
+
var GS_GRADE_DESCRIPTIONS = {
|
|
288
|
+
hernia: ["\u2014", "Small reducible", "Large reducible", "Irreducible", "Obstructed", "Strangulated"],
|
|
289
|
+
appendicitis: ["\u2014", "Mild (clinical)", "Confirmed (USG/CT)", "Complicated (mass)", "Abscess", "Perforation"],
|
|
290
|
+
gallbladder: ["\u2014", "Asymptomatic stones", "Symptomatic", "Acute cholecystitis", "Complicated (CBD stone)", "Perforation/empyema"],
|
|
291
|
+
breast: ["\u2014", "BIRADS 1 \u2014 Negative", "BIRADS 2 \u2014 Benign", "BIRADS 3 \u2014 Probably benign", "BIRADS 4 \u2014 Suspicious", "BIRADS 5 \u2014 Malignant"],
|
|
292
|
+
thyroid: ["\u2014", "TIRADS 1 \u2014 Normal", "TIRADS 2 \u2014 Benign", "TIRADS 3 \u2014 Indeterminate", "TIRADS 4 \u2014 Suspicious", "TIRADS 5 \u2014 Highly suspicious"],
|
|
293
|
+
piles: ["\u2014", "Grade 1", "Grade 2", "Grade 3", "Grade 4", "Grade 5"],
|
|
294
|
+
varicose: ["\u2014", "C1 telangiectasia", "C2 varicose", "C3 oedema", "C4 skin changes", "C5-C6 ulcer"],
|
|
295
|
+
ulcer: ["\u2014", "Superficial", "Deep", "Infected", "Necrotic", "Gangrene"]
|
|
296
|
+
};
|
|
297
|
+
function normalizeGeneralSurgerySmartHistory(raw) {
|
|
298
|
+
const d = defaultGeneralSurgerySmartHistory();
|
|
299
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
|
|
300
|
+
const v = raw;
|
|
301
|
+
const painIn = v.pain && typeof v.pain === "object" ? v.pain : {};
|
|
302
|
+
const sev = Number(painIn.severity);
|
|
303
|
+
const pain = {
|
|
304
|
+
...d.pain,
|
|
305
|
+
...painIn,
|
|
306
|
+
severity: Number.isFinite(sev) ? Math.min(10, Math.max(0, Math.round(sev))) : d.pain.severity
|
|
307
|
+
};
|
|
308
|
+
const str2 = (x) => typeof x === "string" ? x : "";
|
|
309
|
+
const strArr = (x) => Array.isArray(x) ? x.filter((i) => typeof i === "string") : [];
|
|
310
|
+
const swell = v.swelling && typeof v.swelling === "object" ? v.swelling : {};
|
|
311
|
+
const gi = v.gi && typeof v.gi === "object" ? v.gi : {};
|
|
312
|
+
const breast = v.breast && typeof v.breast === "object" ? v.breast : {};
|
|
313
|
+
const ano = v.ano && typeof v.ano === "object" ? v.ano : {};
|
|
314
|
+
const thy = v.thyroid && typeof v.thyroid === "object" ? v.thyroid : {};
|
|
315
|
+
return {
|
|
316
|
+
pain,
|
|
317
|
+
swelling: {
|
|
318
|
+
duration: str2(swell.duration),
|
|
319
|
+
sizeProgression: str2(swell.sizeProgression),
|
|
320
|
+
painfulPainless: str2(swell.painfulPainless),
|
|
321
|
+
checks: strArr(swell.checks)
|
|
322
|
+
},
|
|
323
|
+
gi: {
|
|
324
|
+
appetite: str2(gi.appetite),
|
|
325
|
+
weightLoss: str2(gi.weightLoss),
|
|
326
|
+
bowelHabits: str2(gi.bowelHabits),
|
|
327
|
+
checks: strArr(gi.checks)
|
|
328
|
+
},
|
|
329
|
+
breast: {
|
|
330
|
+
lumpDuration: str2(breast.lumpDuration),
|
|
331
|
+
nippleDischarge: str2(breast.nippleDischarge),
|
|
332
|
+
checks: strArr(breast.checks)
|
|
333
|
+
},
|
|
334
|
+
ano: { checks: strArr(ano.checks) },
|
|
335
|
+
thyroid: {
|
|
336
|
+
swellingDuration: str2(thy.swellingDuration),
|
|
337
|
+
checks: strArr(thy.checks)
|
|
338
|
+
},
|
|
339
|
+
systemic: typeof v.systemic === "string" ? v.systemic : d.systemic
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
function normalizeGeneralSurgeryExamination(raw) {
|
|
343
|
+
const d = defaultGeneralSurgeryExamination();
|
|
344
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
|
|
345
|
+
const v = raw;
|
|
346
|
+
const strArr = (x) => Array.isArray(x) ? x.filter((i) => typeof i === "string") : [];
|
|
347
|
+
const ab = v.abdomen && typeof v.abdomen === "object" ? v.abdomen : {};
|
|
348
|
+
const bowel = ab.bowelSounds;
|
|
349
|
+
const bowels = bowel === "normal" || bowel === "up" || bowel === "down" || bowel === "absent" ? bowel : "none";
|
|
350
|
+
const hb = v.hernia && typeof v.hernia === "object" ? v.hernia : {};
|
|
351
|
+
const br = v.breast && typeof v.breast === "object" ? v.breast : {};
|
|
352
|
+
const th = v.thyroid && typeof v.thyroid === "object" ? v.thyroid : {};
|
|
353
|
+
const ar = v.anorectal && typeof v.anorectal === "object" ? v.anorectal : {};
|
|
354
|
+
const lm = v.limb && typeof v.limb === "object" ? v.limb : {};
|
|
355
|
+
const bool = (x) => x === true;
|
|
356
|
+
return {
|
|
357
|
+
general: strArr(v.general),
|
|
358
|
+
regions: strArr(v.regions),
|
|
359
|
+
abdomen: {
|
|
360
|
+
inspection: strArr(ab.inspection),
|
|
361
|
+
palpation: strArr(ab.palpation),
|
|
362
|
+
percussion: strArr(ab.percussion),
|
|
363
|
+
massNotes: typeof ab.massNotes === "string" ? ab.massNotes : d.abdomen.massNotes,
|
|
364
|
+
bowelSounds: bowels
|
|
365
|
+
},
|
|
366
|
+
hernia: {
|
|
367
|
+
site: typeof hb.site === "string" ? hb.site : "",
|
|
368
|
+
reducible: bool(hb.reducible),
|
|
369
|
+
coughImpulse: bool(hb.coughImpulse),
|
|
370
|
+
tenderness: bool(hb.tenderness)
|
|
371
|
+
},
|
|
372
|
+
breast: {
|
|
373
|
+
lumpSizeCm: typeof br.lumpSizeCm === "string" ? br.lumpSizeCm : "",
|
|
374
|
+
mobile: bool(br.mobile),
|
|
375
|
+
skinInvolvement: bool(br.skinInvolvement),
|
|
376
|
+
axillaryNodes: bool(br.axillaryNodes)
|
|
377
|
+
},
|
|
378
|
+
thyroid: {
|
|
379
|
+
size: typeof th.size === "string" ? th.size : "",
|
|
380
|
+
mobileDeglutition: bool(th.mobileDeglutition),
|
|
381
|
+
nodules: bool(th.nodules),
|
|
382
|
+
cervicalNodes: bool(th.cervicalNodes)
|
|
383
|
+
},
|
|
384
|
+
anorectal: {
|
|
385
|
+
inspection: typeof ar.inspection === "string" ? ar.inspection : "",
|
|
386
|
+
dreDone: bool(ar.dreDone),
|
|
387
|
+
proctoscopyDone: bool(ar.proctoscopyDone),
|
|
388
|
+
notes: typeof ar.notes === "string" ? ar.notes : ""
|
|
389
|
+
},
|
|
390
|
+
limb: {
|
|
391
|
+
dilatedVeins: bool(lm.dilatedVeins),
|
|
392
|
+
ulcer: bool(lm.ulcer),
|
|
393
|
+
oedema: bool(lm.oedema)
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function normalizeGeneralSurgeryGrading(raw) {
|
|
398
|
+
const d = defaultGeneralSurgeryGrading();
|
|
399
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
|
|
400
|
+
const v = raw;
|
|
401
|
+
const out = { ...d };
|
|
402
|
+
for (const k of ALL_GS_CONDITIONS) {
|
|
403
|
+
const n = Number(v[k]);
|
|
404
|
+
if (Number.isFinite(n) && n >= 0 && n <= 5) out[k] = Math.round(n);
|
|
405
|
+
}
|
|
406
|
+
return out;
|
|
407
|
+
}
|
|
408
|
+
function gsGradingRowVisible(cond, chips, regions, grade) {
|
|
409
|
+
if (grade > 0) return true;
|
|
410
|
+
const t = GS_CONDITION_TRIGGERS[cond];
|
|
411
|
+
if (t.chips.some((c) => chips.includes(c))) return true;
|
|
412
|
+
if (t.regions.some((r) => regions.includes(r))) return true;
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/core/painScaleFlags.ts
|
|
417
|
+
function normalizePainScaleFlags(raw, bounds) {
|
|
418
|
+
const min = bounds?.min ?? 0;
|
|
419
|
+
const max = bounds?.max ?? 10;
|
|
420
|
+
let pain = min;
|
|
421
|
+
let flags = [];
|
|
422
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
423
|
+
const o = raw;
|
|
424
|
+
const p = Number(o.pain);
|
|
425
|
+
if (Number.isFinite(p)) pain = Math.min(max, Math.max(min, p));
|
|
426
|
+
if (Array.isArray(o.flags)) {
|
|
427
|
+
flags = o.flags.filter((x) => typeof x === "string");
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return { pain, flags };
|
|
431
|
+
}
|
|
432
|
+
|
|
203
433
|
// src/core/store.ts
|
|
204
434
|
var FormStore = class {
|
|
205
435
|
state;
|
|
@@ -286,7 +516,22 @@ var FormStore = class {
|
|
|
286
516
|
else if (field.type === "surgical_risk_flags")
|
|
287
517
|
values[field.id] = { OD: [], OS: [] };
|
|
288
518
|
else if (field.type === "toggle") values[field.id] = false;
|
|
289
|
-
else
|
|
519
|
+
else if (field.type === "slider") {
|
|
520
|
+
const s = field;
|
|
521
|
+
values[field.id] = s.defaultValue ?? s.min ?? 0;
|
|
522
|
+
} else if (field.type === "general_surgery_smart_history") {
|
|
523
|
+
values[field.id] = field.defaultValue ?? defaultGeneralSurgerySmartHistory();
|
|
524
|
+
} else if (field.type === "general_surgery_examination") {
|
|
525
|
+
values[field.id] = field.defaultValue ?? defaultGeneralSurgeryExamination();
|
|
526
|
+
} else if (field.type === "general_surgery_grading") {
|
|
527
|
+
values[field.id] = field.defaultValue ?? defaultGeneralSurgeryGrading();
|
|
528
|
+
} else if (field.type === "pain_scale_flags") {
|
|
529
|
+
const f = field;
|
|
530
|
+
values[field.id] = normalizePainScaleFlags(
|
|
531
|
+
f.defaultValue ?? { pain: f.min ?? 0, flags: [] },
|
|
532
|
+
{ min: f.min, max: f.max }
|
|
533
|
+
);
|
|
534
|
+
} else values[field.id] = null;
|
|
290
535
|
}
|
|
291
536
|
});
|
|
292
537
|
this.state.values = values;
|
|
@@ -1006,7 +1251,8 @@ var TextWidget = ({ fieldId }) => {
|
|
|
1006
1251
|
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
1007
1252
|
] });
|
|
1008
1253
|
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, children: labelContent });
|
|
1009
|
-
|
|
1254
|
+
const placeholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : void 0;
|
|
1255
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(wrapperClass, isTextarea && "flex h-full min-h-0 flex-col"), children: [
|
|
1010
1256
|
hasVoice ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1011
1257
|
labelEl,
|
|
1012
1258
|
/* @__PURE__ */ jsx(VoiceMicButton, { fieldId, onTranscriptReady: setValue })
|
|
@@ -1020,7 +1266,8 @@ var TextWidget = ({ fieldId }) => {
|
|
|
1020
1266
|
onBlur: setTouched,
|
|
1021
1267
|
disabled,
|
|
1022
1268
|
type: fieldDef.type === "number" ? "number" : "text",
|
|
1023
|
-
className: inputClass,
|
|
1269
|
+
className: cn(inputClass, isTextarea && height == null && "min-h-[80px] flex-1"),
|
|
1270
|
+
placeholder,
|
|
1024
1271
|
...isTextarea && { height }
|
|
1025
1272
|
}
|
|
1026
1273
|
),
|
|
@@ -1496,6 +1743,8 @@ var SelectWidget = ({ fieldId }) => {
|
|
|
1496
1743
|
}
|
|
1497
1744
|
}, [fieldDef]);
|
|
1498
1745
|
if (!fieldDef) return null;
|
|
1746
|
+
const schemaPlaceholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : void 0;
|
|
1747
|
+
const selectPlaceholder = loading ? "Loading..." : schemaPlaceholder ?? "Select...";
|
|
1499
1748
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1500
1749
|
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
1501
1750
|
fieldDef.label,
|
|
@@ -1513,7 +1762,7 @@ var SelectWidget = ({ fieldId }) => {
|
|
|
1513
1762
|
setTouched();
|
|
1514
1763
|
},
|
|
1515
1764
|
children: [
|
|
1516
|
-
/* @__PURE__ */ jsx(SelectTrigger, { id: fieldId, className: showError ? "border-red-500" : "", children: /* @__PURE__ */ jsx(SelectValue, { placeholder:
|
|
1765
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id: fieldId, className: showError ? "border-red-500" : "", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: selectPlaceholder }) }),
|
|
1517
1766
|
/* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: String(opt.value), children: opt.label }, String(opt.value))) })
|
|
1518
1767
|
]
|
|
1519
1768
|
}
|
|
@@ -8034,6 +8283,21 @@ function parallelChipArraysEqual(a, b) {
|
|
|
8034
8283
|
function isSuggestionField(type) {
|
|
8035
8284
|
return type === "suggestion_textarea" || type === "complaint_chips";
|
|
8036
8285
|
}
|
|
8286
|
+
function EmbeddedSchemaField({ fieldId }) {
|
|
8287
|
+
const store = useFormStore();
|
|
8288
|
+
const fieldDef = store.getFieldDef(fieldId);
|
|
8289
|
+
if (!fieldDef) return null;
|
|
8290
|
+
switch (fieldDef.type) {
|
|
8291
|
+
case "text":
|
|
8292
|
+
case "number":
|
|
8293
|
+
case "textarea":
|
|
8294
|
+
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
8295
|
+
case "select":
|
|
8296
|
+
return /* @__PURE__ */ jsx(SelectWidget, { fieldId });
|
|
8297
|
+
default:
|
|
8298
|
+
return null;
|
|
8299
|
+
}
|
|
8300
|
+
}
|
|
8037
8301
|
var SuggestionTextareaWidget = ({ fieldId }) => {
|
|
8038
8302
|
const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
|
|
8039
8303
|
const { state } = useForm();
|
|
@@ -8045,6 +8309,10 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
|
|
|
8045
8309
|
const def = fieldDef && isSuggestionField(fieldDef.type) ? fieldDef : void 0;
|
|
8046
8310
|
const textValue = value == null || typeof value === "string" ? value || "" : String(value);
|
|
8047
8311
|
const parallelChipFieldId = def?.meta && typeof def.meta.parallelChipFieldId === "string" ? def.meta.parallelChipFieldId.trim() : void 0;
|
|
8312
|
+
const embeddedFieldIds = useMemo(() => {
|
|
8313
|
+
const raw = def?.meta && Array.isArray(def.meta.embeddedFieldIds) ? def.meta.embeddedFieldIds : [];
|
|
8314
|
+
return raw.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim()).filter((id) => store.getFieldDef(id));
|
|
8315
|
+
}, [def?.meta, store]);
|
|
8048
8316
|
useEffect(() => {
|
|
8049
8317
|
if (!def) {
|
|
8050
8318
|
setOptions([]);
|
|
@@ -8089,19 +8357,26 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
|
|
|
8089
8357
|
setValue(toggleSuggestionTokenInText(textValue, String(optValue), appendSeparator));
|
|
8090
8358
|
};
|
|
8091
8359
|
const hasSuggestions = options.length > 0;
|
|
8360
|
+
const hasEmbedded = embeddedFieldIds.length > 0;
|
|
8361
|
+
const hasShell = hasSuggestions || hasEmbedded;
|
|
8092
8362
|
const isHighlightLabel = def.theme === "highlight-label";
|
|
8093
8363
|
const suggestionShellClass = cn(
|
|
8094
8364
|
"flex min-w-0 flex-col overflow-hidden",
|
|
8095
|
-
|
|
8365
|
+
hasShell && (isHighlightLabel ? "-mt-1 rounded-b-md border-[#D0D0D0] bg-white" : "rounded-md border border-input bg-background")
|
|
8096
8366
|
);
|
|
8097
8367
|
const chipsRowClass = cn(
|
|
8098
8368
|
"flex flex-wrap gap-2 px-3 pb-2 pt-3",
|
|
8099
8369
|
hasSuggestions && (isHighlightLabel ? "" : "border-b border-input/70"),
|
|
8100
8370
|
disabled && "pointer-events-none opacity-50"
|
|
8101
8371
|
);
|
|
8372
|
+
const embeddedRowClass = cn(
|
|
8373
|
+
"grid gap-3 px-3 sm:grid-cols-3",
|
|
8374
|
+
hasEmbedded && (hasSuggestions ? cn("py-2", isHighlightLabel && "border-t border-input/70") : "border-b border-input/70 py-3"),
|
|
8375
|
+
disabled && "pointer-events-none opacity-50"
|
|
8376
|
+
);
|
|
8102
8377
|
const textareaShellClass = cn(
|
|
8103
8378
|
inputClass,
|
|
8104
|
-
|
|
8379
|
+
hasShell && cn(
|
|
8105
8380
|
"mt-0 rounded-t-none rounded-b-md border-0 shadow-none focus-visible:ring-offset-0",
|
|
8106
8381
|
isHighlightLabel ? "border-t-0" : "min-h-[80px]"
|
|
8107
8382
|
)
|
|
@@ -8128,8 +8403,9 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
|
|
|
8128
8403
|
/* @__PURE__ */ jsx(VoiceMicButton, { fieldId, onTranscriptReady: setValue })
|
|
8129
8404
|
] }) : labelEl,
|
|
8130
8405
|
def.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: def.description }),
|
|
8131
|
-
|
|
8132
|
-
/* @__PURE__ */ jsx("div", { className: chipsRowClass, role: "group", "aria-label": suggestionsAria, children: suggestionButtons }),
|
|
8406
|
+
hasShell ? /* @__PURE__ */ jsxs("div", { className: suggestionShellClass, children: [
|
|
8407
|
+
hasSuggestions && /* @__PURE__ */ jsx("div", { className: chipsRowClass, role: "group", "aria-label": suggestionsAria, children: suggestionButtons }),
|
|
8408
|
+
hasEmbedded && /* @__PURE__ */ jsx("div", { className: embeddedRowClass, children: embeddedFieldIds.map((id) => /* @__PURE__ */ jsx(EmbeddedSchemaField, { fieldId: id }, id)) }),
|
|
8133
8409
|
/* @__PURE__ */ jsx(
|
|
8134
8410
|
Textarea,
|
|
8135
8411
|
{
|
|
@@ -8909,161 +9185,1159 @@ var SurgicalRiskFlagsWidget = ({ fieldId }) => {
|
|
|
8909
9185
|
}
|
|
8910
9186
|
);
|
|
8911
9187
|
};
|
|
8912
|
-
var
|
|
8913
|
-
const { fieldDef,
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
case "multiselect":
|
|
8942
|
-
return /* @__PURE__ */ jsx(MultiSelectWidget, { fieldId });
|
|
8943
|
-
case "repeatable":
|
|
8944
|
-
return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
|
|
8945
|
-
case "image_upload":
|
|
8946
|
-
return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
|
|
8947
|
-
case "media_upload":
|
|
8948
|
-
return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
|
|
8949
|
-
case "signature":
|
|
8950
|
-
return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
|
|
8951
|
-
case "editable_table":
|
|
8952
|
-
return /* @__PURE__ */ jsx(EditableTableWidget, { fieldId });
|
|
8953
|
-
case "medications":
|
|
8954
|
-
return /* @__PURE__ */ jsx(AddMedicationWidget, { fieldId });
|
|
8955
|
-
case "discharge_medication_orders":
|
|
8956
|
-
return /* @__PURE__ */ jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
8957
|
-
case "investigations":
|
|
8958
|
-
return /* @__PURE__ */ jsx(AddInvestigationWidget, { fieldId });
|
|
8959
|
-
case "procedures":
|
|
8960
|
-
return /* @__PURE__ */ jsx(AddProcedureWidget, { fieldId });
|
|
8961
|
-
case "differential_diagnosis":
|
|
8962
|
-
return /* @__PURE__ */ jsx(DifferentialDiagnosisWidget, { fieldId });
|
|
8963
|
-
case "vitals":
|
|
8964
|
-
return /* @__PURE__ */ jsx(VitalsWidget, { fieldId });
|
|
8965
|
-
case "hidden_vitals":
|
|
8966
|
-
return /* @__PURE__ */ jsx(HiddenVitalsWidget, { fieldId });
|
|
8967
|
-
case "referral":
|
|
8968
|
-
return /* @__PURE__ */ jsx(ReferralWidget, { fieldId });
|
|
8969
|
-
case "followup":
|
|
8970
|
-
return /* @__PURE__ */ jsx(FollowupWidget, { fieldId });
|
|
8971
|
-
case "smart_textarea":
|
|
8972
|
-
return /* @__PURE__ */ jsx(SmartTextareaWidget, { fieldId });
|
|
8973
|
-
case "diagnosis_textarea":
|
|
8974
|
-
return /* @__PURE__ */ jsx(DiagnosisTextareaWidget, { fieldId });
|
|
8975
|
-
case "obstetric_history":
|
|
8976
|
-
return /* @__PURE__ */ jsx(ObstetricHistoryWidget, { fieldId });
|
|
8977
|
-
case "eye_prescription":
|
|
8978
|
-
return /* @__PURE__ */ jsx(OphthalmologyWidget, { fieldId });
|
|
8979
|
-
case "ophthal_diagnosis":
|
|
8980
|
-
return /* @__PURE__ */ jsx(OphthalDiagnosisWidget, { fieldId });
|
|
8981
|
-
case "orthopedic_exam":
|
|
8982
|
-
return /* @__PURE__ */ jsx(OrthopedicExamWidget, { fieldId });
|
|
8983
|
-
case "toggle": {
|
|
8984
|
-
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
8985
|
-
const store = useFormStore();
|
|
8986
|
-
const excludes = fieldDef.excludes ?? [];
|
|
8987
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
8988
|
-
/* @__PURE__ */ jsx(
|
|
8989
|
-
Switch,
|
|
8990
|
-
{
|
|
8991
|
-
checked: value === true,
|
|
8992
|
-
disabled,
|
|
8993
|
-
onCheckedChange: (checked) => {
|
|
8994
|
-
setValue(checked);
|
|
8995
|
-
setTouched();
|
|
8996
|
-
if (checked) excludes.forEach((id) => store.setValue(id, false));
|
|
8997
|
-
}
|
|
8998
|
-
}
|
|
8999
|
-
),
|
|
9000
|
-
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
|
|
9001
|
-
] });
|
|
9002
|
-
}
|
|
9003
|
-
case "suggestion_textarea":
|
|
9004
|
-
case "complaint_chips":
|
|
9005
|
-
return /* @__PURE__ */ jsx(SuggestionTextareaWidget, { fieldId });
|
|
9006
|
-
case "lens_assessment":
|
|
9007
|
-
return /* @__PURE__ */ jsx(LensAssessmentWidget, { fieldId });
|
|
9008
|
-
case "functional_impairment_score":
|
|
9009
|
-
return /* @__PURE__ */ jsx(FunctionalImpairmentScoreWidget, { fieldId });
|
|
9010
|
-
case "biometry_iol_workup":
|
|
9011
|
-
return /* @__PURE__ */ jsx(BiometryIolWorkupWidget, { fieldId });
|
|
9012
|
-
case "surgical_risk_flags":
|
|
9013
|
-
return /* @__PURE__ */ jsx(SurgicalRiskFlagsWidget, { fieldId });
|
|
9014
|
-
case "static_text": {
|
|
9015
|
-
const def = fieldDef;
|
|
9016
|
-
const size = def.size ?? "regular";
|
|
9017
|
-
const labelClass = size === "large" ? "text-base" : "text-sm";
|
|
9018
|
-
const descClass = size === "large" ? "text-sm" : "text-xs";
|
|
9019
|
-
return /* @__PURE__ */ jsxs("div", { className: `${labelClass} text-muted-foreground`, children: [
|
|
9020
|
-
def.label,
|
|
9021
|
-
def.description && /* @__PURE__ */ jsx("p", { className: `mt-1 ${descClass} opacity-90`, children: def.description })
|
|
9022
|
-
] });
|
|
9023
|
-
}
|
|
9024
|
-
default:
|
|
9025
|
-
return /* @__PURE__ */ jsxs("div", { className: "text-red-500", children: [
|
|
9026
|
-
"Unknown field type: ",
|
|
9027
|
-
fieldDef.type
|
|
9028
|
-
] });
|
|
9029
|
-
}
|
|
9030
|
-
}
|
|
9031
|
-
var Section = ({ title, children }) => {
|
|
9032
|
-
const [expanded, setExpanded] = useState(true);
|
|
9033
|
-
const handleToggle = () => setExpanded((prev) => !prev);
|
|
9034
|
-
const contentClassName = cn(
|
|
9035
|
-
"overflow-hidden transition-[height] duration-200 ease-in-out",
|
|
9036
|
-
!expanded && "hidden"
|
|
9037
|
-
);
|
|
9038
|
-
return /* @__PURE__ */ jsxs("div", { className: "mb-6 border rounded-lg bg-white shadow-sm overflow-hidden", children: [
|
|
9039
|
-
/* @__PURE__ */ jsxs(
|
|
9040
|
-
"button",
|
|
9188
|
+
var SliderWidget = ({ fieldId }) => {
|
|
9189
|
+
const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
|
|
9190
|
+
const { state } = useForm();
|
|
9191
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
9192
|
+
if (!fieldDef || fieldDef.type !== "slider") return null;
|
|
9193
|
+
const def = fieldDef;
|
|
9194
|
+
const min = def.min ?? 0;
|
|
9195
|
+
const max = def.max ?? 10;
|
|
9196
|
+
const step = def.step ?? 1;
|
|
9197
|
+
const raw = value == null || value === "" ? min : Number(value);
|
|
9198
|
+
const num = Number.isFinite(raw) ? Math.min(max, Math.max(min, raw)) : min;
|
|
9199
|
+
const theme = getThemeConfig("textarea", def.theme);
|
|
9200
|
+
const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
|
|
9201
|
+
const labelClass = theme?.labelClassName;
|
|
9202
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9203
|
+
def.label,
|
|
9204
|
+
" ",
|
|
9205
|
+
def.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" }),
|
|
9206
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-2 text-muted-foreground font-normal tabular-nums", children: [
|
|
9207
|
+
num,
|
|
9208
|
+
"/",
|
|
9209
|
+
max
|
|
9210
|
+
] })
|
|
9211
|
+
] });
|
|
9212
|
+
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { children: labelContent });
|
|
9213
|
+
return /* @__PURE__ */ jsxs("div", { className: wrapperClass, children: [
|
|
9214
|
+
labelEl,
|
|
9215
|
+
/* @__PURE__ */ jsx(
|
|
9216
|
+
Slider,
|
|
9041
9217
|
{
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9218
|
+
className: cn("py-1", showError && "opacity-90 ring-1 ring-red-500 rounded"),
|
|
9219
|
+
disabled,
|
|
9220
|
+
min,
|
|
9221
|
+
max,
|
|
9222
|
+
step,
|
|
9223
|
+
value: [num],
|
|
9224
|
+
onValueChange: (v) => {
|
|
9225
|
+
const n = v[0] ?? min;
|
|
9226
|
+
setValue(n);
|
|
9227
|
+
setTouched();
|
|
9228
|
+
}
|
|
9049
9229
|
}
|
|
9050
9230
|
),
|
|
9051
|
-
|
|
9231
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
9052
9232
|
] });
|
|
9053
9233
|
};
|
|
9054
|
-
var
|
|
9055
|
-
|
|
9056
|
-
label,
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9234
|
+
var CHIEF_CHIPS_FIELD = "chief_complaints_chips";
|
|
9235
|
+
var SWELLING_OPTS = [
|
|
9236
|
+
{ value: "reducible_hernia", label: "Reducible (hernia)" },
|
|
9237
|
+
{ value: "cough_impulse", label: "Cough impulse" },
|
|
9238
|
+
{ value: "skin_changes", label: "Skin changes" }
|
|
9239
|
+
];
|
|
9240
|
+
var GI_OPTS = [
|
|
9241
|
+
{ value: "bleeding_pr", label: "Bleeding PR" },
|
|
9242
|
+
{ value: "vomiting", label: "Vomiting" },
|
|
9243
|
+
{ value: "haematemesis", label: "Haematemesis" }
|
|
9244
|
+
];
|
|
9245
|
+
var BREAST_OPTS = [
|
|
9246
|
+
{ value: "pain", label: "Pain" },
|
|
9247
|
+
{ value: "fh_ca_breast", label: "Family history of Ca breast" }
|
|
9248
|
+
];
|
|
9249
|
+
var ANO_OPTS = [
|
|
9250
|
+
{ value: "pain_defecation", label: "Pain during defecation" },
|
|
9251
|
+
{ value: "bleeding", label: "Bleeding" },
|
|
9252
|
+
{ value: "constipation", label: "Constipation" },
|
|
9253
|
+
{ value: "discharge", label: "Discharge" }
|
|
9254
|
+
];
|
|
9255
|
+
var THYROID_OPTS = [
|
|
9256
|
+
{ value: "dysphagia", label: "Dysphagia" },
|
|
9257
|
+
{ value: "voice_change", label: "Voice change" },
|
|
9258
|
+
{ value: "thyrotoxicosis", label: "Thyrotoxicosis symptoms" }
|
|
9259
|
+
];
|
|
9260
|
+
var SOCRATES_KEYS = [
|
|
9261
|
+
"site",
|
|
9262
|
+
"onset",
|
|
9263
|
+
"character",
|
|
9264
|
+
"radiation",
|
|
9265
|
+
"associated",
|
|
9266
|
+
"timing",
|
|
9267
|
+
"exacerbating"
|
|
9268
|
+
];
|
|
9269
|
+
function Panel({ title, children }) {
|
|
9270
|
+
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
|
|
9271
|
+
/* @__PURE__ */ jsx("div", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5 text-xs font-semibold text-slate-700", children: title }),
|
|
9272
|
+
/* @__PURE__ */ jsx("div", { className: "p-3", children })
|
|
9273
|
+
] });
|
|
9274
|
+
}
|
|
9275
|
+
function chipList(state) {
|
|
9276
|
+
const raw = state.values[CHIEF_CHIPS_FIELD];
|
|
9277
|
+
return Array.isArray(raw) ? raw.filter((x) => typeof x === "string") : [];
|
|
9278
|
+
}
|
|
9279
|
+
var GsSmartHistoryWidget = ({ fieldId }) => {
|
|
9280
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
9281
|
+
const { state } = useForm();
|
|
9282
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
9283
|
+
const safe = useMemo(() => normalizeGeneralSurgerySmartHistory(value), [value]);
|
|
9284
|
+
const chips = useMemo(() => chipList(state), [state]);
|
|
9285
|
+
const showPain = chips.includes("pain");
|
|
9286
|
+
const showSwelling = chips.includes("swelling_lump");
|
|
9287
|
+
const showGI = chips.includes("bleeding") || chips.includes("obstruction");
|
|
9288
|
+
const showBreast = chips.includes("breast");
|
|
9289
|
+
const showAno = chips.includes("anorectal");
|
|
9290
|
+
const showThyroid = chips.includes("thyroid");
|
|
9291
|
+
const update = (next) => {
|
|
9292
|
+
setValue(next);
|
|
9293
|
+
setTouched();
|
|
9063
9294
|
};
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9295
|
+
const setPain = (key, v) => {
|
|
9296
|
+
if (key === "severity") {
|
|
9297
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
9298
|
+
const sev = Number.isFinite(n) ? Math.min(10, Math.max(0, Math.round(n))) : 0;
|
|
9299
|
+
update({ ...safe, pain: { ...safe.pain, severity: sev } });
|
|
9300
|
+
return;
|
|
9301
|
+
}
|
|
9302
|
+
update({ ...safe, pain: { ...safe.pain, [key]: String(v) } });
|
|
9303
|
+
};
|
|
9304
|
+
const toggleArr = (section, val) => {
|
|
9305
|
+
if (section === "swelling") {
|
|
9306
|
+
const a = safe.swelling.checks;
|
|
9307
|
+
const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
|
|
9308
|
+
update({ ...safe, swelling: { ...safe.swelling, checks: next } });
|
|
9309
|
+
} else if (section === "gi") {
|
|
9310
|
+
const a = safe.gi.checks;
|
|
9311
|
+
const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
|
|
9312
|
+
update({ ...safe, gi: { ...safe.gi, checks: next } });
|
|
9313
|
+
} else if (section === "breast") {
|
|
9314
|
+
const a = safe.breast.checks;
|
|
9315
|
+
const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
|
|
9316
|
+
update({ ...safe, breast: { ...safe.breast, checks: next } });
|
|
9317
|
+
} else if (section === "ano") {
|
|
9318
|
+
const a = safe.ano.checks;
|
|
9319
|
+
const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
|
|
9320
|
+
update({ ...safe, ano: { ...safe.ano, checks: next } });
|
|
9321
|
+
} else {
|
|
9322
|
+
const a = safe.thyroid.checks;
|
|
9323
|
+
const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
|
|
9324
|
+
update({ ...safe, thyroid: { ...safe.thyroid, checks: next } });
|
|
9325
|
+
}
|
|
9326
|
+
};
|
|
9327
|
+
if (!fieldDef) return null;
|
|
9328
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
9329
|
+
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
9330
|
+
const labelClass = theme?.labelClassName;
|
|
9331
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9332
|
+
fieldDef.label,
|
|
9333
|
+
fieldDef.required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
9334
|
+
] });
|
|
9335
|
+
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
9336
|
+
const bodyClass = cn(
|
|
9337
|
+
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
9338
|
+
disabled && "pointer-events-none opacity-60"
|
|
9339
|
+
);
|
|
9340
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
9341
|
+
labelEl,
|
|
9342
|
+
/* @__PURE__ */ jsxs("div", { className: bodyClass, children: [
|
|
9343
|
+
showPain ? /* @__PURE__ */ jsx(Panel, { title: "SOCRATES \u2014 pain", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 md:grid-cols-4", children: [
|
|
9344
|
+
SOCRATES_KEYS.map((k) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
9345
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: k }),
|
|
9346
|
+
/* @__PURE__ */ jsx(
|
|
9347
|
+
Input,
|
|
9348
|
+
{
|
|
9349
|
+
className: "h-8 text-xs",
|
|
9350
|
+
value: safe.pain[k],
|
|
9351
|
+
onChange: (e) => setPain(k, e.target.value),
|
|
9352
|
+
disabled
|
|
9353
|
+
}
|
|
9354
|
+
)
|
|
9355
|
+
] }, k)),
|
|
9356
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
9357
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Severity 0\u201310" }),
|
|
9358
|
+
/* @__PURE__ */ jsx(
|
|
9359
|
+
Input,
|
|
9360
|
+
{
|
|
9361
|
+
type: "number",
|
|
9362
|
+
min: 0,
|
|
9363
|
+
max: 10,
|
|
9364
|
+
className: "h-8 text-xs",
|
|
9365
|
+
value: safe.pain.severity,
|
|
9366
|
+
onChange: (e) => setPain("severity", e.target.value),
|
|
9367
|
+
disabled
|
|
9368
|
+
}
|
|
9369
|
+
)
|
|
9370
|
+
] })
|
|
9371
|
+
] }) }) : null,
|
|
9372
|
+
showSwelling ? /* @__PURE__ */ jsxs(Panel, { title: "Swelling history", children: [
|
|
9373
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-3", children: [
|
|
9374
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9375
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Duration" }),
|
|
9376
|
+
/* @__PURE__ */ jsx(
|
|
9377
|
+
Input,
|
|
9378
|
+
{
|
|
9379
|
+
className: "h-8 text-xs",
|
|
9380
|
+
value: safe.swelling.duration,
|
|
9381
|
+
onChange: (e) => update({ ...safe, swelling: { ...safe.swelling, duration: e.target.value } }),
|
|
9382
|
+
disabled
|
|
9383
|
+
}
|
|
9384
|
+
)
|
|
9385
|
+
] }),
|
|
9386
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9387
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Size progression" }),
|
|
9388
|
+
/* @__PURE__ */ jsx(
|
|
9389
|
+
Input,
|
|
9390
|
+
{
|
|
9391
|
+
className: "h-8 text-xs",
|
|
9392
|
+
value: safe.swelling.sizeProgression,
|
|
9393
|
+
onChange: (e) => update({ ...safe, swelling: { ...safe.swelling, sizeProgression: e.target.value } }),
|
|
9394
|
+
disabled
|
|
9395
|
+
}
|
|
9396
|
+
)
|
|
9397
|
+
] }),
|
|
9398
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9399
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Painful / painless" }),
|
|
9400
|
+
/* @__PURE__ */ jsx(
|
|
9401
|
+
Input,
|
|
9402
|
+
{
|
|
9403
|
+
className: "h-8 text-xs",
|
|
9404
|
+
value: safe.swelling.painfulPainless,
|
|
9405
|
+
onChange: (e) => update({ ...safe, swelling: { ...safe.swelling, painfulPainless: e.target.value } }),
|
|
9406
|
+
disabled
|
|
9407
|
+
}
|
|
9408
|
+
)
|
|
9409
|
+
] })
|
|
9410
|
+
] }),
|
|
9411
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: SWELLING_OPTS.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9412
|
+
/* @__PURE__ */ jsx(
|
|
9413
|
+
Checkbox,
|
|
9414
|
+
{
|
|
9415
|
+
checked: safe.swelling.checks.includes(o.value),
|
|
9416
|
+
onCheckedChange: () => toggleArr("swelling", o.value),
|
|
9417
|
+
disabled
|
|
9418
|
+
}
|
|
9419
|
+
),
|
|
9420
|
+
o.label
|
|
9421
|
+
] }, o.value)) })
|
|
9422
|
+
] }) : null,
|
|
9423
|
+
showGI ? /* @__PURE__ */ jsxs(Panel, { title: "GI history", children: [
|
|
9424
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-3", children: [
|
|
9425
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9426
|
+
"Appetite",
|
|
9427
|
+
/* @__PURE__ */ jsx(
|
|
9428
|
+
Input,
|
|
9429
|
+
{
|
|
9430
|
+
className: "h-8 text-xs",
|
|
9431
|
+
value: safe.gi.appetite,
|
|
9432
|
+
onChange: (e) => update({ ...safe, gi: { ...safe.gi, appetite: e.target.value } }),
|
|
9433
|
+
disabled
|
|
9434
|
+
}
|
|
9435
|
+
)
|
|
9436
|
+
] }),
|
|
9437
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9438
|
+
"Weight loss",
|
|
9439
|
+
/* @__PURE__ */ jsx(
|
|
9440
|
+
Input,
|
|
9441
|
+
{
|
|
9442
|
+
className: "h-8 text-xs",
|
|
9443
|
+
value: safe.gi.weightLoss,
|
|
9444
|
+
onChange: (e) => update({ ...safe, gi: { ...safe.gi, weightLoss: e.target.value } }),
|
|
9445
|
+
disabled
|
|
9446
|
+
}
|
|
9447
|
+
)
|
|
9448
|
+
] }),
|
|
9449
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9450
|
+
"Bowel habits",
|
|
9451
|
+
/* @__PURE__ */ jsx(
|
|
9452
|
+
Input,
|
|
9453
|
+
{
|
|
9454
|
+
className: "h-8 text-xs",
|
|
9455
|
+
value: safe.gi.bowelHabits,
|
|
9456
|
+
onChange: (e) => update({ ...safe, gi: { ...safe.gi, bowelHabits: e.target.value } }),
|
|
9457
|
+
disabled
|
|
9458
|
+
}
|
|
9459
|
+
)
|
|
9460
|
+
] })
|
|
9461
|
+
] }),
|
|
9462
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: GI_OPTS.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9463
|
+
/* @__PURE__ */ jsx(
|
|
9464
|
+
Checkbox,
|
|
9465
|
+
{
|
|
9466
|
+
checked: safe.gi.checks.includes(o.value),
|
|
9467
|
+
onCheckedChange: () => toggleArr("gi", o.value),
|
|
9468
|
+
disabled
|
|
9469
|
+
}
|
|
9470
|
+
),
|
|
9471
|
+
o.label
|
|
9472
|
+
] }, o.value)) })
|
|
9473
|
+
] }) : null,
|
|
9474
|
+
showBreast ? /* @__PURE__ */ jsxs(Panel, { title: "Breast history", children: [
|
|
9475
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-2", children: [
|
|
9476
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9477
|
+
"Lump duration",
|
|
9478
|
+
/* @__PURE__ */ jsx(
|
|
9479
|
+
Input,
|
|
9480
|
+
{
|
|
9481
|
+
className: "h-8 text-xs",
|
|
9482
|
+
value: safe.breast.lumpDuration,
|
|
9483
|
+
onChange: (e) => update({ ...safe, breast: { ...safe.breast, lumpDuration: e.target.value } }),
|
|
9484
|
+
disabled
|
|
9485
|
+
}
|
|
9486
|
+
)
|
|
9487
|
+
] }),
|
|
9488
|
+
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
9489
|
+
"Nipple discharge",
|
|
9490
|
+
/* @__PURE__ */ jsx(
|
|
9491
|
+
Input,
|
|
9492
|
+
{
|
|
9493
|
+
className: "h-8 text-xs",
|
|
9494
|
+
value: safe.breast.nippleDischarge,
|
|
9495
|
+
onChange: (e) => update({ ...safe, breast: { ...safe.breast, nippleDischarge: e.target.value } }),
|
|
9496
|
+
disabled
|
|
9497
|
+
}
|
|
9498
|
+
)
|
|
9499
|
+
] })
|
|
9500
|
+
] }),
|
|
9501
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: BREAST_OPTS.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9502
|
+
/* @__PURE__ */ jsx(
|
|
9503
|
+
Checkbox,
|
|
9504
|
+
{
|
|
9505
|
+
checked: safe.breast.checks.includes(o.value),
|
|
9506
|
+
onCheckedChange: () => toggleArr("breast", o.value),
|
|
9507
|
+
disabled
|
|
9508
|
+
}
|
|
9509
|
+
),
|
|
9510
|
+
o.label
|
|
9511
|
+
] }, o.value)) })
|
|
9512
|
+
] }) : null,
|
|
9513
|
+
showAno ? /* @__PURE__ */ jsx(Panel, { title: "Anorectal history", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-2", children: ANO_OPTS.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9514
|
+
/* @__PURE__ */ jsx(
|
|
9515
|
+
Checkbox,
|
|
9516
|
+
{
|
|
9517
|
+
checked: safe.ano.checks.includes(o.value),
|
|
9518
|
+
onCheckedChange: () => toggleArr("ano", o.value),
|
|
9519
|
+
disabled
|
|
9520
|
+
}
|
|
9521
|
+
),
|
|
9522
|
+
o.label
|
|
9523
|
+
] }, o.value)) }) }) : null,
|
|
9524
|
+
showThyroid ? /* @__PURE__ */ jsxs(Panel, { title: "Thyroid history", children: [
|
|
9525
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-2", children: /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1 md:col-span-2", children: [
|
|
9526
|
+
"Swelling duration",
|
|
9527
|
+
/* @__PURE__ */ jsx(
|
|
9528
|
+
Input,
|
|
9529
|
+
{
|
|
9530
|
+
className: "h-8 text-xs",
|
|
9531
|
+
value: safe.thyroid.swellingDuration,
|
|
9532
|
+
onChange: (e) => update({ ...safe, thyroid: { ...safe.thyroid, swellingDuration: e.target.value } }),
|
|
9533
|
+
disabled
|
|
9534
|
+
}
|
|
9535
|
+
)
|
|
9536
|
+
] }) }),
|
|
9537
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: THYROID_OPTS.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9538
|
+
/* @__PURE__ */ jsx(
|
|
9539
|
+
Checkbox,
|
|
9540
|
+
{
|
|
9541
|
+
checked: safe.thyroid.checks.includes(o.value),
|
|
9542
|
+
onCheckedChange: () => toggleArr("thyroid", o.value),
|
|
9543
|
+
disabled
|
|
9544
|
+
}
|
|
9545
|
+
),
|
|
9546
|
+
o.label
|
|
9547
|
+
] }, o.value)) })
|
|
9548
|
+
] }) : null,
|
|
9549
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
9550
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium text-slate-700", children: "Systemic surgical screening" }),
|
|
9551
|
+
/* @__PURE__ */ jsx(
|
|
9552
|
+
Textarea,
|
|
9553
|
+
{
|
|
9554
|
+
className: "min-h-[72px] rounded-md border border-input bg-white text-sm",
|
|
9555
|
+
placeholder: "Fever, weight loss, appetite loss, fatigue, malignancy red flags\u2026",
|
|
9556
|
+
value: safe.systemic,
|
|
9557
|
+
onChange: (e) => update({ ...safe, systemic: e.target.value }),
|
|
9558
|
+
disabled
|
|
9559
|
+
}
|
|
9560
|
+
)
|
|
9561
|
+
] })
|
|
9562
|
+
] }),
|
|
9563
|
+
showError ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
9564
|
+
] });
|
|
9565
|
+
};
|
|
9566
|
+
var GS_CLINICAL_EXAMINATION_FIELD = "clinical_examination";
|
|
9567
|
+
var GENERAL = [
|
|
9568
|
+
{ value: "pallor", label: "Pallor" },
|
|
9569
|
+
{ value: "icterus", label: "Icterus" },
|
|
9570
|
+
{ value: "cyanosis", label: "Cyanosis" },
|
|
9571
|
+
{ value: "clubbing", label: "Clubbing" },
|
|
9572
|
+
{ value: "lymphadenopathy", label: "Lymphadenopathy" },
|
|
9573
|
+
{ value: "oedema", label: "Oedema" }
|
|
9574
|
+
];
|
|
9575
|
+
var REGIONS = [
|
|
9576
|
+
{ key: "abdomen", label: "Abdomen" },
|
|
9577
|
+
{ key: "hernia", label: "Hernia" },
|
|
9578
|
+
{ key: "breast", label: "Breast" },
|
|
9579
|
+
{ key: "thyroid", label: "Thyroid" },
|
|
9580
|
+
{ key: "anorectal", label: "Anorectal" },
|
|
9581
|
+
{ key: "limb", label: "Limb / varicose" }
|
|
9582
|
+
];
|
|
9583
|
+
var ABD_INSP = [
|
|
9584
|
+
{ value: "distension", label: "Distension" },
|
|
9585
|
+
{ value: "scars", label: "Scars" },
|
|
9586
|
+
{ value: "visible_peristalsis", label: "Visible peristalsis" }
|
|
9587
|
+
];
|
|
9588
|
+
var ABD_PALP = [
|
|
9589
|
+
{ value: "tenderness", label: "Tenderness" },
|
|
9590
|
+
{ value: "guarding", label: "Guarding" },
|
|
9591
|
+
{ value: "rigidity", label: "Rigidity" },
|
|
9592
|
+
{ value: "mass", label: "Palpable mass" }
|
|
9593
|
+
];
|
|
9594
|
+
var ABD_PERC = [
|
|
9595
|
+
{ value: "tympany", label: "Tympany" },
|
|
9596
|
+
{ value: "shifting_dullness", label: "Shifting dullness" }
|
|
9597
|
+
];
|
|
9598
|
+
function SubGroup({ title, children }) {
|
|
9599
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
9600
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: title }),
|
|
9601
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children })
|
|
9602
|
+
] });
|
|
9603
|
+
}
|
|
9604
|
+
function RegionCard({ title, children }) {
|
|
9605
|
+
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
|
|
9606
|
+
/* @__PURE__ */ jsx("div", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5 text-xs font-semibold text-slate-700", children: title }),
|
|
9607
|
+
/* @__PURE__ */ jsx("div", { className: "p-3", children })
|
|
9608
|
+
] });
|
|
9609
|
+
}
|
|
9610
|
+
var GsExaminationWidget = ({ fieldId }) => {
|
|
9611
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
9612
|
+
const clinicalField = useField(GS_CLINICAL_EXAMINATION_FIELD);
|
|
9613
|
+
const { state } = useForm();
|
|
9614
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
9615
|
+
const safe = useMemo(() => normalizeGeneralSurgeryExamination(value), [value]);
|
|
9616
|
+
const update = (next) => {
|
|
9617
|
+
setValue(next);
|
|
9618
|
+
setTouched();
|
|
9619
|
+
};
|
|
9620
|
+
const toggleIn = (arr, val) => arr.includes(val) ? arr.filter((x) => x !== val) : [...arr, val];
|
|
9621
|
+
const toggleGeneral = (val) => {
|
|
9622
|
+
update({ ...safe, general: toggleIn(safe.general, val) });
|
|
9623
|
+
};
|
|
9624
|
+
const toggleRegion = (key) => {
|
|
9625
|
+
update({ ...safe, regions: toggleIn(safe.regions, key) });
|
|
9626
|
+
};
|
|
9627
|
+
const toggleAbd = (key, val) => {
|
|
9628
|
+
update({
|
|
9629
|
+
...safe,
|
|
9630
|
+
abdomen: { ...safe.abdomen, [key]: toggleIn(safe.abdomen[key], val) }
|
|
9631
|
+
});
|
|
9632
|
+
};
|
|
9633
|
+
if (!fieldDef) return null;
|
|
9634
|
+
const has = (r) => safe.regions.includes(r);
|
|
9635
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
9636
|
+
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
9637
|
+
const labelClass = theme?.labelClassName;
|
|
9638
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9639
|
+
fieldDef.label,
|
|
9640
|
+
fieldDef.required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
9641
|
+
] });
|
|
9642
|
+
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
9643
|
+
const bodyClass = cn(
|
|
9644
|
+
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
9645
|
+
disabled && "pointer-events-none opacity-60"
|
|
9646
|
+
);
|
|
9647
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
9648
|
+
labelEl,
|
|
9649
|
+
/* @__PURE__ */ jsxs("div", { className: bodyClass, children: [
|
|
9650
|
+
/* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
|
|
9651
|
+
/* @__PURE__ */ jsx("div", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5 text-xs font-semibold text-slate-700", children: "General examination" }),
|
|
9652
|
+
/* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2 text-xs md:grid-cols-3 lg:grid-cols-6", children: GENERAL.map((g) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9653
|
+
/* @__PURE__ */ jsx(
|
|
9654
|
+
Checkbox,
|
|
9655
|
+
{
|
|
9656
|
+
checked: safe.general.includes(g.value),
|
|
9657
|
+
onCheckedChange: () => toggleGeneral(g.value),
|
|
9658
|
+
disabled
|
|
9659
|
+
}
|
|
9660
|
+
),
|
|
9661
|
+
g.label
|
|
9662
|
+
] }, g.value)) }) })
|
|
9663
|
+
] }),
|
|
9664
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
9665
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-semibold text-slate-700", children: "Regional examination \u2014 select region(s)" }),
|
|
9666
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: REGIONS.map((r) => {
|
|
9667
|
+
const on = safe.regions.includes(r.key);
|
|
9668
|
+
return /* @__PURE__ */ jsx(
|
|
9669
|
+
Button,
|
|
9670
|
+
{
|
|
9671
|
+
type: "button",
|
|
9672
|
+
size: "sm",
|
|
9673
|
+
variant: on ? "default" : "outline",
|
|
9674
|
+
className: "h-7 rounded-full px-3 text-xs",
|
|
9675
|
+
onClick: () => toggleRegion(r.key),
|
|
9676
|
+
disabled,
|
|
9677
|
+
children: r.label
|
|
9678
|
+
},
|
|
9679
|
+
r.key
|
|
9680
|
+
);
|
|
9681
|
+
}) })
|
|
9682
|
+
] }),
|
|
9683
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
9684
|
+
has("abdomen") ? /* @__PURE__ */ jsx(RegionCard, { title: "Abdomen \u2014 inspection \xB7 palpation \xB7 percussion \xB7 auscultation", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4", children: [
|
|
9685
|
+
/* @__PURE__ */ jsx(SubGroup, { title: "Inspection", children: ABD_INSP.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9686
|
+
/* @__PURE__ */ jsx(
|
|
9687
|
+
Checkbox,
|
|
9688
|
+
{
|
|
9689
|
+
checked: safe.abdomen.inspection.includes(o.value),
|
|
9690
|
+
onCheckedChange: () => toggleAbd("inspection", o.value),
|
|
9691
|
+
disabled
|
|
9692
|
+
}
|
|
9693
|
+
),
|
|
9694
|
+
o.label
|
|
9695
|
+
] }, o.value)) }),
|
|
9696
|
+
/* @__PURE__ */ jsxs(SubGroup, { title: "Palpation", children: [
|
|
9697
|
+
ABD_PALP.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9698
|
+
/* @__PURE__ */ jsx(
|
|
9699
|
+
Checkbox,
|
|
9700
|
+
{
|
|
9701
|
+
checked: safe.abdomen.palpation.includes(o.value),
|
|
9702
|
+
onCheckedChange: () => toggleAbd("palpation", o.value),
|
|
9703
|
+
disabled
|
|
9704
|
+
}
|
|
9705
|
+
),
|
|
9706
|
+
o.label
|
|
9707
|
+
] }, o.value)),
|
|
9708
|
+
/* @__PURE__ */ jsxs("label", { className: "mt-2 block text-xs", children: [
|
|
9709
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Mass size / mobility" }),
|
|
9710
|
+
/* @__PURE__ */ jsx(
|
|
9711
|
+
Input,
|
|
9712
|
+
{
|
|
9713
|
+
className: "h-8 text-xs",
|
|
9714
|
+
value: safe.abdomen.massNotes,
|
|
9715
|
+
onChange: (e) => update({ ...safe, abdomen: { ...safe.abdomen, massNotes: e.target.value } }),
|
|
9716
|
+
disabled
|
|
9717
|
+
}
|
|
9718
|
+
)
|
|
9719
|
+
] })
|
|
9720
|
+
] }),
|
|
9721
|
+
/* @__PURE__ */ jsx(SubGroup, { title: "Percussion", children: ABD_PERC.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
|
|
9722
|
+
/* @__PURE__ */ jsx(
|
|
9723
|
+
Checkbox,
|
|
9724
|
+
{
|
|
9725
|
+
checked: safe.abdomen.percussion.includes(o.value),
|
|
9726
|
+
onCheckedChange: () => toggleAbd("percussion", o.value),
|
|
9727
|
+
disabled
|
|
9728
|
+
}
|
|
9729
|
+
),
|
|
9730
|
+
o.label
|
|
9731
|
+
] }, o.value)) }),
|
|
9732
|
+
/* @__PURE__ */ jsxs(SubGroup, { title: "Auscultation", children: [
|
|
9733
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1 block text-xs font-medium", children: "Bowel sounds" }),
|
|
9734
|
+
/* @__PURE__ */ jsxs(
|
|
9735
|
+
Select,
|
|
9736
|
+
{
|
|
9737
|
+
value: safe.abdomen.bowelSounds,
|
|
9738
|
+
onValueChange: (val) => update({
|
|
9739
|
+
...safe,
|
|
9740
|
+
abdomen: {
|
|
9741
|
+
...safe.abdomen,
|
|
9742
|
+
bowelSounds: val
|
|
9743
|
+
}
|
|
9744
|
+
}),
|
|
9745
|
+
disabled,
|
|
9746
|
+
children: [
|
|
9747
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select\u2026" }) }),
|
|
9748
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
9749
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
9750
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "normal", children: "Normal" }),
|
|
9751
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "up", children: "\u2191" }),
|
|
9752
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "down", children: "\u2193" }),
|
|
9753
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "absent", children: "Absent" })
|
|
9754
|
+
] })
|
|
9755
|
+
]
|
|
9756
|
+
}
|
|
9757
|
+
)
|
|
9758
|
+
] })
|
|
9759
|
+
] }) }) : null,
|
|
9760
|
+
has("hernia") ? /* @__PURE__ */ jsx(RegionCard, { title: "Hernia exam", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-4", children: [
|
|
9761
|
+
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
9762
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Site" }),
|
|
9763
|
+
/* @__PURE__ */ jsx(
|
|
9764
|
+
Input,
|
|
9765
|
+
{
|
|
9766
|
+
className: "h-8 text-xs",
|
|
9767
|
+
value: safe.hernia.site,
|
|
9768
|
+
onChange: (e) => update({ ...safe, hernia: { ...safe.hernia, site: e.target.value } }),
|
|
9769
|
+
disabled
|
|
9770
|
+
}
|
|
9771
|
+
)
|
|
9772
|
+
] }),
|
|
9773
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9774
|
+
/* @__PURE__ */ jsx(
|
|
9775
|
+
Checkbox,
|
|
9776
|
+
{
|
|
9777
|
+
checked: safe.hernia.reducible,
|
|
9778
|
+
onCheckedChange: (c) => update({ ...safe, hernia: { ...safe.hernia, reducible: c === true } }),
|
|
9779
|
+
disabled
|
|
9780
|
+
}
|
|
9781
|
+
),
|
|
9782
|
+
"Reducible"
|
|
9783
|
+
] }),
|
|
9784
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9785
|
+
/* @__PURE__ */ jsx(
|
|
9786
|
+
Checkbox,
|
|
9787
|
+
{
|
|
9788
|
+
checked: safe.hernia.coughImpulse,
|
|
9789
|
+
onCheckedChange: (c) => update({ ...safe, hernia: { ...safe.hernia, coughImpulse: c === true } }),
|
|
9790
|
+
disabled
|
|
9791
|
+
}
|
|
9792
|
+
),
|
|
9793
|
+
"Cough impulse"
|
|
9794
|
+
] }),
|
|
9795
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9796
|
+
/* @__PURE__ */ jsx(
|
|
9797
|
+
Checkbox,
|
|
9798
|
+
{
|
|
9799
|
+
checked: safe.hernia.tenderness,
|
|
9800
|
+
onCheckedChange: (c) => update({ ...safe, hernia: { ...safe.hernia, tenderness: c === true } }),
|
|
9801
|
+
disabled
|
|
9802
|
+
}
|
|
9803
|
+
),
|
|
9804
|
+
"Tenderness"
|
|
9805
|
+
] })
|
|
9806
|
+
] }) }) : null,
|
|
9807
|
+
has("breast") ? /* @__PURE__ */ jsx(RegionCard, { title: "Breast exam", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-4", children: [
|
|
9808
|
+
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
9809
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Lump size (cm)" }),
|
|
9810
|
+
/* @__PURE__ */ jsx(
|
|
9811
|
+
Input,
|
|
9812
|
+
{
|
|
9813
|
+
className: "h-8 text-xs",
|
|
9814
|
+
value: safe.breast.lumpSizeCm,
|
|
9815
|
+
onChange: (e) => update({ ...safe, breast: { ...safe.breast, lumpSizeCm: e.target.value } }),
|
|
9816
|
+
disabled
|
|
9817
|
+
}
|
|
9818
|
+
)
|
|
9819
|
+
] }),
|
|
9820
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9821
|
+
/* @__PURE__ */ jsx(
|
|
9822
|
+
Checkbox,
|
|
9823
|
+
{
|
|
9824
|
+
checked: safe.breast.mobile,
|
|
9825
|
+
onCheckedChange: (c) => update({ ...safe, breast: { ...safe.breast, mobile: c === true } }),
|
|
9826
|
+
disabled
|
|
9827
|
+
}
|
|
9828
|
+
),
|
|
9829
|
+
"Mobile"
|
|
9830
|
+
] }),
|
|
9831
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9832
|
+
/* @__PURE__ */ jsx(
|
|
9833
|
+
Checkbox,
|
|
9834
|
+
{
|
|
9835
|
+
checked: safe.breast.skinInvolvement,
|
|
9836
|
+
onCheckedChange: (c) => update({ ...safe, breast: { ...safe.breast, skinInvolvement: c === true } }),
|
|
9837
|
+
disabled
|
|
9838
|
+
}
|
|
9839
|
+
),
|
|
9840
|
+
"Skin involvement"
|
|
9841
|
+
] }),
|
|
9842
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9843
|
+
/* @__PURE__ */ jsx(
|
|
9844
|
+
Checkbox,
|
|
9845
|
+
{
|
|
9846
|
+
checked: safe.breast.axillaryNodes,
|
|
9847
|
+
onCheckedChange: (c) => update({ ...safe, breast: { ...safe.breast, axillaryNodes: c === true } }),
|
|
9848
|
+
disabled
|
|
9849
|
+
}
|
|
9850
|
+
),
|
|
9851
|
+
"Axillary nodes"
|
|
9852
|
+
] })
|
|
9853
|
+
] }) }) : null,
|
|
9854
|
+
has("thyroid") ? /* @__PURE__ */ jsx(RegionCard, { title: "Thyroid exam", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-4", children: [
|
|
9855
|
+
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
9856
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Size" }),
|
|
9857
|
+
/* @__PURE__ */ jsx(
|
|
9858
|
+
Input,
|
|
9859
|
+
{
|
|
9860
|
+
className: "h-8 text-xs",
|
|
9861
|
+
value: safe.thyroid.size,
|
|
9862
|
+
onChange: (e) => update({ ...safe, thyroid: { ...safe.thyroid, size: e.target.value } }),
|
|
9863
|
+
disabled
|
|
9864
|
+
}
|
|
9865
|
+
)
|
|
9866
|
+
] }),
|
|
9867
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9868
|
+
/* @__PURE__ */ jsx(
|
|
9869
|
+
Checkbox,
|
|
9870
|
+
{
|
|
9871
|
+
checked: safe.thyroid.mobileDeglutition,
|
|
9872
|
+
onCheckedChange: (c) => update({ ...safe, thyroid: { ...safe.thyroid, mobileDeglutition: c === true } }),
|
|
9873
|
+
disabled
|
|
9874
|
+
}
|
|
9875
|
+
),
|
|
9876
|
+
"Mobile with deglutition"
|
|
9877
|
+
] }),
|
|
9878
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9879
|
+
/* @__PURE__ */ jsx(
|
|
9880
|
+
Checkbox,
|
|
9881
|
+
{
|
|
9882
|
+
checked: safe.thyroid.nodules,
|
|
9883
|
+
onCheckedChange: (c) => update({ ...safe, thyroid: { ...safe.thyroid, nodules: c === true } }),
|
|
9884
|
+
disabled
|
|
9885
|
+
}
|
|
9886
|
+
),
|
|
9887
|
+
"Nodules"
|
|
9888
|
+
] }),
|
|
9889
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9890
|
+
/* @__PURE__ */ jsx(
|
|
9891
|
+
Checkbox,
|
|
9892
|
+
{
|
|
9893
|
+
checked: safe.thyroid.cervicalNodes,
|
|
9894
|
+
onCheckedChange: (c) => update({ ...safe, thyroid: { ...safe.thyroid, cervicalNodes: c === true } }),
|
|
9895
|
+
disabled
|
|
9896
|
+
}
|
|
9897
|
+
),
|
|
9898
|
+
"Cervical lymph nodes"
|
|
9899
|
+
] })
|
|
9900
|
+
] }) }) : null,
|
|
9901
|
+
has("anorectal") ? /* @__PURE__ */ jsx(RegionCard, { title: "Anorectal exam", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-3", children: [
|
|
9902
|
+
/* @__PURE__ */ jsxs("label", { className: "block md:col-span-3", children: [
|
|
9903
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Inspection findings" }),
|
|
9904
|
+
/* @__PURE__ */ jsx(
|
|
9905
|
+
Input,
|
|
9906
|
+
{
|
|
9907
|
+
className: "h-8 text-xs",
|
|
9908
|
+
value: safe.anorectal.inspection,
|
|
9909
|
+
onChange: (e) => update({ ...safe, anorectal: { ...safe.anorectal, inspection: e.target.value } }),
|
|
9910
|
+
disabled
|
|
9911
|
+
}
|
|
9912
|
+
)
|
|
9913
|
+
] }),
|
|
9914
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9915
|
+
/* @__PURE__ */ jsx(
|
|
9916
|
+
Checkbox,
|
|
9917
|
+
{
|
|
9918
|
+
checked: safe.anorectal.dreDone,
|
|
9919
|
+
onCheckedChange: (c) => update({ ...safe, anorectal: { ...safe.anorectal, dreDone: c === true } }),
|
|
9920
|
+
disabled
|
|
9921
|
+
}
|
|
9922
|
+
),
|
|
9923
|
+
"DRE done"
|
|
9924
|
+
] }),
|
|
9925
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9926
|
+
/* @__PURE__ */ jsx(
|
|
9927
|
+
Checkbox,
|
|
9928
|
+
{
|
|
9929
|
+
checked: safe.anorectal.proctoscopyDone,
|
|
9930
|
+
onCheckedChange: (c) => update({ ...safe, anorectal: { ...safe.anorectal, proctoscopyDone: c === true } }),
|
|
9931
|
+
disabled
|
|
9932
|
+
}
|
|
9933
|
+
),
|
|
9934
|
+
"Proctoscopy done"
|
|
9935
|
+
] }),
|
|
9936
|
+
/* @__PURE__ */ jsxs("div", { className: "md:col-span-3", children: [
|
|
9937
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-semibold", children: "DRE / proctoscopy notes" }),
|
|
9938
|
+
/* @__PURE__ */ jsx(
|
|
9939
|
+
Textarea,
|
|
9940
|
+
{
|
|
9941
|
+
className: "mt-1 min-h-[64px] text-sm",
|
|
9942
|
+
placeholder: "Sphincter tone, masses, prostate, bleeding\u2026",
|
|
9943
|
+
value: safe.anorectal.notes,
|
|
9944
|
+
onChange: (e) => update({ ...safe, anorectal: { ...safe.anorectal, notes: e.target.value } }),
|
|
9945
|
+
disabled
|
|
9946
|
+
}
|
|
9947
|
+
)
|
|
9948
|
+
] })
|
|
9949
|
+
] }) }) : null,
|
|
9950
|
+
has("limb") ? /* @__PURE__ */ jsx(RegionCard, { title: "Limb / varicose veins", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-x-4 gap-y-2 text-xs", children: [
|
|
9951
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9952
|
+
/* @__PURE__ */ jsx(
|
|
9953
|
+
Checkbox,
|
|
9954
|
+
{
|
|
9955
|
+
checked: safe.limb.dilatedVeins,
|
|
9956
|
+
onCheckedChange: (c) => update({ ...safe, limb: { ...safe.limb, dilatedVeins: c === true } }),
|
|
9957
|
+
disabled
|
|
9958
|
+
}
|
|
9959
|
+
),
|
|
9960
|
+
"Dilated veins"
|
|
9961
|
+
] }),
|
|
9962
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9963
|
+
/* @__PURE__ */ jsx(
|
|
9964
|
+
Checkbox,
|
|
9965
|
+
{
|
|
9966
|
+
checked: safe.limb.ulcer,
|
|
9967
|
+
onCheckedChange: (c) => update({ ...safe, limb: { ...safe.limb, ulcer: c === true } }),
|
|
9968
|
+
disabled
|
|
9969
|
+
}
|
|
9970
|
+
),
|
|
9971
|
+
"Ulcer"
|
|
9972
|
+
] }),
|
|
9973
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
9974
|
+
/* @__PURE__ */ jsx(
|
|
9975
|
+
Checkbox,
|
|
9976
|
+
{
|
|
9977
|
+
checked: safe.limb.oedema,
|
|
9978
|
+
onCheckedChange: (c) => update({ ...safe, limb: { ...safe.limb, oedema: c === true } }),
|
|
9979
|
+
disabled
|
|
9980
|
+
}
|
|
9981
|
+
),
|
|
9982
|
+
"Oedema"
|
|
9983
|
+
] })
|
|
9984
|
+
] }) }) : null
|
|
9985
|
+
] }),
|
|
9986
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
9987
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-semibold text-slate-700", children: clinicalField.fieldDef?.label ?? "Clinical examination" }),
|
|
9988
|
+
/* @__PURE__ */ jsx(
|
|
9989
|
+
Textarea,
|
|
9990
|
+
{
|
|
9991
|
+
className: "min-h-[88px] rounded-md border border-input bg-white text-sm",
|
|
9992
|
+
value: typeof clinicalField.value === "string" ? clinicalField.value : clinicalField.value == null ? "" : String(clinicalField.value),
|
|
9993
|
+
onChange: (e) => {
|
|
9994
|
+
clinicalField.setValue(e.target.value);
|
|
9995
|
+
clinicalField.setTouched();
|
|
9996
|
+
},
|
|
9997
|
+
disabled: disabled || clinicalField.disabled
|
|
9998
|
+
}
|
|
9999
|
+
)
|
|
10000
|
+
] })
|
|
10001
|
+
] }),
|
|
10002
|
+
showError ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
10003
|
+
] });
|
|
10004
|
+
};
|
|
10005
|
+
var CHIEF_CHIPS_FIELD2 = "chief_complaints_chips";
|
|
10006
|
+
var GS_EXAMINATION_FIELD = "gs_examination";
|
|
10007
|
+
function chipList2(state) {
|
|
10008
|
+
const raw = state.values[CHIEF_CHIPS_FIELD2];
|
|
10009
|
+
return Array.isArray(raw) ? raw.filter((x) => typeof x === "string") : [];
|
|
10010
|
+
}
|
|
10011
|
+
function regionList(state) {
|
|
10012
|
+
const raw = state.values[GS_EXAMINATION_FIELD];
|
|
10013
|
+
const ex = normalizeGeneralSurgeryExamination(raw);
|
|
10014
|
+
return ex.regions;
|
|
10015
|
+
}
|
|
10016
|
+
var GsGradingWidget = ({ fieldId }) => {
|
|
10017
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
10018
|
+
const { state } = useForm();
|
|
10019
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
10020
|
+
const safe = useMemo(() => normalizeGeneralSurgeryGrading(value), [value]);
|
|
10021
|
+
const chips = useMemo(() => chipList2(state), [state]);
|
|
10022
|
+
const regions = useMemo(() => regionList(state), [state]);
|
|
10023
|
+
const visibleRows = useMemo(() => {
|
|
10024
|
+
return ALL_GS_CONDITIONS.filter(
|
|
10025
|
+
(c) => gsGradingRowVisible(c, chips, regions, safe[c] ?? 0)
|
|
10026
|
+
);
|
|
10027
|
+
}, [chips, regions, safe]);
|
|
10028
|
+
const update = (next) => {
|
|
10029
|
+
setValue(next);
|
|
10030
|
+
setTouched();
|
|
10031
|
+
};
|
|
10032
|
+
const setGrade = (cond, gradeStr) => {
|
|
10033
|
+
const n = Math.min(5, Math.max(0, Math.round(Number(gradeStr)) || 0));
|
|
10034
|
+
update({ ...safe, [cond]: n });
|
|
10035
|
+
};
|
|
10036
|
+
if (!fieldDef) return null;
|
|
10037
|
+
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
10038
|
+
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
10039
|
+
const labelClass = theme?.labelClassName;
|
|
10040
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10041
|
+
fieldDef.label,
|
|
10042
|
+
fieldDef.required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
10043
|
+
] });
|
|
10044
|
+
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
10045
|
+
const bodyClass = cn(
|
|
10046
|
+
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
10047
|
+
disabled && "pointer-events-none opacity-60"
|
|
10048
|
+
);
|
|
10049
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
10050
|
+
labelEl,
|
|
10051
|
+
/* @__PURE__ */ jsx("div", { className: bodyClass, children: visibleRows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed border-[#D0D0D0] bg-white p-6 text-center text-xs text-muted-foreground", children: "No conditions to grade yet. Select a chief complaint category or pick an examination region." }) : /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-md border border-[#D0D0D0]", children: /* @__PURE__ */ jsxs("table", { className: "w-full min-w-[520px] border-collapse text-xs", children: [
|
|
10052
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50", children: [
|
|
10053
|
+
/* @__PURE__ */ jsx("th", { className: "px-3 py-2 text-left font-semibold text-slate-700", children: "Condition" }),
|
|
10054
|
+
/* @__PURE__ */ jsx("th", { className: "w-24 px-2 py-2 font-semibold text-slate-700", children: "Grade" }),
|
|
10055
|
+
/* @__PURE__ */ jsx("th", { className: "px-3 py-2 text-left font-semibold text-slate-700", children: "Description" })
|
|
10056
|
+
] }) }),
|
|
10057
|
+
/* @__PURE__ */ jsx("tbody", { className: "bg-white", children: visibleRows.map((c) => {
|
|
10058
|
+
const g = safe[c] ?? 0;
|
|
10059
|
+
const desc = GS_GRADE_DESCRIPTIONS[c][g] ?? "\u2014";
|
|
10060
|
+
return /* @__PURE__ */ jsxs("tr", { className: "border-b border-[#D0D0D0]/80 last:border-0", children: [
|
|
10061
|
+
/* @__PURE__ */ jsx("td", { className: "px-3 py-2 font-medium", children: GS_CONDITION_LABELS[c] }),
|
|
10062
|
+
/* @__PURE__ */ jsx("td", { className: "px-2 py-1.5 align-middle", children: /* @__PURE__ */ jsxs(
|
|
10063
|
+
Select,
|
|
10064
|
+
{
|
|
10065
|
+
value: String(g),
|
|
10066
|
+
onValueChange: (v) => setGrade(c, v),
|
|
10067
|
+
disabled,
|
|
10068
|
+
children: [
|
|
10069
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
10070
|
+
/* @__PURE__ */ jsx(SelectContent, { children: [0, 1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsx(SelectItem, { value: String(n), children: n === 0 ? "\u2014" : String(n) }, n)) })
|
|
10071
|
+
]
|
|
10072
|
+
}
|
|
10073
|
+
) }),
|
|
10074
|
+
/* @__PURE__ */ jsx("td", { className: "px-3 py-2 text-muted-foreground", children: desc })
|
|
10075
|
+
] }, c);
|
|
10076
|
+
}) })
|
|
10077
|
+
] }) }) }),
|
|
10078
|
+
showError ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
10079
|
+
] });
|
|
10080
|
+
};
|
|
10081
|
+
function isFlagSelected(selected, optValue) {
|
|
10082
|
+
return selected.some((v) => v === optValue || String(v) === String(optValue));
|
|
10083
|
+
}
|
|
10084
|
+
var PainScaleFlagsWidget = ({ fieldId }) => {
|
|
10085
|
+
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
10086
|
+
const { state } = useForm();
|
|
10087
|
+
const showError = !!error && (touched || state.submitAttempted);
|
|
10088
|
+
if (!fieldDef || fieldDef.type !== "pain_scale_flags") return null;
|
|
10089
|
+
const def = fieldDef;
|
|
10090
|
+
const min = def.min ?? 0;
|
|
10091
|
+
const max = def.max ?? 10;
|
|
10092
|
+
const step = def.step ?? 1;
|
|
10093
|
+
const flagOptions = def.options ?? [];
|
|
10094
|
+
const safe = useMemo(
|
|
10095
|
+
() => normalizePainScaleFlags(value, { min, max }),
|
|
10096
|
+
[value, min, max]
|
|
10097
|
+
);
|
|
10098
|
+
const theme = getThemeConfig("textarea", def.theme);
|
|
10099
|
+
const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
|
|
10100
|
+
const labelClass = theme?.labelClassName;
|
|
10101
|
+
const update = (next) => {
|
|
10102
|
+
setValue(normalizePainScaleFlags(next, { min, max }));
|
|
10103
|
+
setTouched();
|
|
10104
|
+
};
|
|
10105
|
+
const toggleFlag = (optValue) => {
|
|
10106
|
+
const sel = safe.flags;
|
|
10107
|
+
const isSelected = isFlagSelected(sel, optValue);
|
|
10108
|
+
const nextFlags = isSelected ? sel.filter((v) => v !== optValue && String(v) !== String(optValue)) : [...sel, String(optValue)];
|
|
10109
|
+
update({ pain: safe.pain, flags: nextFlags });
|
|
10110
|
+
};
|
|
10111
|
+
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10112
|
+
def.label,
|
|
10113
|
+
" ",
|
|
10114
|
+
def.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
10115
|
+
] });
|
|
10116
|
+
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { children: labelContent });
|
|
10117
|
+
const bodyClass = cn(
|
|
10118
|
+
"-mt-1 flex min-w-0 flex-col border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
10119
|
+
disabled && "pointer-events-none opacity-60"
|
|
10120
|
+
);
|
|
10121
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(wrapperClass, "h-full min-h-0 flex flex-col"), children: [
|
|
10122
|
+
labelEl,
|
|
10123
|
+
def.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: def.description }),
|
|
10124
|
+
/* @__PURE__ */ jsx("div", { className: cn(bodyClass, "min-h-0 flex-1"), children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-3", children: [
|
|
10125
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
10126
|
+
/* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium text-slate-700", children: [
|
|
10127
|
+
"Pain score (VAS)",
|
|
10128
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-2 font-normal tabular-nums text-muted-foreground", children: [
|
|
10129
|
+
safe.pain,
|
|
10130
|
+
"/",
|
|
10131
|
+
max
|
|
10132
|
+
] })
|
|
10133
|
+
] }),
|
|
10134
|
+
/* @__PURE__ */ jsx(
|
|
10135
|
+
Slider,
|
|
10136
|
+
{
|
|
10137
|
+
className: cn("py-1", showError && "rounded opacity-90 ring-1 ring-red-500"),
|
|
10138
|
+
disabled,
|
|
10139
|
+
min,
|
|
10140
|
+
max,
|
|
10141
|
+
step,
|
|
10142
|
+
value: [safe.pain],
|
|
10143
|
+
onValueChange: (v) => {
|
|
10144
|
+
const n = v[0] ?? min;
|
|
10145
|
+
update({ pain: n, flags: safe.flags });
|
|
10146
|
+
}
|
|
10147
|
+
}
|
|
10148
|
+
)
|
|
10149
|
+
] }),
|
|
10150
|
+
flagOptions.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1.5", children: [
|
|
10151
|
+
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium text-slate-700", children: "Triage flags" }),
|
|
10152
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-x-4 gap-y-2", children: flagOptions.map((opt) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10153
|
+
/* @__PURE__ */ jsx(
|
|
10154
|
+
Checkbox,
|
|
10155
|
+
{
|
|
10156
|
+
id: `${fieldId}-flag-${String(opt.value)}`,
|
|
10157
|
+
checked: isFlagSelected(safe.flags, opt.value),
|
|
10158
|
+
onCheckedChange: () => toggleFlag(opt.value),
|
|
10159
|
+
disabled
|
|
10160
|
+
}
|
|
10161
|
+
),
|
|
10162
|
+
/* @__PURE__ */ jsx(
|
|
10163
|
+
Label,
|
|
10164
|
+
{
|
|
10165
|
+
htmlFor: `${fieldId}-flag-${String(opt.value)}`,
|
|
10166
|
+
className: "cursor-pointer text-sm font-normal leading-none",
|
|
10167
|
+
children: opt.label
|
|
10168
|
+
}
|
|
10169
|
+
)
|
|
10170
|
+
] }, String(opt.value))) })
|
|
10171
|
+
] }) : null
|
|
10172
|
+
] }) }),
|
|
10173
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
10174
|
+
] });
|
|
10175
|
+
};
|
|
10176
|
+
var FieldRenderer = ({ fieldId }) => {
|
|
10177
|
+
const { fieldDef, visible } = useField(fieldId);
|
|
10178
|
+
if (!visible || !fieldDef) {
|
|
10179
|
+
return null;
|
|
10180
|
+
}
|
|
10181
|
+
return renderWidget(fieldId, fieldDef);
|
|
10182
|
+
};
|
|
10183
|
+
function renderWidget(fieldId, fieldDef) {
|
|
10184
|
+
switch (fieldDef.type) {
|
|
10185
|
+
case "text":
|
|
10186
|
+
case "number":
|
|
10187
|
+
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
10188
|
+
case "slider":
|
|
10189
|
+
return /* @__PURE__ */ jsx(SliderWidget, { fieldId });
|
|
10190
|
+
case "textarea":
|
|
10191
|
+
if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
|
|
10192
|
+
return /* @__PURE__ */ jsx(MarMedicationOrdersWidget, { fieldId });
|
|
10193
|
+
}
|
|
10194
|
+
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
10195
|
+
case "richtext":
|
|
10196
|
+
return /* @__PURE__ */ jsx(RichTextWidget, { fieldId });
|
|
10197
|
+
case "date":
|
|
10198
|
+
return /* @__PURE__ */ jsx(DateWidget, { fieldId });
|
|
10199
|
+
case "datetime":
|
|
10200
|
+
return /* @__PURE__ */ jsx(DateTimeWidget, { fieldId });
|
|
10201
|
+
case "select":
|
|
10202
|
+
return /* @__PURE__ */ jsx(SelectWidget, { fieldId });
|
|
10203
|
+
case "radio":
|
|
10204
|
+
return /* @__PURE__ */ jsx(RadioWidget, { fieldId });
|
|
10205
|
+
case "checkbox":
|
|
10206
|
+
return /* @__PURE__ */ jsx(CheckboxWidget, { fieldId });
|
|
10207
|
+
case "multiselect":
|
|
10208
|
+
return /* @__PURE__ */ jsx(MultiSelectWidget, { fieldId });
|
|
10209
|
+
case "repeatable":
|
|
10210
|
+
return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
|
|
10211
|
+
case "image_upload":
|
|
10212
|
+
return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
|
|
10213
|
+
case "media_upload":
|
|
10214
|
+
return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
|
|
10215
|
+
case "signature":
|
|
10216
|
+
return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
|
|
10217
|
+
case "editable_table":
|
|
10218
|
+
return /* @__PURE__ */ jsx(EditableTableWidget, { fieldId });
|
|
10219
|
+
case "medications":
|
|
10220
|
+
return /* @__PURE__ */ jsx(AddMedicationWidget, { fieldId });
|
|
10221
|
+
case "discharge_medication_orders":
|
|
10222
|
+
return /* @__PURE__ */ jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
10223
|
+
case "investigations":
|
|
10224
|
+
return /* @__PURE__ */ jsx(AddInvestigationWidget, { fieldId });
|
|
10225
|
+
case "procedures":
|
|
10226
|
+
return /* @__PURE__ */ jsx(AddProcedureWidget, { fieldId });
|
|
10227
|
+
case "differential_diagnosis":
|
|
10228
|
+
return /* @__PURE__ */ jsx(DifferentialDiagnosisWidget, { fieldId });
|
|
10229
|
+
case "vitals":
|
|
10230
|
+
return /* @__PURE__ */ jsx(VitalsWidget, { fieldId });
|
|
10231
|
+
case "hidden_vitals":
|
|
10232
|
+
return /* @__PURE__ */ jsx(HiddenVitalsWidget, { fieldId });
|
|
10233
|
+
case "referral":
|
|
10234
|
+
return /* @__PURE__ */ jsx(ReferralWidget, { fieldId });
|
|
10235
|
+
case "followup":
|
|
10236
|
+
return /* @__PURE__ */ jsx(FollowupWidget, { fieldId });
|
|
10237
|
+
case "smart_textarea":
|
|
10238
|
+
return /* @__PURE__ */ jsx(SmartTextareaWidget, { fieldId });
|
|
10239
|
+
case "diagnosis_textarea":
|
|
10240
|
+
return /* @__PURE__ */ jsx(DiagnosisTextareaWidget, { fieldId });
|
|
10241
|
+
case "obstetric_history":
|
|
10242
|
+
return /* @__PURE__ */ jsx(ObstetricHistoryWidget, { fieldId });
|
|
10243
|
+
case "eye_prescription":
|
|
10244
|
+
return /* @__PURE__ */ jsx(OphthalmologyWidget, { fieldId });
|
|
10245
|
+
case "ophthal_diagnosis":
|
|
10246
|
+
return /* @__PURE__ */ jsx(OphthalDiagnosisWidget, { fieldId });
|
|
10247
|
+
case "orthopedic_exam":
|
|
10248
|
+
return /* @__PURE__ */ jsx(OrthopedicExamWidget, { fieldId });
|
|
10249
|
+
case "general_surgery_smart_history":
|
|
10250
|
+
return /* @__PURE__ */ jsx(GsSmartHistoryWidget, { fieldId });
|
|
10251
|
+
case "general_surgery_examination":
|
|
10252
|
+
return /* @__PURE__ */ jsx(GsExaminationWidget, { fieldId });
|
|
10253
|
+
case "general_surgery_grading":
|
|
10254
|
+
return /* @__PURE__ */ jsx(GsGradingWidget, { fieldId });
|
|
10255
|
+
case "pain_scale_flags":
|
|
10256
|
+
return /* @__PURE__ */ jsx(PainScaleFlagsWidget, { fieldId });
|
|
10257
|
+
case "toggle": {
|
|
10258
|
+
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
10259
|
+
const store = useFormStore();
|
|
10260
|
+
const excludes = fieldDef.excludes ?? [];
|
|
10261
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
10262
|
+
/* @__PURE__ */ jsx(
|
|
10263
|
+
Switch,
|
|
10264
|
+
{
|
|
10265
|
+
checked: value === true,
|
|
10266
|
+
disabled,
|
|
10267
|
+
onCheckedChange: (checked) => {
|
|
10268
|
+
setValue(checked);
|
|
10269
|
+
setTouched();
|
|
10270
|
+
if (checked) excludes.forEach((id) => store.setValue(id, false));
|
|
10271
|
+
}
|
|
10272
|
+
}
|
|
10273
|
+
),
|
|
10274
|
+
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
|
|
10275
|
+
] });
|
|
10276
|
+
}
|
|
10277
|
+
case "suggestion_textarea":
|
|
10278
|
+
case "complaint_chips":
|
|
10279
|
+
return /* @__PURE__ */ jsx(SuggestionTextareaWidget, { fieldId });
|
|
10280
|
+
case "lens_assessment":
|
|
10281
|
+
return /* @__PURE__ */ jsx(LensAssessmentWidget, { fieldId });
|
|
10282
|
+
case "functional_impairment_score":
|
|
10283
|
+
return /* @__PURE__ */ jsx(FunctionalImpairmentScoreWidget, { fieldId });
|
|
10284
|
+
case "biometry_iol_workup":
|
|
10285
|
+
return /* @__PURE__ */ jsx(BiometryIolWorkupWidget, { fieldId });
|
|
10286
|
+
case "surgical_risk_flags":
|
|
10287
|
+
return /* @__PURE__ */ jsx(SurgicalRiskFlagsWidget, { fieldId });
|
|
10288
|
+
case "static_text": {
|
|
10289
|
+
const def = fieldDef;
|
|
10290
|
+
const size = def.size ?? "regular";
|
|
10291
|
+
const labelClass = size === "large" ? "text-base" : "text-sm";
|
|
10292
|
+
const descClass = size === "large" ? "text-sm" : "text-xs";
|
|
10293
|
+
return /* @__PURE__ */ jsxs("div", { className: `${labelClass} text-muted-foreground`, children: [
|
|
10294
|
+
def.label,
|
|
10295
|
+
def.description && /* @__PURE__ */ jsx("p", { className: `mt-1 ${descClass} opacity-90`, children: def.description })
|
|
10296
|
+
] });
|
|
10297
|
+
}
|
|
10298
|
+
default:
|
|
10299
|
+
return /* @__PURE__ */ jsxs("div", { className: "text-red-500", children: [
|
|
10300
|
+
"Unknown field type: ",
|
|
10301
|
+
fieldDef.type
|
|
10302
|
+
] });
|
|
10303
|
+
}
|
|
10304
|
+
}
|
|
10305
|
+
var Section = ({ title, children }) => {
|
|
10306
|
+
const [expanded, setExpanded] = useState(true);
|
|
10307
|
+
const handleToggle = () => setExpanded((prev) => !prev);
|
|
10308
|
+
const contentClassName = cn(
|
|
10309
|
+
"overflow-hidden transition-[height] duration-200 ease-in-out",
|
|
10310
|
+
!expanded && "hidden"
|
|
10311
|
+
);
|
|
10312
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-6 border rounded-lg bg-white shadow-sm overflow-hidden", children: [
|
|
10313
|
+
/* @__PURE__ */ jsxs(
|
|
10314
|
+
"button",
|
|
10315
|
+
{
|
|
10316
|
+
type: "button",
|
|
10317
|
+
onClick: handleToggle,
|
|
10318
|
+
className: "w-full flex items-center justify-between gap-2 p-4 text-left border-b hover:bg-gray-50/80 transition-colors",
|
|
10319
|
+
children: [
|
|
10320
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium", children: title }),
|
|
10321
|
+
/* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-muted-foreground", "aria-hidden": true, children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5" }) })
|
|
10322
|
+
]
|
|
10323
|
+
}
|
|
10324
|
+
),
|
|
10325
|
+
/* @__PURE__ */ jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsx("div", { className: "p-4 pt-4 space-y-4 border-t-0", children }) })
|
|
10326
|
+
] });
|
|
10327
|
+
};
|
|
10328
|
+
var ColumnLayout = ({
|
|
10329
|
+
columns,
|
|
10330
|
+
label,
|
|
10331
|
+
children
|
|
10332
|
+
}) => {
|
|
10333
|
+
const gridCols = Math.max(1, Math.min(columns, 12));
|
|
10334
|
+
const gridClass = `grid gap-4 w-full`;
|
|
10335
|
+
const style = {
|
|
10336
|
+
gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))`
|
|
10337
|
+
};
|
|
10338
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
10339
|
+
label != null && label !== "" && /* @__PURE__ */ jsx("div", { className: "mb-2 text-sm font-medium text-gray-700", children: label }),
|
|
10340
|
+
/* @__PURE__ */ jsx("div", { className: gridClass, style, children })
|
|
9067
10341
|
] });
|
|
9068
10342
|
};
|
|
9069
10343
|
var DynamicForm = () => {
|
|
@@ -9215,14 +10489,24 @@ var SmartForm = ({
|
|
|
9215
10489
|
if (position !== "left") return null;
|
|
9216
10490
|
return /* @__PURE__ */ jsx(FieldRenderer, { fieldId }, fieldId);
|
|
9217
10491
|
}) }),
|
|
9218
|
-
/* @__PURE__ */ jsx("div", { className: "col-span-2 grid grid-cols-2 gap-
|
|
10492
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2 grid grid-cols-2 gap-2", children: fieldIds.map((fieldId) => {
|
|
9219
10493
|
const fieldDef = store.getFieldDef(fieldId);
|
|
9220
10494
|
if (!fieldDef) return null;
|
|
9221
10495
|
const position = fieldDef.position ?? "center";
|
|
9222
10496
|
if (position !== "center") return null;
|
|
9223
10497
|
const colSpanRaw = fieldDef.colSpan ?? 1;
|
|
9224
10498
|
const colSpan = colSpanRaw === 2 ? 2 : 1;
|
|
9225
|
-
return /* @__PURE__ */ jsx(
|
|
10499
|
+
return /* @__PURE__ */ jsx(
|
|
10500
|
+
"div",
|
|
10501
|
+
{
|
|
10502
|
+
className: cn(
|
|
10503
|
+
"min-h-0 flex flex-col",
|
|
10504
|
+
colSpan === 2 ? "col-span-2" : "col-span-1 h-full"
|
|
10505
|
+
),
|
|
10506
|
+
children: /* @__PURE__ */ jsx(FieldRenderer, { fieldId })
|
|
10507
|
+
},
|
|
10508
|
+
fieldId
|
|
10509
|
+
);
|
|
9226
10510
|
}) }),
|
|
9227
10511
|
/* @__PURE__ */ jsx("div", { className: "col-span-1 flex flex-col gap-2", children: fieldIds.map((fieldId) => {
|
|
9228
10512
|
const fieldDef = store.getFieldDef(fieldId);
|
|
@@ -9670,11 +10954,17 @@ var ReadOnlyDischargeMedicationOrders = ({ fieldDef, value }) => {
|
|
|
9670
10954
|
}) })
|
|
9671
10955
|
] });
|
|
9672
10956
|
};
|
|
9673
|
-
var ReadOnlyFieldRenderer = ({
|
|
10957
|
+
var ReadOnlyFieldRenderer = ({
|
|
10958
|
+
fieldDef,
|
|
10959
|
+
value,
|
|
10960
|
+
allValues,
|
|
10961
|
+
resolveFieldDef
|
|
10962
|
+
}) => {
|
|
9674
10963
|
if (!fieldDef) return null;
|
|
9675
10964
|
switch (fieldDef.type) {
|
|
9676
10965
|
case "text":
|
|
9677
10966
|
case "number":
|
|
10967
|
+
case "slider":
|
|
9678
10968
|
case "textarea":
|
|
9679
10969
|
case "richtext":
|
|
9680
10970
|
return /* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value });
|
|
@@ -9712,8 +11002,30 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
|
9712
11002
|
] });
|
|
9713
11003
|
}
|
|
9714
11004
|
case "suggestion_textarea":
|
|
9715
|
-
case "complaint_chips":
|
|
9716
|
-
|
|
11005
|
+
case "complaint_chips": {
|
|
11006
|
+
const embeddedIds = fieldDef.meta && Array.isArray(fieldDef.meta.embeddedFieldIds) ? fieldDef.meta.embeddedFieldIds.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim()) : [];
|
|
11007
|
+
const showEmbedded = embeddedIds.length > 0 && resolveFieldDef && allValues && typeof allValues === "object";
|
|
11008
|
+
if (!showEmbedded) {
|
|
11009
|
+
return /* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value });
|
|
11010
|
+
}
|
|
11011
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
11012
|
+
/* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value }),
|
|
11013
|
+
/* @__PURE__ */ jsx("div", { className: "grid gap-3 border-t border-muted-foreground/20 pt-3 sm:grid-cols-3", children: embeddedIds.map((id) => {
|
|
11014
|
+
const fd = resolveFieldDef(id);
|
|
11015
|
+
if (!fd) return null;
|
|
11016
|
+
return /* @__PURE__ */ jsx(
|
|
11017
|
+
ReadOnlyFieldRenderer,
|
|
11018
|
+
{
|
|
11019
|
+
fieldDef: fd,
|
|
11020
|
+
value: allValues[id],
|
|
11021
|
+
allValues,
|
|
11022
|
+
resolveFieldDef
|
|
11023
|
+
},
|
|
11024
|
+
id
|
|
11025
|
+
);
|
|
11026
|
+
}) })
|
|
11027
|
+
] });
|
|
11028
|
+
}
|
|
9717
11029
|
case "lens_assessment": {
|
|
9718
11030
|
const v = value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
9719
11031
|
const notes = typeof v?.notes === "string" ? v.notes : "";
|
|
@@ -9789,6 +11101,44 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
|
|
|
9789
11101
|
const lines = [`Right eye (OD): ${od}`, `Left eye (OS): ${os}`].join("\n");
|
|
9790
11102
|
return /* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value: lines });
|
|
9791
11103
|
}
|
|
11104
|
+
case "pain_scale_flags": {
|
|
11105
|
+
const def = fieldDef;
|
|
11106
|
+
const min = def.min ?? 0;
|
|
11107
|
+
const max = def.max ?? 10;
|
|
11108
|
+
const safe = normalizePainScaleFlags(value, { min, max });
|
|
11109
|
+
const opts = def.options ?? [];
|
|
11110
|
+
const flagLabels = safe.flags.map((fv) => {
|
|
11111
|
+
const o = opts.find((x) => x.value === fv || String(x.value) === String(fv));
|
|
11112
|
+
return o?.label ?? fv;
|
|
11113
|
+
});
|
|
11114
|
+
const lines = [
|
|
11115
|
+
`Pain score (VAS): ${safe.pain}/${max}`,
|
|
11116
|
+
flagLabels.length > 0 ? `Triage flags: ${flagLabels.join(", ")}` : "Triage flags: \u2014"
|
|
11117
|
+
].join("\n");
|
|
11118
|
+
return /* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value: lines });
|
|
11119
|
+
}
|
|
11120
|
+
case "general_surgery_smart_history":
|
|
11121
|
+
case "general_surgery_grading":
|
|
11122
|
+
return /* @__PURE__ */ jsx(
|
|
11123
|
+
ReadOnlyText,
|
|
11124
|
+
{
|
|
11125
|
+
fieldDef,
|
|
11126
|
+
value: value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value)
|
|
11127
|
+
}
|
|
11128
|
+
);
|
|
11129
|
+
case "general_surgery_examination": {
|
|
11130
|
+
const structuredDisplay = value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value);
|
|
11131
|
+
const clinicalDef = resolveFieldDef?.("clinical_examination");
|
|
11132
|
+
const clinicalRaw = allValues?.["clinical_examination"];
|
|
11133
|
+
const clinicalStr = typeof clinicalRaw === "string" ? clinicalRaw : clinicalRaw != null && clinicalRaw !== "" ? String(clinicalRaw) : "";
|
|
11134
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
11135
|
+
/* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value: structuredDisplay }),
|
|
11136
|
+
clinicalDef ? /* @__PURE__ */ jsx(ReadOnlyText, { fieldDef: clinicalDef, value: clinicalStr }) : clinicalStr ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
11137
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-700", children: "Clinical examination" }),
|
|
11138
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem] whitespace-pre-wrap", children: clinicalStr })
|
|
11139
|
+
] }) : null
|
|
11140
|
+
] });
|
|
11141
|
+
}
|
|
9792
11142
|
case "static_text": {
|
|
9793
11143
|
const def = fieldDef;
|
|
9794
11144
|
const size = def.size ?? "regular";
|
|
@@ -9835,7 +11185,9 @@ var ReadOnlyForm = ({ schema, submission }) => {
|
|
|
9835
11185
|
ReadOnlyFieldRenderer,
|
|
9836
11186
|
{
|
|
9837
11187
|
fieldDef,
|
|
9838
|
-
value: formData[child]
|
|
11188
|
+
value: formData[child],
|
|
11189
|
+
allValues: formData,
|
|
11190
|
+
resolveFieldDef: (id) => fieldMap.get(id)
|
|
9839
11191
|
},
|
|
9840
11192
|
child
|
|
9841
11193
|
) : null;
|
|
@@ -9854,7 +11206,9 @@ var ReadOnlyForm = ({ schema, submission }) => {
|
|
|
9854
11206
|
ReadOnlyFieldRenderer,
|
|
9855
11207
|
{
|
|
9856
11208
|
fieldDef,
|
|
9857
|
-
value: formData[fieldId]
|
|
11209
|
+
value: formData[fieldId],
|
|
11210
|
+
allValues: formData,
|
|
11211
|
+
resolveFieldDef: (id) => fieldMap.get(id)
|
|
9858
11212
|
},
|
|
9859
11213
|
fieldId
|
|
9860
11214
|
))
|
|
@@ -9885,7 +11239,9 @@ var ReadOnlyForm = ({ schema, submission }) => {
|
|
|
9885
11239
|
ReadOnlyFieldRenderer,
|
|
9886
11240
|
{
|
|
9887
11241
|
fieldDef,
|
|
9888
|
-
value: formData[fieldId]
|
|
11242
|
+
value: formData[fieldId],
|
|
11243
|
+
allValues: formData,
|
|
11244
|
+
resolveFieldDef: (id) => fieldMap.get(id)
|
|
9889
11245
|
},
|
|
9890
11246
|
fieldId
|
|
9891
11247
|
))
|