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 CHANGED
@@ -97,6 +97,15 @@ function validateField(value, field) {
97
97
  return `Must be at most ${rules.max}`;
98
98
  }
99
99
  }
100
+ if (field.type === "slider") {
101
+ const num = Number(value);
102
+ if (isNaN(num)) return "Must be a valid number";
103
+ const s = field;
104
+ const min = s.min ?? 0;
105
+ const max = s.max ?? 10;
106
+ if (num < min) return `Must be at least ${min}`;
107
+ if (num > max) return `Must be at most ${max}`;
108
+ }
100
109
  if (typeof value === "string") {
101
110
  if (rules.minLength !== void 0 && value.length < rules.minLength) {
102
111
  return `Must be at least ${rules.minLength} characters`;
@@ -235,6 +244,227 @@ function applyPrefill(currentValues, fields, prefilledData = {}) {
235
244
  return newValues;
236
245
  }
237
246
 
247
+ // src/core/generalSurgeryPathway.ts
248
+ var defaultGeneralSurgerySmartHistory = () => ({
249
+ pain: {
250
+ site: "",
251
+ onset: "",
252
+ character: "",
253
+ radiation: "",
254
+ associated: "",
255
+ timing: "",
256
+ exacerbating: "",
257
+ severity: 0
258
+ },
259
+ swelling: { duration: "", sizeProgression: "", painfulPainless: "", checks: [] },
260
+ gi: { appetite: "", weightLoss: "", bowelHabits: "", checks: [] },
261
+ breast: { lumpDuration: "", nippleDischarge: "", checks: [] },
262
+ ano: { checks: [] },
263
+ thyroid: { swellingDuration: "", checks: [] },
264
+ systemic: ""
265
+ });
266
+ var defaultGeneralSurgeryExamination = () => ({
267
+ general: [],
268
+ regions: [],
269
+ abdomen: {
270
+ inspection: [],
271
+ palpation: [],
272
+ percussion: [],
273
+ massNotes: "",
274
+ bowelSounds: "none"
275
+ },
276
+ hernia: { site: "", reducible: false, coughImpulse: false, tenderness: false },
277
+ breast: { lumpSizeCm: "", mobile: false, skinInvolvement: false, axillaryNodes: false },
278
+ thyroid: { size: "", mobileDeglutition: false, nodules: false, cervicalNodes: false },
279
+ anorectal: { inspection: "", dreDone: false, proctoscopyDone: false, notes: "" },
280
+ limb: { dilatedVeins: false, ulcer: false, oedema: false }
281
+ });
282
+ var ALL_GS_CONDITIONS = [
283
+ "hernia",
284
+ "appendicitis",
285
+ "gallbladder",
286
+ "breast",
287
+ "thyroid",
288
+ "piles",
289
+ "varicose",
290
+ "ulcer"
291
+ ];
292
+ var defaultGeneralSurgeryGrading = () => ({
293
+ hernia: 0,
294
+ appendicitis: 0,
295
+ gallbladder: 0,
296
+ breast: 0,
297
+ thyroid: 0,
298
+ piles: 0,
299
+ varicose: 0,
300
+ ulcer: 0
301
+ });
302
+ var GS_CONDITION_TRIGGERS = {
303
+ hernia: { regions: ["hernia", "abdomen"], chips: ["swelling_lump", "obstruction"] },
304
+ appendicitis: { regions: ["abdomen"], chips: ["pain", "obstruction"] },
305
+ gallbladder: { regions: ["abdomen"], chips: ["pain"] },
306
+ breast: { regions: ["breast"], chips: ["breast", "swelling_lump"] },
307
+ thyroid: { regions: ["thyroid"], chips: ["thyroid", "swelling_lump"] },
308
+ piles: { regions: ["anorectal"], chips: ["anorectal", "bleeding"] },
309
+ varicose: { regions: ["limb"], chips: ["swelling_lump"] },
310
+ ulcer: { regions: ["limb", "anorectal"], chips: ["ulcer_wound", "discharge"] }
311
+ };
312
+ var GS_CONDITION_LABELS = {
313
+ hernia: "Hernia",
314
+ appendicitis: "Appendicitis",
315
+ gallbladder: "Gallbladder disease",
316
+ breast: "Breast lump (BIRADS)",
317
+ thyroid: "Thyroid nodule (TIRADS)",
318
+ piles: "Haemorrhoids",
319
+ varicose: "Varicose veins (CEAP)",
320
+ ulcer: "Ulcer / wound"
321
+ };
322
+ var GS_GRADE_DESCRIPTIONS = {
323
+ hernia: ["\u2014", "Small reducible", "Large reducible", "Irreducible", "Obstructed", "Strangulated"],
324
+ appendicitis: ["\u2014", "Mild (clinical)", "Confirmed (USG/CT)", "Complicated (mass)", "Abscess", "Perforation"],
325
+ gallbladder: ["\u2014", "Asymptomatic stones", "Symptomatic", "Acute cholecystitis", "Complicated (CBD stone)", "Perforation/empyema"],
326
+ breast: ["\u2014", "BIRADS 1 \u2014 Negative", "BIRADS 2 \u2014 Benign", "BIRADS 3 \u2014 Probably benign", "BIRADS 4 \u2014 Suspicious", "BIRADS 5 \u2014 Malignant"],
327
+ thyroid: ["\u2014", "TIRADS 1 \u2014 Normal", "TIRADS 2 \u2014 Benign", "TIRADS 3 \u2014 Indeterminate", "TIRADS 4 \u2014 Suspicious", "TIRADS 5 \u2014 Highly suspicious"],
328
+ piles: ["\u2014", "Grade 1", "Grade 2", "Grade 3", "Grade 4", "Grade 5"],
329
+ varicose: ["\u2014", "C1 telangiectasia", "C2 varicose", "C3 oedema", "C4 skin changes", "C5-C6 ulcer"],
330
+ ulcer: ["\u2014", "Superficial", "Deep", "Infected", "Necrotic", "Gangrene"]
331
+ };
332
+ function normalizeGeneralSurgerySmartHistory(raw) {
333
+ const d = defaultGeneralSurgerySmartHistory();
334
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
335
+ const v = raw;
336
+ const painIn = v.pain && typeof v.pain === "object" ? v.pain : {};
337
+ const sev = Number(painIn.severity);
338
+ const pain = {
339
+ ...d.pain,
340
+ ...painIn,
341
+ severity: Number.isFinite(sev) ? Math.min(10, Math.max(0, Math.round(sev))) : d.pain.severity
342
+ };
343
+ const str2 = (x) => typeof x === "string" ? x : "";
344
+ const strArr = (x) => Array.isArray(x) ? x.filter((i) => typeof i === "string") : [];
345
+ const swell = v.swelling && typeof v.swelling === "object" ? v.swelling : {};
346
+ const gi = v.gi && typeof v.gi === "object" ? v.gi : {};
347
+ const breast = v.breast && typeof v.breast === "object" ? v.breast : {};
348
+ const ano = v.ano && typeof v.ano === "object" ? v.ano : {};
349
+ const thy = v.thyroid && typeof v.thyroid === "object" ? v.thyroid : {};
350
+ return {
351
+ pain,
352
+ swelling: {
353
+ duration: str2(swell.duration),
354
+ sizeProgression: str2(swell.sizeProgression),
355
+ painfulPainless: str2(swell.painfulPainless),
356
+ checks: strArr(swell.checks)
357
+ },
358
+ gi: {
359
+ appetite: str2(gi.appetite),
360
+ weightLoss: str2(gi.weightLoss),
361
+ bowelHabits: str2(gi.bowelHabits),
362
+ checks: strArr(gi.checks)
363
+ },
364
+ breast: {
365
+ lumpDuration: str2(breast.lumpDuration),
366
+ nippleDischarge: str2(breast.nippleDischarge),
367
+ checks: strArr(breast.checks)
368
+ },
369
+ ano: { checks: strArr(ano.checks) },
370
+ thyroid: {
371
+ swellingDuration: str2(thy.swellingDuration),
372
+ checks: strArr(thy.checks)
373
+ },
374
+ systemic: typeof v.systemic === "string" ? v.systemic : d.systemic
375
+ };
376
+ }
377
+ function normalizeGeneralSurgeryExamination(raw) {
378
+ const d = defaultGeneralSurgeryExamination();
379
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
380
+ const v = raw;
381
+ const strArr = (x) => Array.isArray(x) ? x.filter((i) => typeof i === "string") : [];
382
+ const ab = v.abdomen && typeof v.abdomen === "object" ? v.abdomen : {};
383
+ const bowel = ab.bowelSounds;
384
+ const bowels = bowel === "normal" || bowel === "up" || bowel === "down" || bowel === "absent" ? bowel : "none";
385
+ const hb = v.hernia && typeof v.hernia === "object" ? v.hernia : {};
386
+ const br = v.breast && typeof v.breast === "object" ? v.breast : {};
387
+ const th = v.thyroid && typeof v.thyroid === "object" ? v.thyroid : {};
388
+ const ar = v.anorectal && typeof v.anorectal === "object" ? v.anorectal : {};
389
+ const lm = v.limb && typeof v.limb === "object" ? v.limb : {};
390
+ const bool = (x) => x === true;
391
+ return {
392
+ general: strArr(v.general),
393
+ regions: strArr(v.regions),
394
+ abdomen: {
395
+ inspection: strArr(ab.inspection),
396
+ palpation: strArr(ab.palpation),
397
+ percussion: strArr(ab.percussion),
398
+ massNotes: typeof ab.massNotes === "string" ? ab.massNotes : d.abdomen.massNotes,
399
+ bowelSounds: bowels
400
+ },
401
+ hernia: {
402
+ site: typeof hb.site === "string" ? hb.site : "",
403
+ reducible: bool(hb.reducible),
404
+ coughImpulse: bool(hb.coughImpulse),
405
+ tenderness: bool(hb.tenderness)
406
+ },
407
+ breast: {
408
+ lumpSizeCm: typeof br.lumpSizeCm === "string" ? br.lumpSizeCm : "",
409
+ mobile: bool(br.mobile),
410
+ skinInvolvement: bool(br.skinInvolvement),
411
+ axillaryNodes: bool(br.axillaryNodes)
412
+ },
413
+ thyroid: {
414
+ size: typeof th.size === "string" ? th.size : "",
415
+ mobileDeglutition: bool(th.mobileDeglutition),
416
+ nodules: bool(th.nodules),
417
+ cervicalNodes: bool(th.cervicalNodes)
418
+ },
419
+ anorectal: {
420
+ inspection: typeof ar.inspection === "string" ? ar.inspection : "",
421
+ dreDone: bool(ar.dreDone),
422
+ proctoscopyDone: bool(ar.proctoscopyDone),
423
+ notes: typeof ar.notes === "string" ? ar.notes : ""
424
+ },
425
+ limb: {
426
+ dilatedVeins: bool(lm.dilatedVeins),
427
+ ulcer: bool(lm.ulcer),
428
+ oedema: bool(lm.oedema)
429
+ }
430
+ };
431
+ }
432
+ function normalizeGeneralSurgeryGrading(raw) {
433
+ const d = defaultGeneralSurgeryGrading();
434
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
435
+ const v = raw;
436
+ const out = { ...d };
437
+ for (const k of ALL_GS_CONDITIONS) {
438
+ const n = Number(v[k]);
439
+ if (Number.isFinite(n) && n >= 0 && n <= 5) out[k] = Math.round(n);
440
+ }
441
+ return out;
442
+ }
443
+ function gsGradingRowVisible(cond, chips, regions, grade) {
444
+ if (grade > 0) return true;
445
+ const t = GS_CONDITION_TRIGGERS[cond];
446
+ if (t.chips.some((c) => chips.includes(c))) return true;
447
+ if (t.regions.some((r) => regions.includes(r))) return true;
448
+ return false;
449
+ }
450
+
451
+ // src/core/painScaleFlags.ts
452
+ function normalizePainScaleFlags(raw, bounds) {
453
+ const min = bounds?.min ?? 0;
454
+ const max = bounds?.max ?? 10;
455
+ let pain = min;
456
+ let flags = [];
457
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
458
+ const o = raw;
459
+ const p = Number(o.pain);
460
+ if (Number.isFinite(p)) pain = Math.min(max, Math.max(min, p));
461
+ if (Array.isArray(o.flags)) {
462
+ flags = o.flags.filter((x) => typeof x === "string");
463
+ }
464
+ }
465
+ return { pain, flags };
466
+ }
467
+
238
468
  // src/core/store.ts
239
469
  var FormStore = class {
240
470
  state;
@@ -321,7 +551,22 @@ var FormStore = class {
321
551
  else if (field.type === "surgical_risk_flags")
322
552
  values[field.id] = { OD: [], OS: [] };
323
553
  else if (field.type === "toggle") values[field.id] = false;
324
- else values[field.id] = null;
554
+ else if (field.type === "slider") {
555
+ const s = field;
556
+ values[field.id] = s.defaultValue ?? s.min ?? 0;
557
+ } else if (field.type === "general_surgery_smart_history") {
558
+ values[field.id] = field.defaultValue ?? defaultGeneralSurgerySmartHistory();
559
+ } else if (field.type === "general_surgery_examination") {
560
+ values[field.id] = field.defaultValue ?? defaultGeneralSurgeryExamination();
561
+ } else if (field.type === "general_surgery_grading") {
562
+ values[field.id] = field.defaultValue ?? defaultGeneralSurgeryGrading();
563
+ } else if (field.type === "pain_scale_flags") {
564
+ const f = field;
565
+ values[field.id] = normalizePainScaleFlags(
566
+ f.defaultValue ?? { pain: f.min ?? 0, flags: [] },
567
+ { min: f.min, max: f.max }
568
+ );
569
+ } else values[field.id] = null;
325
570
  }
326
571
  });
