formanitor 0.0.15 → 0.0.17

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
@@ -368,7 +368,7 @@ var FormStore = class {
368
368
  }
369
369
  };
370
370
  this.config.onDraftChange?.(payload);
371
- }, 2500);
371
+ }, 5e3);
372
372
  }
373
373
  async save() {
374
374
  const payload = {
@@ -664,12 +664,27 @@ var FormStore = class {
664
664
  }
665
665
  };
666
666
  var FormContext = React11.createContext(null);
667
+ var emptyFrequentItems = {
668
+ medications: [],
669
+ investigations: [],
670
+ procedures: []
671
+ };
672
+ var FrequentItemsContext = React11.createContext(emptyFrequentItems);
667
673
  var FieldHandlersContext = React11.createContext({});
668
674
  function useFieldHandlers(fieldId) {
669
675
  const map = React11.useContext(FieldHandlersContext);
670
676
  return map[fieldId] ?? { onSearch: async () => [], recentlyUsed: [] };
671
677
  }
672
- var FormProvider = ({ schema, config, fieldHandlers, children }) => {
678
+ function useFrequentItems() {
679
+ return React11.useContext(FrequentItemsContext);
680
+ }
681
+ var FormProvider = ({
682
+ schema,
683
+ config,
684
+ fieldHandlers,
685
+ frequentItems,
686
+ children
687
+ }) => {
673
688
  const storeRef = React11.useRef(null);
674
689
  if (!storeRef.current) {
675
690
  storeRef.current = new FormStore(schema, config);
@@ -682,7 +697,8 @@ var FormProvider = ({ schema, config, fieldHandlers, children }) => {
682
697
  React11.useEffect(() => {
683
698
  storeRef.current?.load();
684
699
  }, []);
685
- return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children: /* @__PURE__ */ jsxRuntime.jsx(FieldHandlersContext.Provider, { value: fieldHandlers ?? {}, children }) });
700
+ const frequentItemsValue = frequentItems ?? emptyFrequentItems;
701
+ return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children: /* @__PURE__ */ jsxRuntime.jsx(FieldHandlersContext.Provider, { value: fieldHandlers ?? {}, children: /* @__PURE__ */ jsxRuntime.jsx(FrequentItemsContext.Provider, { value: frequentItemsValue, children }) }) });
686
702
  };
687
703
  function useFormStore() {
688
704
  const context = React11.useContext(FormContext);
@@ -2500,6 +2516,7 @@ var AddEntityDialog = ({
2500
2516
  onClose,
2501
2517
  title,
2502
2518
  recentlyUsedSlot,
2519
+ chipSectionLabel = "Recently Used",
2503
2520
  children,
2504
2521
  actionSlot
2505
2522
  }) => {
@@ -2507,7 +2524,7 @@ var AddEntityDialog = ({
2507
2524
  /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { className: "px-6 pt-6 pb-4 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "text-lg font-semibold", children: title }) }),
2508
2525
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 flex flex-col gap-4 overflow-y-auto flex-1 min-h-0 pb-4", children: [
2509
2526
  recentlyUsedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2510
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mb-2", children: "Recently Used" }),
2527
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mb-2", children: chipSectionLabel }),
2511
2528
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: recentlyUsedSlot })
2512
2529
  ] }),
2513
2530
  children
@@ -2532,9 +2549,9 @@ function mapToMedication(result) {
2532
2549
  };
2533
2550
  }
