formanitor 0.0.23 → 0.0.25

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
@@ -2813,6 +2813,22 @@ var AddEntityDialog = ({
2813
2813
  actionSlot != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4 flex justify-end shrink-0 border-t border-border bg-background", children: actionSlot })
2814
2814
  ] }) });
2815
2815
  };
2816
+ var BEFORE_AFTER_OPTIONS = [
2817
+ { label: "Blank", value: "" },
2818
+ { label: "AFTER FOOD", value: "AFTER FOOD" },
2819
+ { label: "BEFORE FOOD", value: "BEFORE FOOD" },
2820
+ { label: "WITH FOOD", value: "WITH FOOD" },
2821
+ { label: "SINGLE DOSE", value: "SINGLE DOSE" },
2822
+ { label: "BED TIME", value: "BED TIME" },
2823
+ { label: "EMPTY STOMACH", value: "EMPTY STOMACH" },
2824
+ { label: "LOCAL APPLICATION", value: "LOCAL APPLICATION" },
2825
+ { label: "STAT", value: "STAT" },
2826
+ { label: "INHALATION", value: "INHALATION" }
2827
+ ];
2828
+ var BEFORE_AFTER_NORMALIZATION_MAP = {
2829
+ AF: "AFTER FOOD",
2830
+ BF: "BEFORE FOOD"
2831
+ };
2816
2832
  function mapToMedication(result) {
2817
2833
  return {
2818
2834
  id: result.id,
@@ -2876,7 +2892,7 @@ function mapFrequentItemToMedication(item) {
2876
2892
  const parsed = parseDuration(item.duration);
2877
2893
  const duration_value = item.duration_value ?? parsed.value;
2878
2894
  const duration_unit = item.duration_unit ?? parsed.unit;
2879
- const before_after = item.before_after === "BEFORE FOOD" ? "BEFORE FOOD" : "AFTER FOOD";
2895
+ const before_after = normalizeBeforeAfter(item.before_after);
2880
2896
  const routeNote = item.route ? `Route: ${item.route}` : "";
2881
2897
  const baseNotes = item.notes?.trim() || "";
2882
2898
  const combinedNotes = [baseNotes, routeNote.trim()].filter((part) => part.length > 0).join(" \u2014 ");
@@ -2895,6 +2911,13 @@ function mapFrequentItemToMedication(item) {
2895
2911
  notes: combinedNotes
2896
2912
  };
2897
2913
  }
2914
+ function normalizeBeforeAfter(value) {
2915
+ if (value == null) return "AFTER FOOD";
2916
+ const mapped = BEFORE_AFTER_NORMALIZATION_MAP[value];
2917
+ if (mapped) return mapped;
2918
+ const validValues = BEFORE_AFTER_OPTIONS.map((option) => option.value);
2919
+ return validValues.includes(value) ? value : "AFTER FOOD";
2920
+ }
2898
2921
  function Spinner({
2899
2922
  value,
2900
2923
  onChange
@@ -3002,16 +3025,13 @@ function MedicationCard({
3002
3025
  )
3003
3026
  ] }),
3004
3027
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2 items-center flex-1 min-w-0 justify-end", children: ["morning", "afternoon", "night"].map((slot) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { value: med[slot], onChange: (v) => set(slot, v) }) }, slot)) }),
3005
- /* @__PURE__ */ jsxRuntime.jsxs(
3028
+ /* @__PURE__ */ jsxRuntime.jsx(
3006
3029
  "select",
3007
3030
  {
3008
3031
  className: "text-xs border border-border rounded px-2 py-1 bg-white shrink-0",
3009
- value: med.before_after === "AFTER FOOD" ? "AF" : "BF",
3010
- onChange: (e) => set("before_after", e.target.value === "AF" ? "AFTER FOOD" : "BEFORE FOOD"),
3011
- children: [
3012
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "AF", children: "AF" }),
3013
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "BF", children: "BF" })
3014
- ]
3032
+ value: normalizeBeforeAfter(med.before_after),
3033
+ onChange: (e) => set("before_after", e.target.value),
3034
+ children: BEFORE_AFTER_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.label))
3015
3035
  }
3016
3036
  )
3017
3037
  ] }),
@@ -3556,6 +3576,9 @@ function mapToProcedure(result) {
3556
3576
  fromAI: false
3557
3577
  };
3558
3578
  }