327
572
  this.state.values = values;
@@ -1041,7 +1286,8 @@ var TextWidget = ({ fieldId }) => {
1041
1286
  fieldDef.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
1042
1287
  ] });
1043
1288
  const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: fieldId, className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: fieldId, children: labelContent });
1044
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClass, children: [
1289
+ const placeholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : void 0;
1290
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(wrapperClass, isTextarea && "flex h-full min-h-0 flex-col"), children: [
1045
1291
  hasVoice ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1046
1292
  labelEl,
1047
1293
  /* @__PURE__ */ jsxRuntime.jsx(VoiceMicButton, { fieldId, onTranscriptReady: setValue })
@@ -1055,7 +1301,8 @@ var TextWidget = ({ fieldId }) => {
1055
1301
  onBlur: setTouched,
1056
1302
  disabled,
1057
1303
  type: fieldDef.type === "number" ? "number" : "text",
1058
- className: inputClass,
1304
+ className: cn(inputClass, isTextarea && height == null && "min-h-[80px] flex-1"),
1305
+ placeholder,
1059
1306
  ...isTextarea && { height }
1060
1307
  }
1061
1308
  ),
@@ -1531,6 +1778,8 @@ var SelectWidget = ({ fieldId }) => {
1531
1778
  }
1532
1779
  }, [fieldDef]);
1533
1780
  if (!fieldDef) return null;
1781
+ const schemaPlaceholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : void 0;
1782
+ const selectPlaceholder = loading ? "Loading..." : schemaPlaceholder ?? "Select...";
1534
1783
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1535
1784
  /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: fieldId, children: [
1536
1785
  fieldDef.label,
@@ -1548,7 +1797,7 @@ var SelectWidget = ({ fieldId }) => {
1548
1797
  setTouched();
1549
1798
  },
1550
1799
  children: [
1551
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: fieldId, className: showError ? "border-red-500" : "", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: loading ? "Loading..." : "Select..." }) }),
1800
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: fieldId, className: showError ? "border-red-500" : "", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: selectPlaceholder }) }),
1552
1801
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(opt.value), children: opt.label }, String(opt.value))) })
1553
1802
  ]
1554
1803
  }
@@ -8069,6 +8318,21 @@ function parallelChipArraysEqual(a, b) {
8069
8318
  function isSuggestionField(type) {
8070
8319
  return type === "suggestion_textarea" || type === "complaint_chips";
8071
8320
  }
8321
+ function EmbeddedSchemaField({ fieldId }) {
8322
+ const store = useFormStore();
8323
+ const fieldDef = store.getFieldDef(fieldId);
8324
+ if (!fieldDef) return null;
8325
+ switch (fieldDef.type) {
8326
+ case "text":
8327
+ case "number":
8328
+ case "textarea":
8329
+ return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
8330
+ case "select":
8331
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectWidget, { fieldId });
8332
+ default:
8333
+ return null;
8334
+ }
8335
+ }
8072
8336
  var SuggestionTextareaWidget = ({ fieldId }) => {
8073
8337
  const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
8074
8338
  const { state } = useForm();
@@ -8080,6 +8344,10 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
8080
8344
  const def = fieldDef && isSuggestionField(fieldDef.type) ? fieldDef : void 0;
8081
8345
  const textValue = value == null || typeof value === "string" ? value || "" : String(value);
8082
8346
  const parallelChipFieldId = def?.meta && typeof def.meta.parallelChipFieldId === "string" ? def.meta.parallelChipFieldId.trim() : void 0;
8347
+ const embeddedFieldIds = React15.useMemo(() => {
8348
+ const raw = def?.meta && Array.isArray(def.meta.embeddedFieldIds) ? def.meta.embeddedFieldIds : [];
8349
+ return raw.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim()).filter((id) => store.getFieldDef(id));
8350
+ }, [def?.meta, store]);
8083
8351
  React15.useEffect(() => {
8084
8352
  if (!def) {
8085
8353
  setOptions([]);
@@ -8124,19 +8392,26 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
8124
8392
  setValue(toggleSuggestionTokenInText(textValue, String(optValue), appendSeparator));
8125
8393
  };
8126
8394
  const hasSuggestions = options.length > 0;
8395
+ const hasEmbedded = embeddedFieldIds.length > 0;
8396
+ const hasShell = hasSuggestions || hasEmbedded;
8127
8397
  const isHighlightLabel = def.theme === "highlight-label";
8128
8398
  const suggestionShellClass = cn(
8129
8399
  "flex min-w-0 flex-col overflow-hidden",
8130
- hasSuggestions && (isHighlightLabel ? "-mt-1 rounded-b-md border-[#D0D0D0] bg-white" : "rounded-md border border-input bg-background")
8400
+ hasShell && (isHighlightLabel ? "-mt-1 rounded-b-md border-[#D0D0D0] bg-white" : "rounded-md border border-input bg-background")
8131
8401
  );
8132
8402
  const chipsRowClass = cn(
8133
8403
  "flex flex-wrap gap-2 px-3 pb-2 pt-3",
8134
8404
  hasSuggestions && (isHighlightLabel ? "" : "border-b border-input/70"),
8135
8405
  disabled && "pointer-events-none opacity-50"
8136
8406
  );
8407
+ const embeddedRowClass = cn(
8408
+ "grid gap-3 px-3 sm:grid-cols-3",
8409
+ hasEmbedded && (hasSuggestions ? cn("py-2", isHighlightLabel && "border-t border-input/70") : "border-b border-input/70 py-3"),
8410
+ disabled && "pointer-events-none opacity-50"
8411
+ );
8137
8412
  const textareaShellClass = cn(
8138
8413
  inputClass,
8139
- hasSuggestions && cn(
8414
+ hasShell && cn(
8140
8415
  "mt-0 rounded-t-none rounded-b-md border-0 shadow-none focus-visible:ring-offset-0",
8141
8416
  isHighlightLabel ? "border-t-0" : "min-h-[80px]"
8142
8417
  )
@@ -8163,8 +8438,9 @@ var SuggestionTextareaWidget = ({ fieldId }) => {
8163
8438
  /* @__PURE__ */ jsxRuntime.jsx(VoiceMicButton, { fieldId, onTranscriptReady: setValue })
8164
8439
  ] }) : labelEl,
8165
8440
  def.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: def.description }),
8166
- hasSuggestions ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: suggestionShellClass, children: [
8167
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: chipsRowClass, role: "group", "aria-label": suggestionsAria, children: suggestionButtons }),
8441
+ hasShell ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: suggestionShellClass, children: [
8442
+ hasSuggestions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chipsRowClass, role: "group", "aria-label": suggestionsAria, children: suggestionButtons }),
8443
+ hasEmbedded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: embeddedRowClass, children: embeddedFieldIds.map((id) => /* @__PURE__ */ jsxRuntime.jsx(EmbeddedSchemaField, { fieldId: id }, id)) }),
8168
8444
  /* @__PURE__ */ jsxRuntime.jsx(
8169
8445
  Textarea,
8170
8446
  {
@@ -8944,161 +9220,1159 @@ var SurgicalRiskFlagsWidget = ({ fieldId }) => {
8944
9220
  }
8945
9221
  );
8946
9222
  };