2534
2551
  function mapAIMedicationToMedication(ai) {
2535
- const id = typeof ai.id === "string" ? Number.parseInt(ai.id, 10) || 0 : Number(ai.id);
2552
+ const id = ai.id != null ? String(ai.id) : "";
2536
2553
  return {
2537
- id: Number.isNaN(id) ? 0 : id,
2554
+ id,
2538
2555
  brand_name: ai.brand_name ?? "",
2539
2556
  generic_name: ai.generic_name ?? "",
2540
2557
  frequency: "custom",
@@ -2550,7 +2567,7 @@ function mapAIMedicationToMedication(ai) {
2550
2567
  }
2551
2568
  function createCustomMedication(name, customId) {
2552
2569
  return {
2553
- id: customId,
2570
+ id: String(customId),
2554
2571
  brand_name: name.trim(),
2555
2572
  generic_name: "",
2556
2573
  frequency: "custom",
@@ -2564,6 +2581,39 @@ function createCustomMedication(name, customId) {
2564
2581
  notes: ""
2565
2582
  };
2566
2583
  }
2584
+ function parseDuration(duration) {
2585
+ if (!duration || !duration.trim()) return { value: "3", unit: "days" };
2586
+ const lower = duration.trim().toLowerCase();
2587
+ const match = lower.match(/^(\d+)\s*(day|days|week|weeks|month|months)?$/);
2588
+ if (!match) return { value: "3", unit: "days" };
2589
+ const value = match[1] ?? "3";
2590
+ const unitWord = match[2] ?? "days";
2591
+ const unit = unitWord.startsWith("month") ? "months" : unitWord.startsWith("week") ? "weeks" : "days";
2592
+ return { value, unit };
2593
+ }
2594
+ function mapFrequentItemToMedication(item) {
2595
+ const parsed = parseDuration(item.duration);
2596
+ const duration_value = item.duration_value ?? parsed.value;
2597
+ const duration_unit = item.duration_unit ?? parsed.unit;
2598
+ const before_after = item.before_after === "BEFORE FOOD" ? "BEFORE FOOD" : "AFTER FOOD";
2599
+ const routeNote = item.route ? `Route: ${item.route}` : "";
2600
+ const baseNotes = item.notes?.trim() || "";
2601
+ const combinedNotes = [baseNotes, routeNote.trim()].filter((part) => part.length > 0).join(" \u2014 ");
2602
+ return {
2603
+ id: item.id,
2604
+ brand_name: item.brand_name ?? item.name,
2605
+ generic_name: item.short_name ?? "",
2606
+ frequency: item.frequency ?? "custom",
2607
+ is_custom: false,
2608
+ duration_value,
2609
+ duration_unit,
2610
+ before_after,
2611
+ morning: item.morning ?? "0",
2612
+ afternoon: item.afternoon ?? "0",
2613
+ night: item.night ?? "0",
2614
+ notes: combinedNotes
2615
+ };
2616
+ }
2567
2617
  function Spinner({
2568
2618
  value,
2569
2619
  onChange
@@ -2611,11 +2661,14 @@ function MedicationCard({
2611
2661
  onChange: (e) => set("frequency", e.target.value),
2612
2662
  children: [
2613
2663
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "custom", children: "select frequency" }),
2614
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "OD", children: "OD" }),
2615
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "BD", children: "BD" }),
2616
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "TDS", children: "TDS" }),
2617
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "QID", children: "QID" }),
2618
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "SOS", children: "SOS" })
2664
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "qid", children: "4 times a day (QID)" }),
2665
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "alternate_day", children: "Alternate day" }),
2666
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "once_weekly", children: "Once weekly" }),
2667
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "once_monthly", children: "Once monthly" }),
2668
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "as_needed", children: "As needed" }),
2669
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "fort_night", children: "Fort night" }),
2670
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "at_bed_time", children: "At Bed time" }),
2671
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "sos", children: "SOS only" })
2619
2672
  ]
2620
2673
  }
2621
2674
  ),