3579
+ function createCustomProcedure(trimmedName) {
3580
+ return { name: trimmedName.trim(), is_custom: true };
3581
+ }
3559
3582
  var AddProcedureField = ({
3560
3583
  label = "Procedures",
3561
3584
  value,
@@ -3574,7 +3597,9 @@ var AddProcedureField = ({
3574
3597
  const valueRef = React13.useRef([]);
3575
3598
  const searchInputRef = React13.useRef(null);
3576
3599
  valueRef.current = value;
3577
- const addedIds = new Set(value.map((proc) => proc.id));
3600
+ const addedIds = new Set(
3601
+ value.filter((proc) => !proc.is_custom).map((proc) => proc.id)
3602
+ );
3578
3603
  React13.useEffect(() => {
3579
3604
  if (!open) {
3580
3605
  setQuery("");
@@ -3616,12 +3641,23 @@ var AddProcedureField = ({
3616
3641
  setTimeout(() => searchInputRef.current?.focus(), 0);
3617
3642
  }, ADD_FEEDBACK_MS3);
3618
3643
  }
3619
- function removeProcedure(id) {
3620
- onChange(value.filter((proc) => proc.id !== id));
3644
+ function removeAt(index) {
3645
+ onChange(value.filter((_, i) => i !== index));
3646
+ }
3647
+ function removeBySearchId(id) {
3648
+ onChange(value.filter((proc) => proc.is_custom || proc.id !== id));
3649
+ }
3650
+ function handleAddCustom() {
3651
+ const trimmed = query.trim();
3652
+ if (!trimmed) return;
3653
+ if (valueRef.current.some((p) => p.is_custom && p.name === trimmed)) return;
3654
+ onChange([...valueRef.current, createCustomProcedure(trimmed)]);
3655
+ setQuery("");
3656
+ setResults([]);
3621
3657
  }
3622
3658
  function handleRecentlyUsedToggle(result) {
3623
3659
  if (addedIds.has(result.id)) {
3624
- removeProcedure(result.id);
3660
+ removeBySearchId(result.id);
3625
3661
  } else {
3626
3662
  addProcedure(result);
3627
3663
  }
@@ -3631,7 +3667,7 @@ var AddProcedureField = ({
3631
3667
  const addedById = addedIds.has(id);
3632
3668
  const addedByName = value.some((proc) => proc.name === item.name);
3633
3669
  if (addedById || addedByName) {
3634
- if (addedById) removeProcedure(id);
3670
+ if (addedById) removeBySearchId(id);
3635
3671
  else onChange(value.filter((proc) => proc.name !== item.name));
3636
3672
  return;
3637
3673
  }
@@ -3639,7 +3675,7 @@ var AddProcedureField = ({
3639
3675
  try {
3640
3676
  const searchResults = await onSearch(item.name);
3641
3677
  const first = searchResults?.[0];
3642
- if (first && !valueRef.current.some((proc) => proc.id === first.id)) {
3678
+ if (first && !valueRef.current.some((proc) => !proc.is_custom && proc.id === first.id)) {
3643
3679
  onChange([...valueRef.current, mapToProcedure(first)]);
3644
3680
  }
3645
3681
  } finally {
@@ -3668,7 +3704,7 @@ var AddProcedureField = ({
3668
3704
  const limitedFrequentItems = frequentItems.slice(0, 25);
3669
3705
  const frequentItemChips = limitedFrequentItems.length > 0 ? limitedFrequentItems.map((item) => {
3670
3706
  const id = String(item.id);
3671
- const isAdded = value.some((proc) => proc.id === id) || value.some((proc) => proc.name === item.name);
3707
+ const isAdded = value.some((proc) => !proc.is_custom && proc.id === id) || value.some((proc) => proc.name === item.name);
3672
3708
  const isAdding = addingFrequentId === id;
3673
3709
  return /* @__PURE__ */ jsxRuntime.jsxs(
3674
3710
  "button",
@@ -3702,7 +3738,7 @@ var AddProcedureField = ({
3702
3738
  }
3703
3739
  )
3704
3740
  ] }),
3705
- value.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border rounded-lg border border-border overflow-hidden", children: value.map((proc) => /* @__PURE__ */ jsxRuntime.jsxs(
3741
+ value.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border rounded-lg border border-border overflow-hidden", children: value.map((proc, index) => /* @__PURE__ */ jsxRuntime.jsxs(
3706
3742
  "div",
3707
3743
  {
3708
3744
  className: "flex items-center justify-between px-3 py-2 bg-white hover:bg-gray-50",
@@ -3712,14 +3748,14 @@ var AddProcedureField = ({
3712
3748
  "button",
3713
3749
  {
3714
3750
  type: "button",
3715
- onClick: () => removeProcedure(proc.id),
3751
+ onClick: () => removeAt(index),
3716
3752
  className: "text-muted-foreground hover:text-red-500 transition-colors cursor-pointer",
3717
3753
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
3718
3754
  }
3719
3755
  )
3720
3756
  ]
3721
3757
  },
3722
- proc.id
3758
+ proc.is_custom ? `custom-${index}` : proc.id
3723
3759
  )) }),
3724
3760
  /* @__PURE__ */ jsxRuntime.jsx(
3725
3761
  AddEntityDialog,
@@ -3729,6 +3765,19 @@ var AddProcedureField = ({
3729
3765
  title: "Add Procedure",
3730
3766
  recentlyUsedSlot: frequentItemChips.length > 0 ? frequentItemChips : recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
3731
3767
  chipSectionLabel: frequentItemChips.length > 0 ? "Frequently used" : void 0,
3768
+ actionSlot: /* @__PURE__ */ jsxRuntime.jsx(
3769
+ "button",
3770
+ {
3771
+ type: "button",
3772
+ disabled: !query.trim() || valueRef.current.some((p) => p.is_custom && p.name === query.trim()),
3773
+ onClick: handleAddCustom,
3774
+ className: cn(
3775
+ "rounded-md px-5 py-2 text-sm font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-opacity cursor-pointer",
3776
+ (!query.trim() || valueRef.current.some((p) => p.is_custom && p.name === query.trim())) && "opacity-40 cursor-not-allowed"
3777
+ ),
3778
+ children: "Save Procedure"
3779
+ }
3780
+ ),
3732
3781
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
3733
3782
  /* @__PURE__ */ jsxRuntime.jsx(
3734
3783
  Input,