8947
- var FieldRenderer = ({ fieldId }) => {
8948
- const { fieldDef, visible } = useField(fieldId);
8949
- if (!visible || !fieldDef) {
8950
- return null;
8951
- }
8952
- return renderWidget(fieldId, fieldDef);
8953
- };
8954
- function renderWidget(fieldId, fieldDef) {
8955
- switch (fieldDef.type) {
8956
- case "text":
8957
- case "number":
8958
- return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
8959
- case "textarea":
8960
- if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
8961
- return /* @__PURE__ */ jsxRuntime.jsx(MarMedicationOrdersWidget, { fieldId });
8962
- }
8963
- return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
8964
- case "richtext":
8965
- return /* @__PURE__ */ jsxRuntime.jsx(RichTextWidget, { fieldId });
8966
- case "date":
8967
- return /* @__PURE__ */ jsxRuntime.jsx(DateWidget, { fieldId });
8968
- case "datetime":
8969
- return /* @__PURE__ */ jsxRuntime.jsx(DateTimeWidget, { fieldId });
8970
- case "select":
8971
- return /* @__PURE__ */ jsxRuntime.jsx(SelectWidget, { fieldId });
8972
- case "radio":
8973
- return /* @__PURE__ */ jsxRuntime.jsx(RadioWidget, { fieldId });
8974
- case "checkbox":
8975
- return /* @__PURE__ */ jsxRuntime.jsx(CheckboxWidget, { fieldId });
8976
- case "multiselect":
8977
- return /* @__PURE__ */ jsxRuntime.jsx(MultiSelectWidget, { fieldId });
8978
- case "repeatable":
8979
- return /* @__PURE__ */ jsxRuntime.jsx(RepeatableWidget, { fieldId });
8980
- case "image_upload":
8981
- return /* @__PURE__ */ jsxRuntime.jsx(ImageUploadWidget, { fieldId });
8982
- case "media_upload":
8983
- return /* @__PURE__ */ jsxRuntime.jsx(MediaUploadWidget, { fieldId });
8984
- case "signature":
8985
- return /* @__PURE__ */ jsxRuntime.jsx(SignatureUploadWidget, { fieldId });
8986
- case "editable_table":
8987
- return /* @__PURE__ */ jsxRuntime.jsx(EditableTableWidget, { fieldId });
8988
- case "medications":
8989
- return /* @__PURE__ */ jsxRuntime.jsx(AddMedicationWidget, { fieldId });
8990
- case "discharge_medication_orders":
8991
- return /* @__PURE__ */ jsxRuntime.jsx(DischargeMedicationOrdersWidget, { fieldId });
8992
- case "investigations":
8993
- return /* @__PURE__ */ jsxRuntime.jsx(AddInvestigationWidget, { fieldId });
8994
- case "procedures":
8995
- return /* @__PURE__ */ jsxRuntime.jsx(AddProcedureWidget, { fieldId });
8996
- case "differential_diagnosis":
8997
- return /* @__PURE__ */ jsxRuntime.jsx(DifferentialDiagnosisWidget, { fieldId });
8998
- case "vitals":
8999
- return /* @__PURE__ */ jsxRuntime.jsx(VitalsWidget, { fieldId });
9000
- case "hidden_vitals":
9001
- return /* @__PURE__ */ jsxRuntime.jsx(HiddenVitalsWidget, { fieldId });
9002
- case "referral":
9003
- return /* @__PURE__ */ jsxRuntime.jsx(ReferralWidget, { fieldId });
9004
- case "followup":
9005
- return /* @__PURE__ */ jsxRuntime.jsx(FollowupWidget, { fieldId });
9006
- case "smart_textarea":
9007
- return /* @__PURE__ */ jsxRuntime.jsx(SmartTextareaWidget, { fieldId });
9008
- case "diagnosis_textarea":
9009
- return /* @__PURE__ */ jsxRuntime.jsx(DiagnosisTextareaWidget, { fieldId });
9010
- case "obstetric_history":
9011
- return /* @__PURE__ */ jsxRuntime.jsx(ObstetricHistoryWidget, { fieldId });
9012
- case "eye_prescription":
9013
- return /* @__PURE__ */ jsxRuntime.jsx(OphthalmologyWidget, { fieldId });
9014
- case "ophthal_diagnosis":
9015
- return /* @__PURE__ */ jsxRuntime.jsx(OphthalDiagnosisWidget, { fieldId });
9016
- case "orthopedic_exam":
9017
- return /* @__PURE__ */ jsxRuntime.jsx(OrthopedicExamWidget, { fieldId });
9018
- case "toggle": {
9019
- const { value, setValue, setTouched, disabled } = useField(fieldId);
9020
- const store = useFormStore();
9021
- const excludes = fieldDef.excludes ?? [];
9022
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
9023
- /* @__PURE__ */ jsxRuntime.jsx(
9024
- Switch,
9025
- {
9026
- checked: value === true,
9027
- disabled,
9028
- onCheckedChange: (checked) => {
9029
- setValue(checked);
9030
- setTouched();
9031
- if (checked) excludes.forEach((id) => store.setValue(id, false));
9032
- }
9033
- }
9034
- ),
9035
- /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
9036
- ] });
9037
- }
9038
- case "suggestion_textarea":
9039
- case "complaint_chips":
9040
- return /* @__PURE__ */ jsxRuntime.jsx(SuggestionTextareaWidget, { fieldId });
9041
- case "lens_assessment":
9042
- return /* @__PURE__ */ jsxRuntime.jsx(LensAssessmentWidget, { fieldId });
9043
- case "functional_impairment_score":
9044
- return /* @__PURE__ */ jsxRuntime.jsx(FunctionalImpairmentScoreWidget, { fieldId });
9045
- case "biometry_iol_workup":
9046
- return /* @__PURE__ */ jsxRuntime.jsx(BiometryIolWorkupWidget, { fieldId });
9047
- case "surgical_risk_flags":
9048
- return /* @__PURE__ */ jsxRuntime.jsx(SurgicalRiskFlagsWidget, { fieldId });
9049
- case "static_text": {
9050
- const def = fieldDef;
9051
- const size = def.size ?? "regular";
9052
- const labelClass = size === "large" ? "text-base" : "text-sm";
9053
- const descClass = size === "large" ? "text-sm" : "text-xs";
9054
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${labelClass} text-muted-foreground`, children: [
9055
- def.label,
9056
- def.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `mt-1 ${descClass} opacity-90`, children: def.description })
9057
- ] });
9058
- }
9059
- default:
9060
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500", children: [
9061
- "Unknown field type: ",
9062
- fieldDef.type
9063
- ] });
9064
- }
9065
- }
9066
- var Section = ({ title, children }) => {
9067
- const [expanded, setExpanded] = React15.useState(true);
9068
- const handleToggle = () => setExpanded((prev) => !prev);
9069
- const contentClassName = cn(
9070
- "overflow-hidden transition-[height] duration-200 ease-in-out",
9071
- !expanded && "hidden"
9072
- );
9073
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 border rounded-lg bg-white shadow-sm overflow-hidden", children: [
9074
- /* @__PURE__ */ jsxRuntime.jsxs(
9075
- "button",
9223
+ var SliderWidget = ({ fieldId }) => {
9224
+ const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
9225
+ const { state } = useForm();
9226
+ const showError = !!error && (touched || state.submitAttempted);
9227
+ if (!fieldDef || fieldDef.type !== "slider") return null;
9228
+ const def = fieldDef;
9229
+ const min = def.min ?? 0;
9230
+ const max = def.max ?? 10;
9231
+ const step = def.step ?? 1;
9232
+ const raw = value == null || value === "" ? min : Number(value);
9233
+ const num = Number.isFinite(raw) ? Math.min(max, Math.max(min, raw)) : min;
9234
+ const theme = getThemeConfig("textarea", def.theme);
9235
+ const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
9236
+ const labelClass = theme?.labelClassName;
9237
+ const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9238
+ def.label,
9239
+ " ",
9240
+ def.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" }),
9241
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-muted-foreground font-normal tabular-nums", children: [
9242
+ num,
9243
+ "/",
9244
+ max
9245
+ ] })
9246
+ ] });
9247
+ const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { children: labelContent });
9248
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClass, children: [
9249
+ labelEl,
9250
+ /* @__PURE__ */ jsxRuntime.jsx(
9251
+ Slider,
9076
9252
  {
9077
- type: "button",
9078
- onClick: handleToggle,
9079
- className: "w-full flex items-center justify-between gap-2 p-4 text-left border-b hover:bg-gray-50/80 transition-colors",
9080
- children: [
9081
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-medium", children: title }),
9082
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-muted-foreground", "aria-hidden": true, children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-5 w-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-5 w-5" }) })
9083
- ]
9253
+ className: cn("py-1", showError && "opacity-90 ring-1 ring-red-500 rounded"),
9254
+ disabled,
9255
+ min,
9256
+ max,
9257
+ step,
9258
+ value: [num],
9259
+ onValueChange: (v) => {
9260
+ const n = v[0] ?? min;
9261
+ setValue(n);
9262
+ setTouched();
9263
+ }
9084
9264
  }
9085
9265
  ),
9086
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 pt-4 space-y-4 border-t-0", children }) })
9266
+ showError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
9087
9267
  ] });
9088
9268
  };
9089
- var ColumnLayout = ({
9090
- columns,
9091
- label,
9092
- children
9093
- }) => {
9094
- const gridCols = Math.max(1, Math.min(columns, 12));
9095
- const gridClass = `grid gap-4 w-full`;
9096
- const style = {
9097
- gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))`
9269
+ var CHIEF_CHIPS_FIELD = "chief_complaints_chips";
9270
+ var SWELLING_OPTS = [
9271
+ { value: "reducible_hernia", label: "Reducible (hernia)" },
9272
+ { value: "cough_impulse", label: "Cough impulse" },
9273
+ { value: "skin_changes", label: "Skin changes" }
9274
+ ];
9275
+ var GI_OPTS = [
9276
+ { value: "bleeding_pr", label: "Bleeding PR" },
9277
+ { value: "vomiting", label: "Vomiting" },
9278
+ { value: "haematemesis", label: "Haematemesis" }
9279
+ ];
9280
+ var BREAST_OPTS = [
9281
+ { value: "pain", label: "Pain" },
9282
+ { value: "fh_ca_breast", label: "Family history of Ca breast" }
9283
+ ];
9284
+ var ANO_OPTS = [
9285
+ { value: "pain_defecation", label: "Pain during defecation" },
9286
+ { value: "bleeding", label: "Bleeding" },
9287
+ { value: "constipation", label: "Constipation" },
9288
+ { value: "discharge", label: "Discharge" }
9289
+ ];
9290
+ var THYROID_OPTS = [
9291
+ { value: "dysphagia", label: "Dysphagia" },
9292
+ { value: "voice_change", label: "Voice change" },
9293
+ { value: "thyrotoxicosis", label: "Thyrotoxicosis symptoms" }
9294
+ ];
9295
+ var SOCRATES_KEYS = [
9296
+ "site",
9297
+ "onset",
9298
+ "character",
9299
+ "radiation",
9300
+ "associated",
9301
+ "timing",
9302
+ "exacerbating"
9303
+ ];
9304
+ function Panel({ title, children }) {
9305
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
9306
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5 text-xs font-semibold text-slate-700", children: title }),
9307
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3", children })
9308
+ ] });
9309
+ }
9310
+ function chipList(state) {
9311
+ const raw = state.values[CHIEF_CHIPS_FIELD];
9312
+ return Array.isArray(raw) ? raw.filter((x) => typeof x === "string") : [];
9313
+ }
9314
+ var GsSmartHistoryWidget = ({ fieldId }) => {
9315
+ const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
9316
+ const { state } = useForm();
9317
+ const showError = !!error && (touched || state.submitAttempted);
9318
+ const safe = React15.useMemo(() => normalizeGeneralSurgerySmartHistory(value), [value]);
9319
+ const chips = React15.useMemo(() => chipList(state), [state]);
9320
+ const showPain = chips.includes("pain");
9321
+ const showSwelling = chips.includes("swelling_lump");
9322
+ const showGI = chips.includes("bleeding") || chips.includes("obstruction");
9323
+ const showBreast = chips.includes("breast");
9324
+ const showAno = chips.includes("anorectal");
9325
+ const showThyroid = chips.includes("thyroid");
9326
+ const update = (next) => {
9327
+ setValue(next);
9328
+ setTouched();
9098
9329
  };
9099
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
9100
- label != null && label !== "" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-sm font-medium text-gray-700", children: label }),
9101
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: gridClass, style, children })
9330
+ const setPain = (key, v) => {
9331
+ if (key === "severity") {
9332
+ const n = typeof v === "number" ? v : Number(v);
9333
+ const sev = Number.isFinite(n) ? Math.min(10, Math.max(0, Math.round(n))) : 0;
9334
+ update({ ...safe, pain: { ...safe.pain, severity: sev } });
9335
+ return;
9336
+ }
9337
+ update({ ...safe, pain: { ...safe.pain, [key]: String(v) } });
9338
+ };
9339
+ const toggleArr = (section, val) => {
9340
+ if (section === "swelling") {
9341
+ const a = safe.swelling.checks;
9342
+ const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
9343
+ update({ ...safe, swelling: { ...safe.swelling, checks: next } });
9344
+ } else if (section === "gi") {
9345
+ const a = safe.gi.checks;
9346
+ const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
9347
+ update({ ...safe, gi: { ...safe.gi, checks: next } });
9348
+ } else if (section === "breast") {
9349
+ const a = safe.breast.checks;
9350
+ const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
9351
+ update({ ...safe, breast: { ...safe.breast, checks: next } });
9352
+ } else if (section === "ano") {
9353
+ const a = safe.ano.checks;
9354
+ const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
9355
+ update({ ...safe, ano: { ...safe.ano, checks: next } });
9356
+ } else {
9357
+ const a = safe.thyroid.checks;
9358
+ const next = a.includes(val) ? a.filter((x) => x !== val) : [...a, val];
9359
+ update({ ...safe, thyroid: { ...safe.thyroid, checks: next } });
9360
+ }
9361
+ };
9362
+ if (!fieldDef) return null;
9363
+ const theme = getThemeConfig("textarea", fieldDef.theme);
9364
+ const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
9365
+ const labelClass = theme?.labelClassName;
9366
+ const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9367
+ fieldDef.label,
9368
+ fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
9369
+ ] });
9370
+ const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium", children: labelContent });
9371
+ const bodyClass = cn(
9372
+ "-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
9373
+ disabled && "pointer-events-none opacity-60"
9374
+ );
9375
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
9376
+ labelEl,
9377
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: bodyClass, children: [
9378
+ showPain ? /* @__PURE__ */ jsxRuntime.jsx(Panel, { title: "SOCRATES \u2014 pain", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2 md:grid-cols-4", children: [
9379
+ SOCRATES_KEYS.map((k) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
9380
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: k }),
9381
+ /* @__PURE__ */ jsxRuntime.jsx(
9382
+ Input,
9383
+ {
9384
+ className: "h-8 text-xs",
9385
+ value: safe.pain[k],
9386
+ onChange: (e) => setPain(k, e.target.value),
9387
+ disabled
9388
+ }
9389
+ )
9390
+ ] }, k)),
9391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
9392
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Severity 0\u201310" }),
9393
+ /* @__PURE__ */ jsxRuntime.jsx(
9394
+ Input,
9395
+ {
9396
+ type: "number",
9397
+ min: 0,
9398
+ max: 10,
9399
+ className: "h-8 text-xs",
9400
+ value: safe.pain.severity,
9401
+ onChange: (e) => setPain("severity", e.target.value),
9402
+ disabled
9403
+ }
9404
+ )
9405
+ ] })
9406
+ ] }) }) : null,
9407
+ showSwelling ? /* @__PURE__ */ jsxRuntime.jsxs(Panel, { title: "Swelling history", children: [
9408
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-3", children: [
9409
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9410
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Duration" }),
9411
+ /* @__PURE__ */ jsxRuntime.jsx(
9412
+ Input,
9413
+ {
9414
+ className: "h-8 text-xs",
9415
+ value: safe.swelling.duration,
9416
+ onChange: (e) => update({ ...safe, swelling: { ...safe.swelling, duration: e.target.value } }),
9417
+ disabled
9418
+ }
9419
+ )
9420
+ ] }),
9421
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9422
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Size progression" }),
9423
+ /* @__PURE__ */ jsxRuntime.jsx(
9424
+ Input,
9425
+ {
9426
+ className: "h-8 text-xs",
9427
+ value: safe.swelling.sizeProgression,
9428
+ onChange: (e) => update({ ...safe, swelling: { ...safe.swelling, sizeProgression: e.target.value } }),
9429
+ disabled
9430
+ }
9431
+ )
9432
+ ] }),
9433
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9434
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Painful / painless" }),
9435
+ /* @__PURE__ */ jsxRuntime.jsx(
9436
+ Input,
9437
+ {
9438
+ className: "h-8 text-xs",
9439
+ value: safe.swelling.painfulPainless,
9440
+ onChange: (e) => update({ ...safe, swelling: { ...safe.swelling, painfulPainless: e.target.value } }),
9441
+ disabled
9442
+ }
9443
+ )
9444
+ ] })
9445
+ ] }),
9446
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: SWELLING_OPTS.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9447
+ /* @__PURE__ */ jsxRuntime.jsx(
9448
+ Checkbox,
9449
+ {
9450
+ checked: safe.swelling.checks.includes(o.value),
9451
+ onCheckedChange: () => toggleArr("swelling", o.value),
9452
+ disabled
9453
+ }
9454
+ ),
9455
+ o.label
9456
+ ] }, o.value)) })
9457
+ ] }) : null,
9458
+ showGI ? /* @__PURE__ */ jsxRuntime.jsxs(Panel, { title: "GI history", children: [
9459
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-3", children: [
9460
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9461
+ "Appetite",
9462
+ /* @__PURE__ */ jsxRuntime.jsx(
9463
+ Input,
9464
+ {
9465
+ className: "h-8 text-xs",
9466
+ value: safe.gi.appetite,
9467
+ onChange: (e) => update({ ...safe, gi: { ...safe.gi, appetite: e.target.value } }),
9468
+ disabled
9469
+ }
9470
+ )
9471
+ ] }),
9472
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9473
+ "Weight loss",
9474
+ /* @__PURE__ */ jsxRuntime.jsx(
9475
+ Input,
9476
+ {
9477
+ className: "h-8 text-xs",
9478
+ value: safe.gi.weightLoss,
9479
+ onChange: (e) => update({ ...safe, gi: { ...safe.gi, weightLoss: e.target.value } }),
9480
+ disabled
9481
+ }
9482
+ )
9483
+ ] }),
9484
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9485
+ "Bowel habits",
9486
+ /* @__PURE__ */ jsxRuntime.jsx(
9487
+ Input,
9488
+ {
9489
+ className: "h-8 text-xs",
9490
+ value: safe.gi.bowelHabits,
9491
+ onChange: (e) => update({ ...safe, gi: { ...safe.gi, bowelHabits: e.target.value } }),
9492
+ disabled
9493
+ }
9494
+ )
9495
+ ] })
9496
+ ] }),
9497
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: GI_OPTS.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9498
+ /* @__PURE__ */ jsxRuntime.jsx(
9499
+ Checkbox,
9500
+ {
9501
+ checked: safe.gi.checks.includes(o.value),
9502
+ onCheckedChange: () => toggleArr("gi", o.value),
9503
+ disabled
9504
+ }
9505
+ ),
9506
+ o.label
9507
+ ] }, o.value)) })
9508
+ ] }) : null,
9509
+ showBreast ? /* @__PURE__ */ jsxRuntime.jsxs(Panel, { title: "Breast history", children: [
9510
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-2", children: [
9511
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9512
+ "Lump duration",
9513
+ /* @__PURE__ */ jsxRuntime.jsx(
9514
+ Input,
9515
+ {
9516
+ className: "h-8 text-xs",
9517
+ value: safe.breast.lumpDuration,
9518
+ onChange: (e) => update({ ...safe, breast: { ...safe.breast, lumpDuration: e.target.value } }),
9519
+ disabled
9520
+ }
9521
+ )
9522
+ ] }),
9523
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1", children: [
9524
+ "Nipple discharge",
9525
+ /* @__PURE__ */ jsxRuntime.jsx(
9526
+ Input,
9527
+ {
9528
+ className: "h-8 text-xs",
9529
+ value: safe.breast.nippleDischarge,
9530
+ onChange: (e) => update({ ...safe, breast: { ...safe.breast, nippleDischarge: e.target.value } }),
9531
+ disabled
9532
+ }
9533
+ )
9534
+ ] })
9535
+ ] }),
9536
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: BREAST_OPTS.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9537
+ /* @__PURE__ */ jsxRuntime.jsx(
9538
+ Checkbox,
9539
+ {
9540
+ checked: safe.breast.checks.includes(o.value),
9541
+ onCheckedChange: () => toggleArr("breast", o.value),
9542
+ disabled
9543
+ }
9544
+ ),
9545
+ o.label
9546
+ ] }, o.value)) })
9547
+ ] }) : null,
9548
+ showAno ? /* @__PURE__ */ jsxRuntime.jsx(Panel, { title: "Anorectal history", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-2", children: ANO_OPTS.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9549
+ /* @__PURE__ */ jsxRuntime.jsx(
9550
+ Checkbox,
9551
+ {
9552
+ checked: safe.ano.checks.includes(o.value),
9553
+ onCheckedChange: () => toggleArr("ano", o.value),
9554
+ disabled
9555
+ }
9556
+ ),
9557
+ o.label
9558
+ ] }, o.value)) }) }) : null,
9559
+ showThyroid ? /* @__PURE__ */ jsxRuntime.jsxs(Panel, { title: "Thyroid history", children: [
9560
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2 text-xs md:grid-cols-2", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1 md:col-span-2", children: [
9561
+ "Swelling duration",
9562
+ /* @__PURE__ */ jsxRuntime.jsx(
9563
+ Input,
9564
+ {
9565
+ className: "h-8 text-xs",
9566
+ value: safe.thyroid.swellingDuration,
9567
+ onChange: (e) => update({ ...safe, thyroid: { ...safe.thyroid, swellingDuration: e.target.value } }),
9568
+ disabled
9569
+ }
9570
+ )
9571
+ ] }) }),
9572
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-2", children: THYROID_OPTS.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9573
+ /* @__PURE__ */ jsxRuntime.jsx(
9574
+ Checkbox,
9575
+ {
9576
+ checked: safe.thyroid.checks.includes(o.value),
9577
+ onCheckedChange: () => toggleArr("thyroid", o.value),
9578
+ disabled
9579
+ }
9580
+ ),
9581
+ o.label
9582
+ ] }, o.value)) })
9583
+ ] }) : null,
9584
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
9585
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs font-medium text-slate-700", children: "Systemic surgical screening" }),
9586
+ /* @__PURE__ */ jsxRuntime.jsx(
9587
+ Textarea,
9588
+ {
9589
+ className: "min-h-[72px] rounded-md border border-input bg-white text-sm",
9590
+ placeholder: "Fever, weight loss, appetite loss, fatigue, malignancy red flags\u2026",
9591
+ value: safe.systemic,
9592
+ onChange: (e) => update({ ...safe, systemic: e.target.value }),
9593
+ disabled
9594
+ }
9595
+ )
9596
+ ] })
9597
+ ] }),
9598
+ showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
9599
+ ] });
9600
+ };
9601
+ var GS_CLINICAL_EXAMINATION_FIELD = "clinical_examination";
9602
+ var GENERAL = [
9603
+ { value: "pallor", label: "Pallor" },
9604
+ { value: "icterus", label: "Icterus" },
9605
+ { value: "cyanosis", label: "Cyanosis" },
9606
+ { value: "clubbing", label: "Clubbing" },
9607
+ { value: "lymphadenopathy", label: "Lymphadenopathy" },
9608
+ { value: "oedema", label: "Oedema" }
9609
+ ];
9610
+ var REGIONS = [
9611
+ { key: "abdomen", label: "Abdomen" },
9612
+ { key: "hernia", label: "Hernia" },
9613
+ { key: "breast", label: "Breast" },
9614
+ { key: "thyroid", label: "Thyroid" },
9615
+ { key: "anorectal", label: "Anorectal" },
9616
+ { key: "limb", label: "Limb / varicose" }
9617
+ ];
9618
+ var ABD_INSP = [
9619
+ { value: "distension", label: "Distension" },
9620
+ { value: "scars", label: "Scars" },
9621
+ { value: "visible_peristalsis", label: "Visible peristalsis" }
9622
+ ];
9623
+ var ABD_PALP = [
9624
+ { value: "tenderness", label: "Tenderness" },
9625
+ { value: "guarding", label: "Guarding" },
9626
+ { value: "rigidity", label: "Rigidity" },
9627
+ { value: "mass", label: "Palpable mass" }
9628
+ ];
9629
+ var ABD_PERC = [
9630
+ { value: "tympany", label: "Tympany" },
9631
+ { value: "shifting_dullness", label: "Shifting dullness" }
9632
+ ];
9633
+ function SubGroup({ title, children }) {
9634
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
9635
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: title }),
9636
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children })
9637
+ ] });
9638
+ }
9639
+ function RegionCard({ title, children }) {
9640
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
9641
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5 text-xs font-semibold text-slate-700", children: title }),
9642
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3", children })
9643
+ ] });
9644
+ }
9645
+ var GsExaminationWidget = ({ fieldId }) => {
9646
+ const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
9647
+ const clinicalField = useField(GS_CLINICAL_EXAMINATION_FIELD);
9648
+ const { state } = useForm();
9649
+ const showError = !!error && (touched || state.submitAttempted);
9650
+ const safe = React15.useMemo(() => normalizeGeneralSurgeryExamination(value), [value]);
9651
+ const update = (next) => {
9652
+ setValue(next);
9653
+ setTouched();
9654
+ };
9655
+ const toggleIn = (arr, val) => arr.includes(val) ? arr.filter((x) => x !== val) : [...arr, val];
9656
+ const toggleGeneral = (val) => {
9657
+ update({ ...safe, general: toggleIn(safe.general, val) });
9658
+ };
9659
+ const toggleRegion = (key) => {
9660
+ update({ ...safe, regions: toggleIn(safe.regions, key) });
9661
+ };
9662
+ const toggleAbd = (key, val) => {
9663
+ update({
9664
+ ...safe,
9665
+ abdomen: { ...safe.abdomen, [key]: toggleIn(safe.abdomen[key], val) }
9666
+ });
9667
+ };
9668
+ if (!fieldDef) return null;
9669
+ const has = (r) => safe.regions.includes(r);
9670
+ const theme = getThemeConfig("textarea", fieldDef.theme);
9671
+ const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
9672
+ const labelClass = theme?.labelClassName;
9673
+ const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9674
+ fieldDef.label,
9675
+ fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
9676
+ ] });
9677
+ const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium", children: labelContent });
9678
+ const bodyClass = cn(
9679
+ "-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
9680
+ disabled && "pointer-events-none opacity-60"
9681
+ );
9682
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
9683
+ labelEl,
9684
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: bodyClass, children: [
9685
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden rounded-md border border-[#D0D0D0] bg-white", children: [
9686
+ /* @__PURE__ */ jsxRuntime.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" }),
9687
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-2 text-xs md:grid-cols-3 lg:grid-cols-6", children: GENERAL.map((g) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9688
+ /* @__PURE__ */ jsxRuntime.jsx(
9689
+ Checkbox,
9690
+ {
9691
+ checked: safe.general.includes(g.value),
9692
+ onCheckedChange: () => toggleGeneral(g.value),
9693
+ disabled
9694
+ }
9695
+ ),
9696
+ g.label
9697
+ ] }, g.value)) }) })
9698
+ ] }),
9699
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9700
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold text-slate-700", children: "Regional examination \u2014 select region(s)" }),
9701
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: REGIONS.map((r) => {
9702
+ const on = safe.regions.includes(r.key);
9703
+ return /* @__PURE__ */ jsxRuntime.jsx(
9704
+ Button,
9705
+ {
9706
+ type: "button",
9707
+ size: "sm",
9708
+ variant: on ? "default" : "outline",
9709
+ className: "h-7 rounded-full px-3 text-xs",
9710
+ onClick: () => toggleRegion(r.key),
9711
+ disabled,
9712
+ children: r.label
9713
+ },
9714
+ r.key
9715
+ );
9716
+ }) })
9717
+ ] }),
9718
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
9719
+ has("abdomen") ? /* @__PURE__ */ jsxRuntime.jsx(RegionCard, { title: "Abdomen \u2014 inspection \xB7 palpation \xB7 percussion \xB7 auscultation", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4", children: [
9720
+ /* @__PURE__ */ jsxRuntime.jsx(SubGroup, { title: "Inspection", children: ABD_INSP.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9721
+ /* @__PURE__ */ jsxRuntime.jsx(
9722
+ Checkbox,
9723
+ {
9724
+ checked: safe.abdomen.inspection.includes(o.value),
9725
+ onCheckedChange: () => toggleAbd("inspection", o.value),
9726
+ disabled
9727
+ }
9728
+ ),
9729
+ o.label
9730
+ ] }, o.value)) }),
9731
+ /* @__PURE__ */ jsxRuntime.jsxs(SubGroup, { title: "Palpation", children: [
9732
+ ABD_PALP.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9733
+ /* @__PURE__ */ jsxRuntime.jsx(
9734
+ Checkbox,
9735
+ {
9736
+ checked: safe.abdomen.palpation.includes(o.value),
9737
+ onCheckedChange: () => toggleAbd("palpation", o.value),
9738
+ disabled
9739
+ }
9740
+ ),
9741
+ o.label
9742
+ ] }, o.value)),
9743
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "mt-2 block text-xs", children: [
9744
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Mass size / mobility" }),
9745
+ /* @__PURE__ */ jsxRuntime.jsx(
9746
+ Input,
9747
+ {
9748
+ className: "h-8 text-xs",
9749
+ value: safe.abdomen.massNotes,
9750
+ onChange: (e) => update({ ...safe, abdomen: { ...safe.abdomen, massNotes: e.target.value } }),
9751
+ disabled
9752
+ }
9753
+ )
9754
+ ] })
9755
+ ] }),
9756
+ /* @__PURE__ */ jsxRuntime.jsx(SubGroup, { title: "Percussion", children: ABD_PERC.map((o) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-xs", children: [
9757
+ /* @__PURE__ */ jsxRuntime.jsx(
9758
+ Checkbox,
9759
+ {
9760
+ checked: safe.abdomen.percussion.includes(o.value),
9761
+ onCheckedChange: () => toggleAbd("percussion", o.value),
9762
+ disabled
9763
+ }
9764
+ ),
9765
+ o.label
9766
+ ] }, o.value)) }),
9767
+ /* @__PURE__ */ jsxRuntime.jsxs(SubGroup, { title: "Auscultation", children: [
9768
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block text-xs font-medium", children: "Bowel sounds" }),
9769
+ /* @__PURE__ */ jsxRuntime.jsxs(
9770
+ Select,
9771
+ {
9772
+ value: safe.abdomen.bowelSounds,
9773
+ onValueChange: (val) => update({
9774
+ ...safe,
9775
+ abdomen: {
9776
+ ...safe.abdomen,
9777
+ bowelSounds: val
9778
+ }
9779
+ }),
9780
+ disabled,
9781
+ children: [
9782
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select\u2026" }) }),
9783
+ /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
9784
+ /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "none", children: "\u2014" }),
9785
+ /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "normal", children: "Normal" }),
9786
+ /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "up", children: "\u2191" }),
9787
+ /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "down", children: "\u2193" }),
9788
+ /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "absent", children: "Absent" })
9789
+ ] })
9790
+ ]
9791
+ }
9792
+ )
9793
+ ] })
9794
+ ] }) }) : null,
9795
+ has("hernia") ? /* @__PURE__ */ jsxRuntime.jsx(RegionCard, { title: "Hernia exam", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-4", children: [
9796
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block", children: [
9797
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Site" }),
9798
+ /* @__PURE__ */ jsxRuntime.jsx(
9799
+ Input,
9800
+ {
9801
+ className: "h-8 text-xs",
9802
+ value: safe.hernia.site,
9803
+ onChange: (e) => update({ ...safe, hernia: { ...safe.hernia, site: e.target.value } }),
9804
+ disabled
9805
+ }
9806
+ )
9807
+ ] }),
9808
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9809
+ /* @__PURE__ */ jsxRuntime.jsx(
9810
+ Checkbox,
9811
+ {
9812
+ checked: safe.hernia.reducible,
9813
+ onCheckedChange: (c) => update({ ...safe, hernia: { ...safe.hernia, reducible: c === true } }),
9814
+ disabled
9815
+ }
9816
+ ),
9817
+ "Reducible"
9818
+ ] }),
9819
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9820
+ /* @__PURE__ */ jsxRuntime.jsx(
9821
+ Checkbox,
9822
+ {
9823
+ checked: safe.hernia.coughImpulse,
9824
+ onCheckedChange: (c) => update({ ...safe, hernia: { ...safe.hernia, coughImpulse: c === true } }),
9825
+ disabled
9826
+ }
9827
+ ),
9828
+ "Cough impulse"
9829
+ ] }),
9830
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9831
+ /* @__PURE__ */ jsxRuntime.jsx(
9832
+ Checkbox,
9833
+ {
9834
+ checked: safe.hernia.tenderness,
9835
+ onCheckedChange: (c) => update({ ...safe, hernia: { ...safe.hernia, tenderness: c === true } }),
9836
+ disabled
9837
+ }
9838
+ ),
9839
+ "Tenderness"
9840
+ ] })
9841
+ ] }) }) : null,
9842
+ has("breast") ? /* @__PURE__ */ jsxRuntime.jsx(RegionCard, { title: "Breast exam", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-4", children: [
9843
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block", children: [
9844
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Lump size (cm)" }),
9845
+ /* @__PURE__ */ jsxRuntime.jsx(
9846
+ Input,
9847
+ {
9848
+ className: "h-8 text-xs",
9849
+ value: safe.breast.lumpSizeCm,
9850
+ onChange: (e) => update({ ...safe, breast: { ...safe.breast, lumpSizeCm: e.target.value } }),
9851
+ disabled
9852
+ }
9853
+ )
9854
+ ] }),
9855
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9856
+ /* @__PURE__ */ jsxRuntime.jsx(
9857
+ Checkbox,
9858
+ {
9859
+ checked: safe.breast.mobile,
9860
+ onCheckedChange: (c) => update({ ...safe, breast: { ...safe.breast, mobile: c === true } }),
9861
+ disabled
9862
+ }
9863
+ ),
9864
+ "Mobile"
9865
+ ] }),
9866
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9867
+ /* @__PURE__ */ jsxRuntime.jsx(
9868
+ Checkbox,
9869
+ {
9870
+ checked: safe.breast.skinInvolvement,
9871
+ onCheckedChange: (c) => update({ ...safe, breast: { ...safe.breast, skinInvolvement: c === true } }),
9872
+ disabled
9873
+ }
9874
+ ),
9875
+ "Skin involvement"
9876
+ ] }),
9877
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9878
+ /* @__PURE__ */ jsxRuntime.jsx(
9879
+ Checkbox,
9880
+ {
9881
+ checked: safe.breast.axillaryNodes,
9882
+ onCheckedChange: (c) => update({ ...safe, breast: { ...safe.breast, axillaryNodes: c === true } }),
9883
+ disabled
9884
+ }
9885
+ ),
9886
+ "Axillary nodes"
9887
+ ] })
9888
+ ] }) }) : null,
9889
+ has("thyroid") ? /* @__PURE__ */ jsxRuntime.jsx(RegionCard, { title: "Thyroid exam", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-4", children: [
9890
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block", children: [
9891
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Size" }),
9892
+ /* @__PURE__ */ jsxRuntime.jsx(
9893
+ Input,
9894
+ {
9895
+ className: "h-8 text-xs",
9896
+ value: safe.thyroid.size,
9897
+ onChange: (e) => update({ ...safe, thyroid: { ...safe.thyroid, size: e.target.value } }),
9898
+ disabled
9899
+ }
9900
+ )
9901
+ ] }),
9902
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9903
+ /* @__PURE__ */ jsxRuntime.jsx(
9904
+ Checkbox,
9905
+ {
9906
+ checked: safe.thyroid.mobileDeglutition,
9907
+ onCheckedChange: (c) => update({ ...safe, thyroid: { ...safe.thyroid, mobileDeglutition: c === true } }),
9908
+ disabled
9909
+ }
9910
+ ),
9911
+ "Mobile with deglutition"
9912
+ ] }),
9913
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9914
+ /* @__PURE__ */ jsxRuntime.jsx(
9915
+ Checkbox,
9916
+ {
9917
+ checked: safe.thyroid.nodules,
9918
+ onCheckedChange: (c) => update({ ...safe, thyroid: { ...safe.thyroid, nodules: c === true } }),
9919
+ disabled
9920
+ }
9921
+ ),
9922
+ "Nodules"
9923
+ ] }),
9924
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9925
+ /* @__PURE__ */ jsxRuntime.jsx(
9926
+ Checkbox,
9927
+ {
9928
+ checked: safe.thyroid.cervicalNodes,
9929
+ onCheckedChange: (c) => update({ ...safe, thyroid: { ...safe.thyroid, cervicalNodes: c === true } }),
9930
+ disabled
9931
+ }
9932
+ ),
9933
+ "Cervical lymph nodes"
9934
+ ] })
9935
+ ] }) }) : null,
9936
+ has("anorectal") ? /* @__PURE__ */ jsxRuntime.jsx(RegionCard, { title: "Anorectal exam", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-3", children: [
9937
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block md:col-span-3", children: [
9938
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block font-medium", children: "Inspection findings" }),
9939
+ /* @__PURE__ */ jsxRuntime.jsx(
9940
+ Input,
9941
+ {
9942
+ className: "h-8 text-xs",
9943
+ value: safe.anorectal.inspection,
9944
+ onChange: (e) => update({ ...safe, anorectal: { ...safe.anorectal, inspection: e.target.value } }),
9945
+ disabled
9946
+ }
9947
+ )
9948
+ ] }),
9949
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9950
+ /* @__PURE__ */ jsxRuntime.jsx(
9951
+ Checkbox,
9952
+ {
9953
+ checked: safe.anorectal.dreDone,
9954
+ onCheckedChange: (c) => update({ ...safe, anorectal: { ...safe.anorectal, dreDone: c === true } }),
9955
+ disabled
9956
+ }
9957
+ ),
9958
+ "DRE done"
9959
+ ] }),
9960
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9961
+ /* @__PURE__ */ jsxRuntime.jsx(
9962
+ Checkbox,
9963
+ {
9964
+ checked: safe.anorectal.proctoscopyDone,
9965
+ onCheckedChange: (c) => update({ ...safe, anorectal: { ...safe.anorectal, proctoscopyDone: c === true } }),
9966
+ disabled
9967
+ }
9968
+ ),
9969
+ "Proctoscopy done"
9970
+ ] }),
9971
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:col-span-3", children: [
9972
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs font-semibold", children: "DRE / proctoscopy notes" }),
9973
+ /* @__PURE__ */ jsxRuntime.jsx(
9974
+ Textarea,
9975
+ {
9976
+ className: "mt-1 min-h-[64px] text-sm",
9977
+ placeholder: "Sphincter tone, masses, prostate, bleeding\u2026",
9978
+ value: safe.anorectal.notes,
9979
+ onChange: (e) => update({ ...safe, anorectal: { ...safe.anorectal, notes: e.target.value } }),
9980
+ disabled
9981
+ }
9982
+ )
9983
+ ] })
9984
+ ] }) }) : null,
9985
+ has("limb") ? /* @__PURE__ */ jsxRuntime.jsx(RegionCard, { title: "Limb / varicose veins", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-x-4 gap-y-2 text-xs", children: [
9986
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9987
+ /* @__PURE__ */ jsxRuntime.jsx(
9988
+ Checkbox,
9989
+ {
9990
+ checked: safe.limb.dilatedVeins,
9991
+ onCheckedChange: (c) => update({ ...safe, limb: { ...safe.limb, dilatedVeins: c === true } }),
9992
+ disabled
9993
+ }
9994
+ ),
9995
+ "Dilated veins"
9996
+ ] }),
9997
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
9998
+ /* @__PURE__ */ jsxRuntime.jsx(
9999
+ Checkbox,
10000
+ {
10001
+ checked: safe.limb.ulcer,
10002
+ onCheckedChange: (c) => update({ ...safe, limb: { ...safe.limb, ulcer: c === true } }),
10003
+ disabled
10004
+ }
10005
+ ),
10006
+ "Ulcer"
10007
+ ] }),
10008
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
10009
+ /* @__PURE__ */ jsxRuntime.jsx(
10010
+ Checkbox,
10011
+ {
10012
+ checked: safe.limb.oedema,
10013
+ onCheckedChange: (c) => update({ ...safe, limb: { ...safe.limb, oedema: c === true } }),
10014
+ disabled
10015
+ }
10016
+ ),
10017
+ "Oedema"
10018
+ ] })
10019
+ ] }) }) : null
10020
+ ] }),
10021
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
10022
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs font-semibold text-slate-700", children: clinicalField.fieldDef?.label ?? "Clinical examination" }),
10023
+ /* @__PURE__ */ jsxRuntime.jsx(
10024
+ Textarea,
10025
+ {
10026
+ className: "min-h-[88px] rounded-md border border-input bg-white text-sm",
10027
+ value: typeof clinicalField.value === "string" ? clinicalField.value : clinicalField.value == null ? "" : String(clinicalField.value),
10028
+ onChange: (e) => {
10029
+ clinicalField.setValue(e.target.value);
10030
+ clinicalField.setTouched();
10031
+ },
10032
+ disabled: disabled || clinicalField.disabled
10033
+ }
10034
+ )
10035
+ ] })
10036
+ ] }),
10037
+ showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
10038
+ ] });
10039
+ };
10040
+ var CHIEF_CHIPS_FIELD2 = "chief_complaints_chips";
10041
+ var GS_EXAMINATION_FIELD = "gs_examination";
10042
+ function chipList2(state) {
10043
+ const raw = state.values[CHIEF_CHIPS_FIELD2];
10044
+ return Array.isArray(raw) ? raw.filter((x) => typeof x === "string") : [];
10045
+ }
10046
+ function regionList(state) {
10047
+ const raw = state.values[GS_EXAMINATION_FIELD];
10048
+ const ex = normalizeGeneralSurgeryExamination(raw);
10049
+ return ex.regions;
10050
+ }
10051
+ var GsGradingWidget = ({ fieldId }) => {
10052
+ const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
10053
+ const { state } = useForm();
10054
+ const showError = !!error && (touched || state.submitAttempted);
10055
+ const safe = React15.useMemo(() => normalizeGeneralSurgeryGrading(value), [value]);
10056
+ const chips = React15.useMemo(() => chipList2(state), [state]);
10057
+ const regions = React15.useMemo(() => regionList(state), [state]);
10058
+ const visibleRows = React15.useMemo(() => {
10059
+ return ALL_GS_CONDITIONS.filter(
10060
+ (c) => gsGradingRowVisible(c, chips, regions, safe[c] ?? 0)
10061
+ );
10062
+ }, [chips, regions, safe]);
10063
+ const update = (next) => {
10064
+ setValue(next);
10065
+ setTouched();
10066
+ };
10067
+ const setGrade = (cond, gradeStr) => {
10068
+ const n = Math.min(5, Math.max(0, Math.round(Number(gradeStr)) || 0));
10069
+ update({ ...safe, [cond]: n });
10070
+ };
10071
+ if (!fieldDef) return null;
10072
+ const theme = getThemeConfig("textarea", fieldDef.theme);
10073
+ const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
10074
+ const labelClass = theme?.labelClassName;
10075
+ const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10076
+ fieldDef.label,
10077
+ fieldDef.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
10078
+ ] });
10079
+ const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium", children: labelContent });
10080
+ const bodyClass = cn(
10081
+ "-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
10082
+ disabled && "pointer-events-none opacity-60"
10083
+ );
10084
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
10085
+ labelEl,
10086
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: bodyClass, children: visibleRows.length === 0 ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto rounded-md border border-[#D0D0D0]", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full min-w-[520px] border-collapse text-xs", children: [
10087
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50", children: [
10088
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-slate-700", children: "Condition" }),
10089
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-24 px-2 py-2 font-semibold text-slate-700", children: "Grade" }),
10090
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-slate-700", children: "Description" })
10091
+ ] }) }),
10092
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white", children: visibleRows.map((c) => {
10093
+ const g = safe[c] ?? 0;
10094
+ const desc = GS_GRADE_DESCRIPTIONS[c][g] ?? "\u2014";
10095
+ return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-[#D0D0D0]/80 last:border-0", children: [
10096
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 font-medium", children: GS_CONDITION_LABELS[c] }),
10097
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-2 py-1.5 align-middle", children: /* @__PURE__ */ jsxRuntime.jsxs(
10098
+ Select,
10099
+ {
10100
+ value: String(g),
10101
+ onValueChange: (v) => setGrade(c, v),
10102
+ disabled,
10103
+ children: [
10104
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
10105
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: [0, 1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(n), children: n === 0 ? "\u2014" : String(n) }, n)) })
10106
+ ]
10107
+ }
10108
+ ) }),
10109
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 text-muted-foreground", children: desc })
10110
+ ] }, c);
10111
+ }) })
10112
+ ] }) }) }),
10113
+ showError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
10114
+ ] });
10115
+ };
10116
+ function isFlagSelected(selected, optValue) {
10117
+ return selected.some((v) => v === optValue || String(v) === String(optValue));
10118
+ }
10119
+ var PainScaleFlagsWidget = ({ fieldId }) => {
10120
+ const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
10121
+ const { state } = useForm();
10122
+ const showError = !!error && (touched || state.submitAttempted);
10123
+ if (!fieldDef || fieldDef.type !== "pain_scale_flags") return null;
10124
+ const def = fieldDef;
10125
+ const min = def.min ?? 0;
10126
+ const max = def.max ?? 10;
10127
+ const step = def.step ?? 1;
10128
+ const flagOptions = def.options ?? [];
10129
+ const safe = React15.useMemo(
10130
+ () => normalizePainScaleFlags(value, { min, max }),
10131
+ [value, min, max]
10132
+ );
10133
+ const theme = getThemeConfig("textarea", def.theme);
10134
+ const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
10135
+ const labelClass = theme?.labelClassName;
10136
+ const update = (next) => {
10137
+ setValue(normalizePainScaleFlags(next, { min, max }));
10138
+ setTouched();
10139
+ };
10140
+ const toggleFlag = (optValue) => {
10141
+ const sel = safe.flags;
10142
+ const isSelected = isFlagSelected(sel, optValue);
10143
+ const nextFlags = isSelected ? sel.filter((v) => v !== optValue && String(v) !== String(optValue)) : [...sel, String(optValue)];
10144
+ update({ pain: safe.pain, flags: nextFlags });
10145
+ };
10146
+ const labelContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10147
+ def.label,
10148
+ " ",
10149
+ def.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
10150
+ ] });
10151
+ const labelEl = theme ? /* @__PURE__ */ jsxRuntime.jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsxRuntime.jsx(Label, { children: labelContent });
10152
+ const bodyClass = cn(
10153
+ "-mt-1 flex min-w-0 flex-col border-t border-[#D0D0D0] bg-white px-3 py-3",
10154
+ disabled && "pointer-events-none opacity-60"
10155
+ );
10156
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(wrapperClass, "h-full min-h-0 flex flex-col"), children: [
10157
+ labelEl,
10158
+ def.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: def.description }),
10159
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(bodyClass, "min-h-0 flex-1"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-3", children: [
10160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
10161
+ /* @__PURE__ */ jsxRuntime.jsxs(Label, { className: "text-sm font-medium text-slate-700", children: [
10162
+ "Pain score (VAS)",
10163
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 font-normal tabular-nums text-muted-foreground", children: [
10164
+ safe.pain,
10165
+ "/",
10166
+ max
10167
+ ] })
10168
+ ] }),
10169
+ /* @__PURE__ */ jsxRuntime.jsx(
10170
+ Slider,
10171
+ {
10172
+ className: cn("py-1", showError && "rounded opacity-90 ring-1 ring-red-500"),
10173
+ disabled,
10174
+ min,
10175
+ max,
10176
+ step,
10177
+ value: [safe.pain],
10178
+ onValueChange: (v) => {
10179
+ const n = v[0] ?? min;
10180
+ update({ pain: n, flags: safe.flags });
10181
+ }
10182
+ }
10183
+ )
10184
+ ] }),
10185
+ flagOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-1.5", children: [
10186
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium text-slate-700", children: "Triage flags" }),
10187
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-x-4 gap-y-2", children: flagOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10188
+ /* @__PURE__ */ jsxRuntime.jsx(
10189
+ Checkbox,
10190
+ {
10191
+ id: `${fieldId}-flag-${String(opt.value)}`,
10192
+ checked: isFlagSelected(safe.flags, opt.value),
10193
+ onCheckedChange: () => toggleFlag(opt.value),
10194
+ disabled
10195
+ }
10196
+ ),
10197
+ /* @__PURE__ */ jsxRuntime.jsx(
10198
+ Label,
10199
+ {
10200
+ htmlFor: `${fieldId}-flag-${String(opt.value)}`,
10201
+ className: "cursor-pointer text-sm font-normal leading-none",
10202
+ children: opt.label
10203
+ }
10204
+ )
10205
+ ] }, String(opt.value))) })
10206
+ ] }) : null
10207
+ ] }) }),
10208
+ showError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
10209
+ ] });
10210
+ };
10211
+ var FieldRenderer = ({ fieldId }) => {
10212
+ const { fieldDef, visible } = useField(fieldId);
10213
+ if (!visible || !fieldDef) {
10214
+ return null;
10215
+ }
10216
+ return renderWidget(fieldId, fieldDef);
10217
+ };
10218
+ function renderWidget(fieldId, fieldDef) {
10219
+ switch (fieldDef.type) {
10220
+ case "text":
10221
+ case "number":
10222
+ return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
10223
+ case "slider":
10224
+ return /* @__PURE__ */ jsxRuntime.jsx(SliderWidget, { fieldId });
10225
+ case "textarea":
10226
+ if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
10227
+ return /* @__PURE__ */ jsxRuntime.jsx(MarMedicationOrdersWidget, { fieldId });
10228
+ }
10229
+ return /* @__PURE__ */ jsxRuntime.jsx(TextWidget, { fieldId });
10230
+ case "richtext":
10231
+ return /* @__PURE__ */ jsxRuntime.jsx(RichTextWidget, { fieldId });
10232
+ case "date":
10233
+ return /* @__PURE__ */ jsxRuntime.jsx(DateWidget, { fieldId });
10234
+ case "datetime":
10235
+ return /* @__PURE__ */ jsxRuntime.jsx(DateTimeWidget, { fieldId });
10236
+ case "select":
10237
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectWidget, { fieldId });
10238
+ case "radio":
10239
+ return /* @__PURE__ */ jsxRuntime.jsx(RadioWidget, { fieldId });
10240
+ case "checkbox":
10241
+ return /* @__PURE__ */ jsxRuntime.jsx(CheckboxWidget, { fieldId });
10242
+ case "multiselect":
10243
+ return /* @__PURE__ */ jsxRuntime.jsx(MultiSelectWidget, { fieldId });
10244
+ case "repeatable":
10245
+ return /* @__PURE__ */ jsxRuntime.jsx(RepeatableWidget, { fieldId });
10246
+ case "image_upload":
10247
+ return /* @__PURE__ */ jsxRuntime.jsx(ImageUploadWidget, { fieldId });
10248
+ case "media_upload":
10249
+ return /* @__PURE__ */ jsxRuntime.jsx(MediaUploadWidget, { fieldId });
10250
+ case "signature":
10251
+ return /* @__PURE__ */ jsxRuntime.jsx(SignatureUploadWidget, { fieldId });
10252
+ case "editable_table":
10253
+ return /* @__PURE__ */ jsxRuntime.jsx(EditableTableWidget, { fieldId });
10254
+ case "medications":
10255
+ return /* @__PURE__ */ jsxRuntime.jsx(AddMedicationWidget, { fieldId });
10256
+ case "discharge_medication_orders":
10257
+ return /* @__PURE__ */ jsxRuntime.jsx(DischargeMedicationOrdersWidget, { fieldId });
10258
+ case "investigations":
10259
+ return /* @__PURE__ */ jsxRuntime.jsx(AddInvestigationWidget, { fieldId });
10260
+ case "procedures":
10261
+ return /* @__PURE__ */ jsxRuntime.jsx(AddProcedureWidget, { fieldId });
10262
+ case "differential_diagnosis":
10263
+ return /* @__PURE__ */ jsxRuntime.jsx(DifferentialDiagnosisWidget, { fieldId });
10264
+ case "vitals":
10265
+ return /* @__PURE__ */ jsxRuntime.jsx(VitalsWidget, { fieldId });
10266
+ case "hidden_vitals":
10267
+ return /* @__PURE__ */ jsxRuntime.jsx(HiddenVitalsWidget, { fieldId });
10268
+ case "referral":
10269
+ return /* @__PURE__ */ jsxRuntime.jsx(ReferralWidget, { fieldId });
10270
+ case "followup":
10271
+ return /* @__PURE__ */ jsxRuntime.jsx(FollowupWidget, { fieldId });
10272
+ case "smart_textarea":
10273
+ return /* @__PURE__ */ jsxRuntime.jsx(SmartTextareaWidget, { fieldId });
10274
+ case "diagnosis_textarea":
10275
+ return /* @__PURE__ */ jsxRuntime.jsx(DiagnosisTextareaWidget, { fieldId });
10276
+ case "obstetric_history":
10277
+ return /* @__PURE__ */ jsxRuntime.jsx(ObstetricHistoryWidget, { fieldId });
10278
+ case "eye_prescription":
10279
+ return /* @__PURE__ */ jsxRuntime.jsx(OphthalmologyWidget, { fieldId });
10280
+ case "ophthal_diagnosis":
10281
+ return /* @__PURE__ */ jsxRuntime.jsx(OphthalDiagnosisWidget, { fieldId });
10282
+ case "orthopedic_exam":
10283
+ return /* @__PURE__ */ jsxRuntime.jsx(OrthopedicExamWidget, { fieldId });
10284
+ case "general_surgery_smart_history":
10285
+ return /* @__PURE__ */ jsxRuntime.jsx(GsSmartHistoryWidget, { fieldId });
10286
+ case "general_surgery_examination":
10287
+ return /* @__PURE__ */ jsxRuntime.jsx(GsExaminationWidget, { fieldId });
10288
+ case "general_surgery_grading":
10289
+ return /* @__PURE__ */ jsxRuntime.jsx(GsGradingWidget, { fieldId });
10290
+ case "pain_scale_flags":
10291
+ return /* @__PURE__ */ jsxRuntime.jsx(PainScaleFlagsWidget, { fieldId });
10292
+ case "toggle": {
10293
+ const { value, setValue, setTouched, disabled } = useField(fieldId);
10294
+ const store = useFormStore();
10295
+ const excludes = fieldDef.excludes ?? [];
10296
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
10297
+ /* @__PURE__ */ jsxRuntime.jsx(
10298
+ Switch,
10299
+ {
10300
+ checked: value === true,
10301
+ disabled,
10302
+ onCheckedChange: (checked) => {
10303
+ setValue(checked);
10304
+ setTouched();
10305
+ if (checked) excludes.forEach((id) => store.setValue(id, false));
10306
+ }
10307
+ }
10308
+ ),
10309
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
10310
+ ] });
10311
+ }
10312
+ case "suggestion_textarea":
10313
+ case "complaint_chips":
10314
+ return /* @__PURE__ */ jsxRuntime.jsx(SuggestionTextareaWidget, { fieldId });
10315
+ case "lens_assessment":
10316
+ return /* @__PURE__ */ jsxRuntime.jsx(LensAssessmentWidget, { fieldId });
10317
+ case "functional_impairment_score":
10318
+ return /* @__PURE__ */ jsxRuntime.jsx(FunctionalImpairmentScoreWidget, { fieldId });
10319
+ case "biometry_iol_workup":
10320
+ return /* @__PURE__ */ jsxRuntime.jsx(BiometryIolWorkupWidget, { fieldId });
10321
+ case "surgical_risk_flags":
10322
+ return /* @__PURE__ */ jsxRuntime.jsx(SurgicalRiskFlagsWidget, { fieldId });
10323
+ case "static_text": {
10324
+ const def = fieldDef;
10325
+ const size = def.size ?? "regular";
10326
+ const labelClass = size === "large" ? "text-base" : "text-sm";
10327
+ const descClass = size === "large" ? "text-sm" : "text-xs";
10328
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${labelClass} text-muted-foreground`, children: [
10329
+ def.label,
10330
+ def.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `mt-1 ${descClass} opacity-90`, children: def.description })
10331
+ ] });
10332
+ }
10333
+ default:
10334
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-red-500", children: [
10335
+ "Unknown field type: ",
10336
+ fieldDef.type
10337
+ ] });
10338
+ }
10339
+ }
10340
+ var Section = ({ title, children }) => {
10341
+ const [expanded, setExpanded] = React15.useState(true);
10342
+ const handleToggle = () => setExpanded((prev) => !prev);
10343
+ const contentClassName = cn(
10344
+ "overflow-hidden transition-[height] duration-200 ease-in-out",
10345
+ !expanded && "hidden"
10346
+ );
10347
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 border rounded-lg bg-white shadow-sm overflow-hidden", children: [
10348
+ /* @__PURE__ */ jsxRuntime.jsxs(
10349
+ "button",
10350
+ {
10351
+ type: "button",
10352
+ onClick: handleToggle,
10353
+ className: "w-full flex items-center justify-between gap-2 p-4 text-left border-b hover:bg-gray-50/80 transition-colors",
10354
+ children: [
10355
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-medium", children: title }),
10356
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0 text-muted-foreground", "aria-hidden": true, children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-5 w-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-5 w-5" }) })
10357
+ ]
10358
+ }
10359
+ ),
10360
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 pt-4 space-y-4 border-t-0", children }) })
10361
+ ] });
10362
+ };
10363
+ var ColumnLayout = ({
10364
+ columns,
10365
+ label,
10366
+ children
10367
+ }) => {
10368
+ const gridCols = Math.max(1, Math.min(columns, 12));
10369
+ const gridClass = `grid gap-4 w-full`;
10370
+ const style = {
10371
+ gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))`
10372
+ };
10373
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
10374
+ label != null && label !== "" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-sm font-medium text-gray-700", children: label }),
10375
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: gridClass, style, children })
9102
10376
  ] });