@@ -2754,6 +2807,7 @@ var AddMedicationField = ({
2754
2807
  onChange,
2755
2808
  onSearch,
2756
2809
  recentlyUsed = [],
2810
+ frequentItems = [],
2757
2811
  suggestedMedications = []
2758
2812
  }) => {
2759
2813
  const [open, setOpen] = React11.useState(false);
@@ -2799,6 +2853,13 @@ var AddMedicationField = ({
2799
2853
  onChange([...safeValue, mapToMedication(result)]);
2800
2854
  }
2801
2855
  }
2856
+ function handleFrequentItemToggle(item) {
2857
+ if (addedIds.has(String(item.id))) {
2858
+ onChange(safeValue.filter((m) => String(m.id) !== String(item.id)));
2859
+ } else {
2860
+ onChange([...safeValue, mapFrequentItemToMedication(item)]);
2861
+ }
2862
+ }
2802
2863
  function handleResultClick(result) {
2803
2864
  if (addedIds.has(String(result.id))) return;
2804
2865
  setAddingResultId(result.id);
@@ -2849,6 +2910,26 @@ var AddMedicationField = ({
2849
2910
  r.id
2850
2911
  );
2851
2912
  });
2913
+ const limitedFrequentItems = frequentItems.slice(0, 25);
2914
+ const frequentItemChips = limitedFrequentItems.length > 0 ? limitedFrequentItems.map((item) => {
2915
+ const isAdded = addedIds.has(String(item.id));
2916
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2917
+ "button",
2918
+ {
2919
+ type: "button",
2920
+ onClick: () => handleFrequentItemToggle(item),
2921
+ className: cn(
2922
+ "rounded-full border text-[11px] px-2 py-0.5 transition-colors cursor-pointer",
2923
+ isAdded ? "border-green-300 bg-green-50 text-green-700" : "border-border bg-white hover:bg-gray-50"
2924
+ ),
2925
+ children: [
2926
+ isAdded && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1", children: "\u2713" }),
2927
+ item.brand_name ?? item.name
2928
+ ]
2929
+ },
2930
+ item.id
2931
+ );
2932
+ }) : [];
2852
2933
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md overflow-hidden flex flex-col border bg-white border-[#D0D0D0] space-y-3 p-3 h-fit", children: [
2853
2934
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2854
2935
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: label }),
@@ -2862,22 +2943,6 @@ var AddMedicationField = ({
2862
2943
  }
2863
2944
  )
2864
2945
  ] }),
2865
- suggestedMedications.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5 items-center", children: [
2866
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground mr-1", children: "Suggestions:" }),
2867
- suggestedMedications.filter((s) => !addedIds.has(String(s.id))).map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
2868
- "button",
2869
- {
2870
- type: "button",
2871
- onClick: () => handleAddSuggestion(s),
2872
- className: "inline-flex items-center gap-1 rounded-full border border-dashed border-purple-300 bg-purple-50/80 text-purple-800 text-xs px-2.5 py-1 hover:bg-purple-100 transition-colors cursor-pointer",
2873
- children: [
2874
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3" }),
2875
- s.brand_name || s.generic_name || String(s.id)
2876
- ]
2877
- },
2878
- String(s.id)
2879
- ))
2880
- ] }),
2881
2946
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: safeValue.map((med, i) => /* @__PURE__ */ jsxRuntime.jsx(
2882
2947
  MedicationCard,
2883
2948
  {
@@ -2893,7 +2958,8 @@ var AddMedicationField = ({
2893
2958
  open,
2894
2959
  onClose: () => setOpen(false),
2895
2960
  title: "Add Medication",
2896
- recentlyUsedSlot: recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
2961
+ recentlyUsedSlot: frequentItemChips.length > 0 ? frequentItemChips : recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
2962
+ chipSectionLabel: frequentItemChips.length > 0 ? "Frequently used" : void 0,
2897
2963
  actionSlot: /* @__PURE__ */ jsxRuntime.jsx(
2898
2964
  "button",
2899
2965
  {
@@ -2918,6 +2984,22 @@ var AddMedicationField = ({
2918
2984
  className: "border border-border rounded-md focus-visible:ring-0"
2919
2985
  }
2920
2986
  ),
2987
+ suggestedMedications.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5 items-center", children: [
2988
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground mr-1", children: "Suggestions:" }),
2989
+ suggestedMedications.filter((s) => !addedIds.has(String(s.id))).slice(0, 25).map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
2990
+ "button",
2991
+ {
2992
+ type: "button",
2993
+ onClick: () => handleAddSuggestion(s),
2994
+ className: "inline-flex items-center gap-1 rounded-full border border-dashed border-purple-300 bg-purple-50/80 text-purple-800 text-[11px] px-2 py-0.5 hover:bg-purple-100 transition-colors cursor-pointer",
2995
+ children: [
2996
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3" }),
2997
+ s.brand_name || s.generic_name || String(s.id)
2998
+ ]
2999
+ },
3000
+ String(s.id)
3001
+ ))
3002
+ ] }),
2921
3003
  loading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "Searching\u2026" }),