9103
10377
  };
9104
10378
  var DynamicForm = () => {
@@ -9250,14 +10524,24 @@ var SmartForm = ({
9250
10524
  if (position !== "left") return null;
9251
10525
  return /* @__PURE__ */ jsxRuntime.jsx(FieldRenderer, { fieldId }, fieldId);
9252
10526
  }) }),
9253
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-2 grid grid-cols-2 gap-x-2 space-y-2", children: fieldIds.map((fieldId) => {
10527
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-2 grid grid-cols-2 gap-2", children: fieldIds.map((fieldId) => {
9254
10528
  const fieldDef = store.getFieldDef(fieldId);
9255
10529
  if (!fieldDef) return null;
9256
10530
  const position = fieldDef.position ?? "center";
9257
10531
  if (position !== "center") return null;
9258
10532
  const colSpanRaw = fieldDef.colSpan ?? 1;
9259
10533
  const colSpan = colSpanRaw === 2 ? 2 : 1;
9260
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: colSpan === 2 ? "col-span-2" : "col-span-1", children: /* @__PURE__ */ jsxRuntime.jsx(FieldRenderer, { fieldId }) }, fieldId);
10534
+ return /* @__PURE__ */ jsxRuntime.jsx(
10535
+ "div",
10536
+ {
10537
+ className: cn(
10538
+ "min-h-0 flex flex-col",
10539
+ colSpan === 2 ? "col-span-2" : "col-span-1 h-full"
10540
+ ),
10541
+ children: /* @__PURE__ */ jsxRuntime.jsx(FieldRenderer, { fieldId })
10542
+ },
10543
+ fieldId
10544
+ );
9261
10545
  }) }),
9262
10546
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-1 flex flex-col gap-2", children: fieldIds.map((fieldId) => {
9263
10547
  const fieldDef = store.getFieldDef(fieldId);
@@ -9705,11 +10989,17 @@ var ReadOnlyDischargeMedicationOrders = ({ fieldDef, value }) => {
9705
10989
  }) })
9706
10990
  ] });
9707
10991
  };
9708
- var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
10992
+ var ReadOnlyFieldRenderer = ({
10993
+ fieldDef,
10994
+ value,
10995
+ allValues,
10996
+ resolveFieldDef
10997
+ }) => {
9709
10998
  if (!fieldDef) return null;
9710
10999
  switch (fieldDef.type) {
9711
11000
  case "text":
9712
11001
  case "number":
11002
+ case "slider":
9713
11003
  case "textarea":
9714
11004
  case "richtext":
9715
11005
  return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value });
@@ -9747,8 +11037,30 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
9747
11037
  ] });
9748
11038
  }
9749
11039
  case "suggestion_textarea":
9750
- case "complaint_chips":
9751
- return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value });
11040
+ case "complaint_chips": {
11041
+ 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()) : [];
11042
+ const showEmbedded = embeddedIds.length > 0 && resolveFieldDef && allValues && typeof allValues === "object";
11043
+ if (!showEmbedded) {
11044
+ return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value });
11045
+ }
11046
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
11047
+ /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value }),
11048
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-3 border-t border-muted-foreground/20 pt-3 sm:grid-cols-3", children: embeddedIds.map((id) => {
11049
+ const fd = resolveFieldDef(id);
11050
+ if (!fd) return null;
11051
+ return /* @__PURE__ */ jsxRuntime.jsx(
11052
+ ReadOnlyFieldRenderer,
11053
+ {
11054
+ fieldDef: fd,
11055
+ value: allValues[id],
11056
+ allValues,
11057
+ resolveFieldDef
11058
+ },
11059
+ id
11060
+ );
11061
+ }) })
11062
+ ] });
11063
+ }
9752
11064
  case "lens_assessment": {
9753
11065
  const v = value && typeof value === "object" && !Array.isArray(value) ? value : null;
9754
11066
  const notes = typeof v?.notes === "string" ? v.notes : "";
@@ -9824,6 +11136,44 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
9824
11136
  const lines = [`Right eye (OD): ${od}`, `Left eye (OS): ${os}`].join("\n");
9825
11137
  return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value: lines });