2922
3004
  !loading && results.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-2 max-h-64 overflow-y-auto", children: results.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
2923
3005
  SearchResultCard,
@@ -2937,6 +3019,7 @@ var AddMedicationWidget = ({ fieldId }) => {
2937
3019
  const { value, setValue } = useField(fieldId);
2938
3020
  const handlers = useFieldHandlers(fieldId);
2939
3021
  const { medications: suggestedMedications } = useAISuggestions();
3022
+ const { medications: frequentMedications } = useFrequentItems();
2940
3023
  const safeValue = Array.isArray(value) ? value : [];
2941
3024
  return /* @__PURE__ */ jsxRuntime.jsx(
2942
3025
  AddMedicationField,
@@ -2945,6 +3028,7 @@ var AddMedicationWidget = ({ fieldId }) => {
2945
3028
  onChange: setValue,
2946
3029
  onSearch: handlers.onSearch,
2947
3030
  recentlyUsed: handlers.recentlyUsed,
3031
+ frequentItems: frequentMedications,
2948
3032
  suggestedMedications
2949
3033
  }
2950
3034
  );
@@ -2963,13 +3047,15 @@ var AddInvestigationField = ({
2963
3047
  value,
2964
3048
  onChange,
2965
3049
  onSearch,
2966
- recentlyUsed = []
3050
+ recentlyUsed = [],
3051
+ frequentItems = []
2967
3052
  }) => {
2968
3053
  const [open, setOpen] = React11.useState(false);
2969
3054
  const [query, setQuery] = React11.useState("");
2970
3055
  const [results, setResults] = React11.useState([]);
2971
3056
  const [loading, setLoading] = React11.useState(false);
2972
3057
  const [addingId, setAddingId] = React11.useState(null);
3058
+ const [addingFrequentId, setAddingFrequentId] = React11.useState(null);
2973
3059
  const debounceRef = React11.useRef(null);
2974
3060
  const valueRef = React11.useRef([]);
2975
3061
  const searchInputRef = React11.useRef(null);
@@ -2980,6 +3066,7 @@ var AddInvestigationField = ({
2980
3066
  setQuery("");
2981
3067
  setResults([]);
2982
3068
  setAddingId(null);
3069
+ setAddingFrequentId(null);
2983
3070
  }
2984
3071
  }, [open]);
2985
3072
  function handleQueryChange(q) {
@@ -3025,6 +3112,26 @@ var AddInvestigationField = ({
3025
3112
  addInvestigation(result);
3026
3113
  }
3027
3114
  }
3115
+ async function handleFrequentItemToggle(item) {
3116
+ const id = String(item.id);
3117
+ const addedById = addedIds.has(id);
3118
+ const addedByName = value.some((inv) => inv.name === item.name);
3119
+ if (addedById || addedByName) {
3120
+ if (addedById) removeInvestigation(id);
3121
+ else onChange(value.filter((inv) => inv.name !== item.name));
3122
+ return;
3123
+ }
3124
+ setAddingFrequentId(id);
3125
+ try {
3126
+ const searchResults = await onSearch(item.name);
3127
+ const first = searchResults?.[0];
3128
+ if (first && !valueRef.current.some((inv) => inv.id === first.id)) {
3129
+ onChange([...valueRef.current, mapToInvestigation(first)]);
3130
+ }
3131
+ } finally {
3132
+ setAddingFrequentId(null);
3133
+ }
3134
+ }
3028
3135
  const recentlyUsedChips = recentlyUsed.map((r) => {
3029
3136
  const isAdded = addedIds.has(r.id);
3030
3137
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3044,6 +3151,30 @@ var AddInvestigationField = ({
3044
3151
  r.id
3045
3152
  );
3046
3153
  });
3154
+ const limitedFrequentItems = frequentItems.slice(0, 25);
3155
+ const frequentItemChips = limitedFrequentItems.length > 0 ? limitedFrequentItems.map((item) => {
3156
+ const id = String(item.id);
3157
+ const isAdded = value.some((inv) => inv.id === id) || value.some((inv) => inv.name === item.name);
3158
+ const isAdding = addingFrequentId === id;
3159
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3160
+ "button",
3161
+ {
3162
+ type: "button",
3163
+ disabled: isAdding,
3164
+ onClick: () => handleFrequentItemToggle(item),
3165
+ className: cn(
3166
+ "rounded-full border text-xs px-3 py-1 transition-colors",
3167
+ isAdded ? "border-green-300 bg-green-50 text-green-700" : "border-border bg-white hover:bg-gray-50",
3168
+ isAdding && "opacity-70 pointer-events-none"
3169
+ ),
3170
+ children: [
3171
+ isAdded && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1", children: "\u2713" }),
3172
+ isAdding ? "\u2026" : item.name
3173
+ ]
3174
+ },
3175
+ item.id
3176
+ );
3177
+ }) : [];
3047
3178
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit", children: [
3048
3179
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
3049
3180
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: label }),
@@ -3082,7 +3213,8 @@ var AddInvestigationField = ({
3082
3213
  open,
3083
3214
  onClose: () => setOpen(false),
3084
3215
  title: "Add Investigation",
3085
- recentlyUsedSlot: recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
3216
+ recentlyUsedSlot: frequentItemChips.length > 0 ? frequentItemChips : recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
3217
+ chipSectionLabel: frequentItemChips.length > 0 ? "Frequently used" : void 0,
3086
3218
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
3087
3219
  /* @__PURE__ */ jsxRuntime.jsx(
3088
3220
  Input,
@@ -3122,13 +3254,15 @@ var AddInvestigationField = ({
3122
3254
  var AddInvestigationWidget = ({ fieldId }) => {
3123
3255
  const { value, setValue } = useField(fieldId);
3124
3256
  const handlers = useFieldHandlers(fieldId);
3257
+ const { investigations: frequentInvestigations } = useFrequentItems();
3125
3258
  return /* @__PURE__ */ jsxRuntime.jsx(
3126
3259
  AddInvestigationField,
3127
3260
  {
3128
3261
  value: value ?? [],
3129
3262
  onChange: setValue,
3130
3263
  onSearch: handlers.onSearch,
3131
- recentlyUsed: handlers.recentlyUsed
3264
+ recentlyUsed: handlers.recentlyUsed,
3265
+ frequentItems: frequentInvestigations
3132
3266
  }
3133
3267
  );
3134
3268
  };
@@ -3146,13 +3280,15 @@ var AddProcedureField = ({
3146
3280
  value,
3147
3281
  onChange,
3148
3282
  onSearch,
3149
- recentlyUsed = []
3283
+ recentlyUsed = [],
3284
+ frequentItems = []
3150
3285
  }) => {
3151
3286
  const [open, setOpen] = React11.useState(false);
3152
3287
  const [query, setQuery] = React11.useState("");
3153
3288
  const [results, setResults] = React11.useState([]);
3154
3289
  const [loading, setLoading] = React11.useState(false);
3155
3290
  const [addingId, setAddingId] = React11.useState(null);
3291
+ const [addingFrequentId, setAddingFrequentId] = React11.useState(null);
3156
3292
  const debounceRef = React11.useRef(null);
3157
3293
  const valueRef = React11.useRef([]);
3158
3294
  const searchInputRef = React11.useRef(null);
@@ -3163,6 +3299,7 @@ var AddProcedureField = ({
3163
3299
  setQuery("");
3164
3300
  setResults([]);
3165
3301
  setAddingId(null);
3302
+ setAddingFrequentId(null);
3166
3303
  }
3167
3304
  }, [open]);
3168
3305
  function handleQueryChange(q) {
@@ -3208,6 +3345,26 @@ var AddProcedureField = ({
3208
3345
  addProcedure(result);
3209
3346
  }
3210
3347
  }
3348
+ async function handleFrequentItemToggle(item) {
3349
+ const id = String(item.id);
3350
+ const addedById = addedIds.has(id);
3351
+ const addedByName = value.some((proc) => proc.name === item.name);
3352
+ if (addedById || addedByName) {
3353
+ if (addedById) removeProcedure(id);
3354
+ else onChange(value.filter((proc) => proc.name !== item.name));
3355
+ return;
3356
+ }
3357
+ setAddingFrequentId(id);
3358
+ try {
3359
+ const searchResults = await onSearch(item.name);
3360
+ const first = searchResults?.[0];
3361
+ if (first && !valueRef.current.some((proc) => proc.id === first.id)) {
3362
+ onChange([...valueRef.current, mapToProcedure(first)]);
3363
+ }
3364
+ } finally {
3365
+ setAddingFrequentId(null);
3366
+ }
3367
+ }
3211
3368
  const recentlyUsedChips = recentlyUsed.map((r) => {
3212
3369
  const isAdded = addedIds.has(r.id);
3213
3370
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3227,6 +3384,30 @@ var AddProcedureField = ({
3227
3384
  r.id
3228
3385
  );
3229
3386
  });
3387
+ const limitedFrequentItems = frequentItems.slice(0, 25);
3388
+ const frequentItemChips = limitedFrequentItems.length > 0 ? limitedFrequentItems.map((item) => {
3389
+ const id = String(item.id);
3390
+ const isAdded = value.some((proc) => proc.id === id) || value.some((proc) => proc.name === item.name);
3391
+ const isAdding = addingFrequentId === id;
3392
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3393
+ "button",
3394
+ {
3395
+ type: "button",
3396
+ disabled: isAdding,
3397
+ onClick: () => handleFrequentItemToggle(item),
3398
+ className: cn(
3399
+ "rounded-full border text-xs px-3 py-1 transition-colors",
3400
+ isAdded ? "border-green-300 bg-green-50 text-green-700" : "border-border bg-white hover:bg-gray-50",
3401
+ isAdding && "opacity-70 pointer-events-none"
3402
+ ),
3403
+ children: [
3404
+ isAdded && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1", children: "\u2713" }),
3405
+ isAdding ? "\u2026" : item.name
3406
+ ]
3407
+ },
3408
+ item.id
3409
+ );
3410
+ }) : [];
3230
3411
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md overflow-hidden flex flex-col bg-white border border-[#D0D0D0] space-y-3 p-3 h-fit", children: [
3231
3412
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
3232
3413
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: label }),
@@ -3265,7 +3446,8 @@ var AddProcedureField = ({
3265
3446
  open,
3266
3447
  onClose: () => setOpen(false),
3267
3448
  title: "Add Procedure",
3268
- recentlyUsedSlot: recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
3449
+ recentlyUsedSlot: frequentItemChips.length > 0 ? frequentItemChips : recentlyUsedChips.length > 0 ? recentlyUsedChips : void 0,
3450
+ chipSectionLabel: frequentItemChips.length > 0 ? "Frequently used" : void 0,
3269
3451
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
3270
3452
  /* @__PURE__ */ jsxRuntime.jsx(
3271
3453
  Input,
@@ -3305,13 +3487,15 @@ var AddProcedureField = ({
3305
3487
  var AddProcedureWidget = ({ fieldId }) => {
3306
3488
  const { value, setValue } = useField(fieldId);
3307
3489
  const handlers = useFieldHandlers(fieldId);
3490
+ const { procedures: frequentProcedures } = useFrequentItems();
3308
3491
  return /* @__PURE__ */ jsxRuntime.jsx(
3309
3492
  AddProcedureField,
3310
3493
  {
3311
3494
  value: value ?? [],
3312
3495
  onChange: setValue,
3313
3496
  onSearch: handlers.onSearch,
3314
- recentlyUsed: handlers.recentlyUsed
3497
+ recentlyUsed: handlers.recentlyUsed,
3498
+ frequentItems: frequentProcedures
3315
3499
  }
3316
3500
  );
3317
3501
  };
@@ -5647,6 +5831,7 @@ exports.useField = useField;
5647
5831
  exports.useFieldHandlers = useFieldHandlers;
5648
5832
  exports.useForm = useForm;
5649
5833
  exports.useFormStore = useFormStore;
5834
+ exports.useFrequentItems = useFrequentItems;
5650
5835
  exports.useSmartKeywords = useSmartKeywords;
5651
5836
  exports.validateField = validateField;
5652
5837
  exports.validateForm = validateForm;