9826
11138
  }
11139
+ case "pain_scale_flags": {
11140
+ const def = fieldDef;
11141
+ const min = def.min ?? 0;
11142
+ const max = def.max ?? 10;
11143
+ const safe = normalizePainScaleFlags(value, { min, max });
11144
+ const opts = def.options ?? [];
11145
+ const flagLabels = safe.flags.map((fv) => {
11146
+ const o = opts.find((x) => x.value === fv || String(x.value) === String(fv));
11147
+ return o?.label ?? fv;
11148
+ });
11149
+ const lines = [
11150
+ `Pain score (VAS): ${safe.pain}/${max}`,
11151
+ flagLabels.length > 0 ? `Triage flags: ${flagLabels.join(", ")}` : "Triage flags: \u2014"
11152
+ ].join("\n");
11153
+ return /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value: lines });
11154
+ }
11155
+ case "general_surgery_smart_history":
11156
+ case "general_surgery_grading":
11157
+ return /* @__PURE__ */ jsxRuntime.jsx(
11158
+ ReadOnlyText,
11159
+ {
11160
+ fieldDef,
11161
+ value: value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value)
11162
+ }
11163
+ );
11164
+ case "general_surgery_examination": {
11165
+ const structuredDisplay = value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value);
11166
+ const clinicalDef = resolveFieldDef?.("clinical_examination");
11167
+ const clinicalRaw = allValues?.["clinical_examination"];
11168
+ const clinicalStr = typeof clinicalRaw === "string" ? clinicalRaw : clinicalRaw != null && clinicalRaw !== "" ? String(clinicalRaw) : "";
11169
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
11170
+ /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef, value: structuredDisplay }),
11171
+ clinicalDef ? /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyText, { fieldDef: clinicalDef, value: clinicalStr }) : clinicalStr ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
11172
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700", children: "Clinical examination" }),
11173
+ /* @__PURE__ */ jsxRuntime.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 })
11174
+ ] }) : null
11175
+ ] });
11176
+ }
9827
11177
  case "static_text": {
9828
11178
  const def = fieldDef;
9829
11179
  const size = def.size ?? "regular";
@@ -9870,7 +11220,9 @@ var ReadOnlyForm = ({ schema, submission }) => {
9870
11220
  ReadOnlyFieldRenderer,
9871
11221
  {
9872
11222
  fieldDef,
9873
- value: formData[child]
11223
+ value: formData[child],
11224
+ allValues: formData,
11225
+ resolveFieldDef: (id) => fieldMap.get(id)
9874
11226
  },
9875
11227
  child
9876
11228
  ) : null;
@@ -9889,7 +11241,9 @@ var ReadOnlyForm = ({ schema, submission }) => {
9889
11241
  ReadOnlyFieldRenderer,
9890
11242
  {
9891
11243
  fieldDef,
9892
- value: formData[fieldId]
11244
+ value: formData[fieldId],
11245
+ allValues: formData,
11246
+ resolveFieldDef: (id) => fieldMap.get(id)
9893
11247
  },
9894
11248
  fieldId
9895
11249
  ))
@@ -9920,7 +11274,9 @@ var ReadOnlyForm = ({ schema, submission }) => {
9920
11274
  ReadOnlyFieldRenderer,
9921
11275
  {
9922
11276
  fieldDef,
9923
- value: formData[fieldId]
11277
+ value: formData[fieldId],
11278
+ allValues: formData,
11279
+ resolveFieldDef: (id) => fieldMap.get(id)
9924
11280
  },
9925
11281
  fieldId
9926
11282
  ))