formanitor 0.0.47 → 0.0.49
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 +677 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -4
- package/dist/index.d.ts +99 -4
- package/dist/index.mjs +678 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import { Slot } from '@radix-ui/react-slot';
|
|
|
14
14
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
15
15
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
16
16
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
17
|
-
import { format, addDays, addWeeks,
|
|
17
|
+
import { format, addDays, addWeeks, differenceInCalendarDays, parseISO } from 'date-fns';
|
|
18
18
|
import { DayPicker } from 'react-day-picker';
|
|
19
19
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
20
20
|
import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
@@ -32,8 +32,25 @@ function fieldMetaRequestsMarMedicationOrdersButton(meta) {
|
|
|
32
32
|
|
|
33
33
|
// src/core/validate.ts
|
|
34
34
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
35
|
-
function validateField(value, field) {
|
|
35
|
+
function validateField(value, field, allValues) {
|
|
36
36
|
if (field.hidden || field.disabled) return null;
|
|
37
|
+
if (field.type === "otp_input") {
|
|
38
|
+
if (field.required) {
|
|
39
|
+
if (!value || typeof value !== "object" || value.verified !== true) {
|
|
40
|
+
return "Please verify your mobile number with OTP";
|
|
41
|
+
}
|
|
42
|
+
const otpField = field;
|
|
43
|
+
const phoneFieldId = otpField.meta?.phoneFieldId ?? "phone";
|
|
44
|
+
if (allValues) {
|
|
45
|
+
const phoneRaw = allValues[phoneFieldId] ?? "";
|
|
46
|
+
const e164 = phoneRaw.startsWith("+") ? phoneRaw : `+91${phoneRaw}`;
|
|
47
|
+
if (value.phone && value.phone !== e164) {
|
|
48
|
+
return "Mobile number changed \u2014 please re-verify";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
37
54
|
if (field.required) {
|
|
38
55
|
if (value === null || value === void 0 || value === "") {
|
|
39
56
|
return "This field is required";
|
|
@@ -94,7 +111,7 @@ function validateForm(values, fields) {
|
|
|
94
111
|
const errors = {};
|
|
95
112
|
for (const [key, field] of Object.entries(fields)) {
|
|
96
113
|
if (field.type === "static_text") continue;
|
|
97
|
-
const error = validateField(values[key], field);
|
|
114
|
+
const error = validateField(values[key], field, values);
|
|
98
115
|
if (error) {
|
|
99
116
|
errors[key] = error;
|
|
100
117
|
}
|
|
@@ -1171,6 +1188,9 @@ var FormStore = class {
|
|
|
1171
1188
|
persistence;
|
|
1172
1189
|
prefillData = {};
|
|
1173
1190
|
config;
|
|
1191
|
+
// Widget-owned errors that schema validation cannot express (e.g. "OTP not sent yet").
|
|
1192
|
+
// Merged on top of validateForm output in evaluate().
|
|
1193
|
+
externalErrors = {};
|
|
1174
1194
|
// Cache for debounce
|
|
1175
1195
|
saveTimeout = null;
|
|
1176
1196
|
draftCallbackTimeout = null;
|
|
@@ -1290,6 +1310,9 @@ var FormStore = class {
|
|
|
1290
1310
|
getSchema() {
|
|
1291
1311
|
return this.schema;
|
|
1292
1312
|
}
|
|
1313
|
+
getConfig() {
|
|
1314
|
+
return this.config;
|
|
1315
|
+
}
|
|
1293
1316
|
getFieldDef(fieldId) {
|
|
1294
1317
|
return this.fieldMap[fieldId];
|
|
1295
1318
|
}
|
|
@@ -1337,6 +1360,17 @@ var FormStore = class {
|
|
|
1337
1360
|
this.notify();
|
|
1338
1361
|
this.scheduleSave();
|
|
1339
1362
|
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Let a widget report an error that schema validation cannot express
|
|
1365
|
+
* (e.g. "Send OTP to continue" until the API call succeeds).
|
|
1366
|
+
* Pass `null` to clear a previously set external error.
|
|
1367
|
+
*/
|
|
1368
|
+
setExternalError(fieldId, message) {
|
|
1369
|
+
if ((this.externalErrors[fieldId] ?? null) === message) return;
|
|
1370
|
+
this.externalErrors = { ...this.externalErrors, [fieldId]: message };
|
|
1371
|
+
this.evaluate();
|
|
1372
|
+
this.notify();
|
|
1373
|
+
}
|
|
1340
1374
|
setTouched(fieldId) {
|
|
1341
1375
|
if (this.state.touched[fieldId]) return;
|
|
1342
1376
|
this.state.touched = { ...this.state.touched, [fieldId]: true };
|
|
@@ -1465,6 +1499,20 @@ var FormStore = class {
|
|
|
1465
1499
|
result[field.id] = parts.length > 0 ? parts.join("\n\n") : null;
|
|
1466
1500
|
return;
|
|
1467
1501
|
}
|
|
1502
|
+
if (field.type === "otp_input") {
|
|
1503
|
+
const raw = values[field.id];
|
|
1504
|
+
if (typeof raw === "string") {
|
|
1505
|
+
result[field.id] = raw;
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && raw.verified === true) {
|
|
1509
|
+
const code = raw.code;
|
|
1510
|
+
result[field.id] = typeof code === "string" ? code : null;
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
result[field.id] = null;
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1468
1516
|
if (field.type === "image_upload" || field.type === "media_upload" || field.type === "signature") {
|
|
1469
1517
|
const raw = values[field.id];
|
|
1470
1518
|
if (raw !== void 0 && raw !== null && raw !== "") {
|
|
@@ -1581,8 +1629,12 @@ var FormStore = class {
|
|
|
1581
1629
|
};
|
|
1582
1630
|
});
|
|
1583
1631
|
const errors = validateForm(this.state.values, effectiveFields);
|
|
1584
|
-
|
|
1585
|
-
|
|
1632
|
+
const merged = { ...errors };
|
|
1633
|
+
for (const [id, msg] of Object.entries(this.externalErrors)) {
|
|
1634
|
+
if (msg) merged[id] = msg;
|
|
1635
|
+
}
|
|
1636
|
+
this.state.errors = merged;
|
|
1637
|
+
this.state.isValid = Object.keys(merged).length === 0;
|
|
1586
1638
|
}
|
|
1587
1639
|
// --- Workflow ---
|
|
1588
1640
|
getAvailableTransitions() {
|
|
@@ -5839,15 +5891,21 @@ var UNIT_OPTIONS = [
|
|
|
5839
5891
|
{ value: "weeks", label: "Weeks" },
|
|
5840
5892
|
{ value: "months", label: "Months" }
|
|
5841
5893
|
];
|
|
5894
|
+
var DAYS_PER_MONTH = 30;
|
|
5842
5895
|
function durationToDays(valueNum, unit) {
|
|
5843
5896
|
const today = /* @__PURE__ */ new Date();
|
|
5844
5897
|
today.setHours(0, 0, 0, 0);
|
|
5845
5898
|
let target;
|
|
5846
5899
|
if (unit === "days") target = addDays(today, valueNum);
|
|
5847
5900
|
else if (unit === "weeks") target = addWeeks(today, valueNum);
|
|
5848
|
-
else target =
|
|
5901
|
+
else target = addDays(today, valueNum * DAYS_PER_MONTH);
|
|
5849
5902
|
return Math.max(0, differenceInCalendarDays(target, today));
|
|
5850
5903
|
}
|
|
5904
|
+
function daysToDisplayCount(daysNum, unit) {
|
|
5905
|
+
if (unit === "days") return Math.max(0, daysNum);
|
|
5906
|
+
if (unit === "weeks") return Math.round(daysNum / 7) || 1;
|
|
5907
|
+
return Math.round(daysNum / DAYS_PER_MONTH) || 1;
|
|
5908
|
+
}
|
|
5851
5909
|
function dateToDays(date) {
|
|
5852
5910
|
const today = /* @__PURE__ */ new Date();
|
|
5853
5911
|
today.setHours(0, 0, 0, 0);
|
|
@@ -5915,9 +5973,7 @@ var FollowupWidget = ({ fieldId }) => {
|
|
|
5915
5973
|
const daysNum = hasFollowup ? parseInt(followup.value, 10) || 7 : 7;
|
|
5916
5974
|
const currentDate = hasFollowup ? daysToDate(daysNum) : null;
|
|
5917
5975
|
const followupMode = displayMode;
|
|
5918
|
-
const currentValue = hasFollowup
|
|
5919
|
-
displayUnit === "weeks" ? Math.round(daysNum / 7) || 1 : Math.round(daysNum / 30) || 1
|
|
5920
|
-
) : "7";
|
|
5976
|
+
const currentValue = hasFollowup ? String(daysToDisplayCount(daysNum, displayUnit)) : "7";
|
|
5921
5977
|
const currentUnit = displayUnit;
|
|
5922
5978
|
const handleFollowupTypeChange = useCallback(
|
|
5923
5979
|
(newType) => {
|
|
@@ -5954,9 +6010,18 @@ var FollowupWidget = ({ fieldId }) => {
|
|
|
5954
6010
|
},
|
|
5955
6011
|
[displayUnit, setValue, setTouched]
|
|
5956
6012
|
);
|
|
5957
|
-
const handleUnitChange = useCallback(
|
|
5958
|
-
|
|
5959
|
-
|
|
6013
|
+
const handleUnitChange = useCallback(
|
|
6014
|
+
(newUnit) => {
|
|
6015
|
+
if (newUnit === displayUnit) return;
|
|
6016
|
+
const n = daysToDisplayCount(daysNum, displayUnit);
|
|
6017
|
+
setDisplayUnit(newUnit);
|
|
6018
|
+
if (!hasFollowup) return;
|
|
6019
|
+
setTouched();
|
|
6020
|
+
const newDays = durationToDays(n, newUnit);
|
|
6021
|
+
setValue({ followupType: "one time", value: String(newDays), unit: "days" });
|
|
6022
|
+
},
|
|
6023
|
+
[displayUnit, daysNum, hasFollowup, setValue, setTouched]
|
|
6024
|
+
);
|
|
5960
6025
|
const handleDateSelect = useCallback(
|
|
5961
6026
|
(selected) => {
|
|
5962
6027
|
setTouched();
|
|
@@ -13762,6 +13827,347 @@ var OBGPathwayWidget = ({ fieldId }) => {
|
|
|
13762
13827
|
] })
|
|
13763
13828
|
] });
|
|
13764
13829
|
};
|
|
13830
|
+
var RESEND_COOLDOWN_SECONDS = 30;
|
|
13831
|
+
var PhoneInputWidget = ({ fieldId }) => {
|
|
13832
|
+
const { fieldDef, error, touched, disabled, value: fieldValue } = useField(fieldId);
|
|
13833
|
+
const { state } = useForm();
|
|
13834
|
+
const store = useFormStore();
|
|
13835
|
+
const rawPhone = fieldValue ?? "";
|
|
13836
|
+
const wasAlreadySent = rawPhone.length === 10 && !error;
|
|
13837
|
+
const [status, setStatus] = useState(wasAlreadySent ? "sent" : "idle");
|
|
13838
|
+
const [resendCooldown, setResendCooldown] = useState(0);
|
|
13839
|
+
const [resendError, setResendError] = useState("");
|
|
13840
|
+
const hasSentRef = useRef(wasAlreadySent);
|
|
13841
|
+
const sentPhoneRef = useRef(wasAlreadySent ? rawPhone : "");
|
|
13842
|
+
const isSendingRef = useRef(false);
|
|
13843
|
+
const isResendingRef = useRef(false);
|
|
13844
|
+
const showError = !!error && (touched || state.submitAttempted) && status !== "sending" && status !== "sent";
|
|
13845
|
+
useEffect(() => {
|
|
13846
|
+
if (resendCooldown <= 0) return;
|
|
13847
|
+
const t = setTimeout(() => setResendCooldown((c) => Math.max(0, c - 1)), 1e3);
|
|
13848
|
+
return () => clearTimeout(t);
|
|
13849
|
+
}, [resendCooldown]);
|
|
13850
|
+
if (!fieldDef) return null;
|
|
13851
|
+
const placeholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : "Enter 10-digit mobile number";
|
|
13852
|
+
const handleChange = (e) => {
|
|
13853
|
+
const digits = e.target.value.replace(/\D/g, "").slice(0, 10);
|
|
13854
|
+
if (hasSentRef.current && digits !== sentPhoneRef.current) {
|
|
13855
|
+
hasSentRef.current = false;
|
|
13856
|
+
sentPhoneRef.current = "";
|
|
13857
|
+
setStatus("idle");
|
|
13858
|
+
setResendCooldown(0);
|
|
13859
|
+
setResendError("");
|
|
13860
|
+
store.setExternalError(fieldId, "Send OTP to continue");
|
|
13861
|
+
const otpFieldId = fieldDef.meta?.otpFieldId;
|
|
13862
|
+
if (otpFieldId) {
|
|
13863
|
+
store.setValue(otpFieldId, "");
|
|
13864
|
+
store.setExternalError(otpFieldId, "Verify OTP to continue");
|
|
13865
|
+
}
|
|
13866
|
+
}
|
|
13867
|
+
store.setValue(fieldId, digits);
|
|
13868
|
+
if (digits.length === 10 && !hasSentRef.current && !isSendingRef.current) {
|
|
13869
|
+
sendOtp(digits);
|
|
13870
|
+
}
|
|
13871
|
+
};
|
|
13872
|
+
const sendOtp = async (phone) => {
|
|
13873
|
+
if (isSendingRef.current) return;
|
|
13874
|
+
isSendingRef.current = true;
|
|
13875
|
+
setStatus("sending");
|
|
13876
|
+
store.setExternalError(fieldId, "Sending OTP...");
|
|
13877
|
+
try {
|
|
13878
|
+
const authCfg = store.getConfig().auth;
|
|
13879
|
+
const base = authCfg?.baseUrl ?? ((typeof process !== "undefined" && process.env?.NEXT_PUBLIC_API_URL) ?? "");
|
|
13880
|
+
const sendPath = authCfg?.sendPath ?? "/api/auth/otp/send/";
|
|
13881
|
+
const countryCode = authCfg?.defaultCountryCode ?? "+91";
|
|
13882
|
+
const res = await fetch(`${base}${sendPath}`, {
|
|
13883
|
+
method: "POST",
|
|
13884
|
+
headers: { "Content-Type": "application/json" },
|
|
13885
|
+
body: JSON.stringify({ mobile_number: `${countryCode}${phone}` })
|
|
13886
|
+
});
|
|
13887
|
+
const data = await res.json().catch(() => ({}));
|
|
13888
|
+
if (res.ok) {
|
|
13889
|
+
hasSentRef.current = true;
|
|
13890
|
+
sentPhoneRef.current = phone;
|
|
13891
|
+
setStatus("sent");
|
|
13892
|
+
setResendCooldown(RESEND_COOLDOWN_SECONDS);
|
|
13893
|
+
store.setExternalError(fieldId, null);
|
|
13894
|
+
} else {
|
|
13895
|
+
setStatus("error");
|
|
13896
|
+
store.setExternalError(fieldId, data.error ?? "Failed to send OTP. Please try again.");
|
|
13897
|
+
}
|
|
13898
|
+
} catch {
|
|
13899
|
+
setStatus("error");
|
|
13900
|
+
store.setExternalError(fieldId, "Network error. Please try again.");
|
|
13901
|
+
} finally {
|
|
13902
|
+
isSendingRef.current = false;
|
|
13903
|
+
}
|
|
13904
|
+
};
|
|
13905
|
+
const handleResend = async () => {
|
|
13906
|
+
if (isResendingRef.current || resendCooldown > 0) return;
|
|
13907
|
+
isResendingRef.current = true;
|
|
13908
|
+
setResendError("");
|
|
13909
|
+
try {
|
|
13910
|
+
const authCfg = store.getConfig().auth;
|
|
13911
|
+
const base = authCfg?.baseUrl ?? ((typeof process !== "undefined" && process.env?.NEXT_PUBLIC_API_URL) ?? "");
|
|
13912
|
+
const resendPath = authCfg?.resendPath ?? "/api/auth/otp/resend/";
|
|
13913
|
+
const countryCode = authCfg?.defaultCountryCode ?? "+91";
|
|
13914
|
+
const res = await fetch(`${base}${resendPath}`, {
|
|
13915
|
+
method: "POST",
|
|
13916
|
+
headers: { "Content-Type": "application/json" },
|
|
13917
|
+
body: JSON.stringify({ mobile_number: `${countryCode}${rawPhone}`, retrytype: "text" })
|
|
13918
|
+
});
|
|
13919
|
+
const data = await res.json().catch(() => ({}));
|
|
13920
|
+
if (res.ok) {
|
|
13921
|
+
setResendCooldown(RESEND_COOLDOWN_SECONDS);
|
|
13922
|
+
setResendError("");
|
|
13923
|
+
} else {
|
|
13924
|
+
setResendError(data.error ?? "Failed to resend OTP. Please try again.");
|
|
13925
|
+
}
|
|
13926
|
+
} catch {
|
|
13927
|
+
setResendError("Network error. Please try again.");
|
|
13928
|
+
} finally {
|
|
13929
|
+
isResendingRef.current = false;
|
|
13930
|
+
}
|
|
13931
|
+
};
|
|
13932
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
13933
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
13934
|
+
fieldDef.label,
|
|
13935
|
+
" ",
|
|
13936
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
13937
|
+
] }),
|
|
13938
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
13939
|
+
/* @__PURE__ */ jsx(
|
|
13940
|
+
Input,
|
|
13941
|
+
{
|
|
13942
|
+
id: fieldId,
|
|
13943
|
+
type: "tel",
|
|
13944
|
+
inputMode: "numeric",
|
|
13945
|
+
value: rawPhone,
|
|
13946
|
+
onChange: handleChange,
|
|
13947
|
+
onBlur: () => store.setTouched(fieldId),
|
|
13948
|
+
disabled: disabled || status === "sending",
|
|
13949
|
+
placeholder,
|
|
13950
|
+
maxLength: 10,
|
|
13951
|
+
className: cn(
|
|
13952
|
+
showError && "border-red-500",
|
|
13953
|
+
status === "sent" && "border-green-500 pr-9",
|
|
13954
|
+
status === "sending" && "pr-9"
|
|
13955
|
+
)
|
|
13956
|
+
}
|
|
13957
|
+
),
|
|
13958
|
+
status === "sending" && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxs(
|
|
13959
|
+
"svg",
|
|
13960
|
+
{
|
|
13961
|
+
className: "animate-spin h-4 w-4 text-muted-foreground",
|
|
13962
|
+
viewBox: "0 0 24 24",
|
|
13963
|
+
fill: "none",
|
|
13964
|
+
children: [
|
|
13965
|
+
/* @__PURE__ */ jsx(
|
|
13966
|
+
"circle",
|
|
13967
|
+
{
|
|
13968
|
+
className: "opacity-25",
|
|
13969
|
+
cx: "12",
|
|
13970
|
+
cy: "12",
|
|
13971
|
+
r: "10",
|
|
13972
|
+
stroke: "currentColor",
|
|
13973
|
+
strokeWidth: "4"
|
|
13974
|
+
}
|
|
13975
|
+
),
|
|
13976
|
+
/* @__PURE__ */ jsx(
|
|
13977
|
+
"path",
|
|
13978
|
+
{
|
|
13979
|
+
className: "opacity-75",
|
|
13980
|
+
fill: "currentColor",
|
|
13981
|
+
d: "M4 12a8 8 0 018-8v8H4z"
|
|
13982
|
+
}
|
|
13983
|
+
)
|
|
13984
|
+
]
|
|
13985
|
+
}
|
|
13986
|
+
) }),
|
|
13987
|
+
status === "sent" && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsx(
|
|
13988
|
+
"svg",
|
|
13989
|
+
{
|
|
13990
|
+
className: "h-4 w-4 text-green-500",
|
|
13991
|
+
viewBox: "0 0 20 20",
|
|
13992
|
+
fill: "currentColor",
|
|
13993
|
+
children: /* @__PURE__ */ jsx(
|
|
13994
|
+
"path",
|
|
13995
|
+
{
|
|
13996
|
+
fillRule: "evenodd",
|
|
13997
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
13998
|
+
clipRule: "evenodd"
|
|
13999
|
+
}
|
|
14000
|
+
)
|
|
14001
|
+
}
|
|
14002
|
+
) })
|
|
14003
|
+
] }),
|
|
14004
|
+
status === "sent" && /* @__PURE__ */ jsxs("p", { className: "text-xs text-green-600", children: [
|
|
14005
|
+
"OTP sent to +91",
|
|
14006
|
+
rawPhone
|
|
14007
|
+
] }),
|
|
14008
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error }),
|
|
14009
|
+
status === "sent" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
14010
|
+
/* @__PURE__ */ jsx("span", { children: "Didn't receive it?" }),
|
|
14011
|
+
/* @__PURE__ */ jsx(
|
|
14012
|
+
"button",
|
|
14013
|
+
{
|
|
14014
|
+
type: "button",
|
|
14015
|
+
onClick: handleResend,
|
|
14016
|
+
disabled: resendCooldown > 0,
|
|
14017
|
+
className: cn(
|
|
14018
|
+
"underline transition-colors",
|
|
14019
|
+
resendCooldown > 0 ? "opacity-40 cursor-not-allowed" : "text-primary hover:text-primary/80 cursor-pointer"
|
|
14020
|
+
),
|
|
14021
|
+
children: resendCooldown > 0 ? `Resend in ${resendCooldown}s` : "Resend OTP"
|
|
14022
|
+
}
|
|
14023
|
+
)
|
|
14024
|
+
] }),
|
|
14025
|
+
resendError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: resendError })
|
|
14026
|
+
] });
|
|
14027
|
+
};
|
|
14028
|
+
var OtpInputWidget = ({ fieldId }) => {
|
|
14029
|
+
const { fieldDef, error, touched, disabled } = useField(fieldId);
|
|
14030
|
+
const { state } = useForm();
|
|
14031
|
+
const store = useFormStore();
|
|
14032
|
+
const phoneFieldId = fieldDef?.meta?.phoneFieldId ?? "phone";
|
|
14033
|
+
const { value: phoneValue } = useField(phoneFieldId);
|
|
14034
|
+
const phone = phoneValue ?? "";
|
|
14035
|
+
const e164Phone = phone.startsWith("+") ? phone : `+91${phone}`;
|
|
14036
|
+
const [otp, setOtp] = useState("");
|
|
14037
|
+
const [status, setStatus] = useState("idle");
|
|
14038
|
+
const isVerifyingRef = useRef(false);
|
|
14039
|
+
const showError = !!error && (touched || state.submitAttempted) && status !== "verifying" && status !== "verified";
|
|
14040
|
+
if (!fieldDef) return null;
|
|
14041
|
+
const placeholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : "Enter 4-digit OTP";
|
|
14042
|
+
const handleChange = (e) => {
|
|
14043
|
+
const digits = e.target.value.replace(/\D/g, "").slice(0, 4);
|
|
14044
|
+
if (status === "failed") {
|
|
14045
|
+
setStatus("idle");
|
|
14046
|
+
store.setExternalError(fieldId, null);
|
|
14047
|
+
}
|
|
14048
|
+
setOtp(digits);
|
|
14049
|
+
store.setValue(fieldId, digits);
|
|
14050
|
+
if (digits.length === 4 && !isVerifyingRef.current) {
|
|
14051
|
+
verifyOtp(digits);
|
|
14052
|
+
}
|
|
14053
|
+
};
|
|
14054
|
+
const verifyOtp = async (code) => {
|
|
14055
|
+
if (isVerifyingRef.current) return;
|
|
14056
|
+
isVerifyingRef.current = true;
|
|
14057
|
+
setStatus("verifying");
|
|
14058
|
+
store.setExternalError(fieldId, "Verifying...");
|
|
14059
|
+
try {
|
|
14060
|
+
const authCfg = store.getConfig().auth;
|
|
14061
|
+
const base = authCfg?.baseUrl ?? ((typeof process !== "undefined" && process.env?.NEXT_PUBLIC_API_URL) ?? "");
|
|
14062
|
+
const verifyPath = authCfg?.verifyPath ?? "/api/auth/otp/verify/";
|
|
14063
|
+
const res = await fetch(`${base}${verifyPath}`, {
|
|
14064
|
+
method: "POST",
|
|
14065
|
+
headers: { "Content-Type": "application/json" },
|
|
14066
|
+
body: JSON.stringify({ mobile_number: e164Phone, otp_code: code })
|
|
14067
|
+
});
|
|
14068
|
+
const data = await res.json().catch(() => ({}));
|
|
14069
|
+
if (res.ok) {
|
|
14070
|
+
setStatus("verified");
|
|
14071
|
+
store.setExternalError(fieldId, null);
|
|
14072
|
+
store.setValue(fieldId, {
|
|
14073
|
+
verified: true,
|
|
14074
|
+
phone: e164Phone,
|
|
14075
|
+
code,
|
|
14076
|
+
...data?.verification_token ? { token: data.verification_token } : {}
|
|
14077
|
+
});
|
|
14078
|
+
} else {
|
|
14079
|
+
setStatus("failed");
|
|
14080
|
+
const msg = data.error ?? "Invalid OTP. Please try again.";
|
|
14081
|
+
store.setExternalError(fieldId, msg);
|
|
14082
|
+
setOtp("");
|
|
14083
|
+
store.setValue(fieldId, "");
|
|
14084
|
+
}
|
|
14085
|
+
} catch {
|
|
14086
|
+
setStatus("failed");
|
|
14087
|
+
store.setExternalError(fieldId, "Network error. Please try again.");
|
|
14088
|
+
setOtp("");
|
|
14089
|
+
store.setValue(fieldId, "");
|
|
14090
|
+
} finally {
|
|
14091
|
+
isVerifyingRef.current = false;
|
|
14092
|
+
}
|
|
14093
|
+
};
|
|
14094
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
14095
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
|
|
14096
|
+
fieldDef.label,
|
|
14097
|
+
" ",
|
|
14098
|
+
fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
14099
|
+
] }),
|
|
14100
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
14101
|
+
/* @__PURE__ */ jsx(
|
|
14102
|
+
Input,
|
|
14103
|
+
{
|
|
14104
|
+
id: fieldId,
|
|
14105
|
+
type: "tel",
|
|
14106
|
+
inputMode: "numeric",
|
|
14107
|
+
value: otp,
|
|
14108
|
+
onChange: handleChange,
|
|
14109
|
+
onBlur: () => store.setTouched(fieldId),
|
|
14110
|
+
disabled: disabled || status === "verifying" || status === "verified",
|
|
14111
|
+
placeholder,
|
|
14112
|
+
maxLength: 4,
|
|
14113
|
+
className: cn(
|
|
14114
|
+
"tracking-widest text-center text-lg",
|
|
14115
|
+
showError && "border-red-500",
|
|
14116
|
+
status === "verified" && "border-green-500 pr-9",
|
|
14117
|
+
status === "verifying" && "pr-9"
|
|
14118
|
+
)
|
|
14119
|
+
}
|
|
14120
|
+
),
|
|
14121
|
+
status === "verifying" && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxs(
|
|
14122
|
+
"svg",
|
|
14123
|
+
{
|
|
14124
|
+
className: "animate-spin h-4 w-4 text-muted-foreground",
|
|
14125
|
+
viewBox: "0 0 24 24",
|
|
14126
|
+
fill: "none",
|
|
14127
|
+
children: [
|
|
14128
|
+
/* @__PURE__ */ jsx(
|
|
14129
|
+
"circle",
|
|
14130
|
+
{
|
|
14131
|
+
className: "opacity-25",
|
|
14132
|
+
cx: "12",
|
|
14133
|
+
cy: "12",
|
|
14134
|
+
r: "10",
|
|
14135
|
+
stroke: "currentColor",
|
|
14136
|
+
strokeWidth: "4"
|
|
14137
|
+
}
|
|
14138
|
+
),
|
|
14139
|
+
/* @__PURE__ */ jsx(
|
|
14140
|
+
"path",
|
|
14141
|
+
{
|
|
14142
|
+
className: "opacity-75",
|
|
14143
|
+
fill: "currentColor",
|
|
14144
|
+
d: "M4 12a8 8 0 018-8v8H4z"
|
|
14145
|
+
}
|
|
14146
|
+
)
|
|
14147
|
+
]
|
|
14148
|
+
}
|
|
14149
|
+
) }),
|
|
14150
|
+
status === "verified" && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsx(
|
|
14151
|
+
"svg",
|
|
14152
|
+
{
|
|
14153
|
+
className: "h-4 w-4 text-green-500",
|
|
14154
|
+
viewBox: "0 0 20 20",
|
|
14155
|
+
fill: "currentColor",
|
|
14156
|
+
children: /* @__PURE__ */ jsx(
|
|
14157
|
+
"path",
|
|
14158
|
+
{
|
|
14159
|
+
fillRule: "evenodd",
|
|
14160
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
14161
|
+
clipRule: "evenodd"
|
|
14162
|
+
}
|
|
14163
|
+
)
|
|
14164
|
+
}
|
|
14165
|
+
) })
|
|
14166
|
+
] }),
|
|
14167
|
+
status === "verified" && /* @__PURE__ */ jsx("p", { className: "text-xs text-green-600", children: "Mobile number verified successfully" }),
|
|
14168
|
+
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
14169
|
+
] });
|
|
14170
|
+
};
|
|
13765
14171
|
var FieldRenderer = ({ fieldId }) => {
|
|
13766
14172
|
const { fieldDef, visible } = useField(fieldId);
|
|
13767
14173
|
if (!visible || !fieldDef) {
|
|
@@ -13853,6 +14259,10 @@ function renderWidget(fieldId, fieldDef) {
|
|
|
13853
14259
|
return /* @__PURE__ */ jsx(OBGExaminationWidget, { fieldId });
|
|
13854
14260
|
case "obg_pathway":
|
|
13855
14261
|
return /* @__PURE__ */ jsx(OBGPathwayWidget, { fieldId });
|
|
14262
|
+
case "phone_input":
|
|
14263
|
+
return /* @__PURE__ */ jsx(PhoneInputWidget, { fieldId });
|
|
14264
|
+
case "otp_input":
|
|
14265
|
+
return /* @__PURE__ */ jsx(OtpInputWidget, { fieldId });
|
|
13856
14266
|
case "toggle": {
|
|
13857
14267
|
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
13858
14268
|
const store = useFormStore();
|
|
@@ -13973,16 +14383,6 @@ var DynamicForm = () => {
|
|
|
13973
14383
|
})
|
|
13974
14384
|
] });
|
|
13975
14385
|
};
|
|
13976
|
-
function PlainSection({
|
|
13977
|
-
title,
|
|
13978
|
-
showHeading,
|
|
13979
|
-
children
|
|
13980
|
-
}) {
|
|
13981
|
-
return /* @__PURE__ */ jsxs("div", { className: "mb-6 space-y-4", children: [
|
|
13982
|
-
showHeading ? /* @__PURE__ */ jsx("h2", { className: "text-base font-medium text-foreground", children: title }) : null,
|
|
13983
|
-
children
|
|
13984
|
-
] });
|
|
13985
|
-
}
|
|
13986
14386
|
function renderSectionChildren(children) {
|
|
13987
14387
|
return children.map((child, index) => {
|
|
13988
14388
|
if (typeof child === "string") {
|
|
@@ -14002,6 +14402,16 @@ function renderSectionChildren(children) {
|
|
|
14002
14402
|
return /* @__PURE__ */ jsx(React15__default.Fragment, {}, index);
|
|
14003
14403
|
});
|
|
14004
14404
|
}
|
|
14405
|
+
function PlainSection({
|
|
14406
|
+
title,
|
|
14407
|
+
showHeading,
|
|
14408
|
+
children
|
|
14409
|
+
}) {
|
|
14410
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-6 space-y-4", children: [
|
|
14411
|
+
showHeading ? /* @__PURE__ */ jsx("h2", { className: "text-base font-medium text-foreground", children: title }) : null,
|
|
14412
|
+
children
|
|
14413
|
+
] });
|
|
14414
|
+
}
|
|
14005
14415
|
var DynamicFormV2 = ({
|
|
14006
14416
|
showTitle = true,
|
|
14007
14417
|
sectionMode = "plain",
|
|
@@ -14042,6 +14452,247 @@ var DynamicFormV2 = ({
|
|
|
14042
14452
|
})
|
|
14043
14453
|
] });
|
|
14044
14454
|
};
|
|
14455
|
+
function flattenStepFieldIds(step) {
|
|
14456
|
+
const ids = [];
|
|
14457
|
+
for (const child of step.children) {
|
|
14458
|
+
if (typeof child === "string") {
|
|
14459
|
+
ids.push(child);
|
|
14460
|
+
} else if (child.type === "column_layout") {
|
|
14461
|
+
ids.push(...child.children);
|
|
14462
|
+
}
|
|
14463
|
+
}
|
|
14464
|
+
return ids;
|
|
14465
|
+
}
|
|
14466
|
+
function isFieldComplete(id, state, fieldMap) {
|
|
14467
|
+
if (state.visibility[id] === false) return true;
|
|
14468
|
+
if (state.errors[id]) return false;
|
|
14469
|
+
const def = fieldMap[id];
|
|
14470
|
+
if (def?.required) {
|
|
14471
|
+
const v = state.values[id];
|
|
14472
|
+
if (v === null || v === void 0 || v === "") return false;
|
|
14473
|
+
if (Array.isArray(v) && v.length === 0) return false;
|
|
14474
|
+
}
|
|
14475
|
+
return true;
|
|
14476
|
+
}
|
|
14477
|
+
function isStepComplete(step, state, fieldMap) {
|
|
14478
|
+
return flattenStepFieldIds(step).every(
|
|
14479
|
+
(id) => isFieldComplete(id, state, fieldMap)
|
|
14480
|
+
);
|
|
14481
|
+
}
|
|
14482
|
+
var Stepper2 = ({ steps, statuses, variant }) => {
|
|
14483
|
+
if (variant === "dots") {
|
|
14484
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 mb-6", children: steps.map((step, i) => {
|
|
14485
|
+
const status = statuses[i];
|
|
14486
|
+
return /* @__PURE__ */ jsxs(React15__default.Fragment, { children: [
|
|
14487
|
+
/* @__PURE__ */ jsx(
|
|
14488
|
+
"div",
|
|
14489
|
+
{
|
|
14490
|
+
className: cn(
|
|
14491
|
+
"h-2.5 w-2.5 rounded-full transition-colors",
|
|
14492
|
+
status === "complete" && "bg-primary",
|
|
14493
|
+
status === "active" && "bg-primary ring-2 ring-primary/30",
|
|
14494
|
+
status === "locked" && "bg-muted"
|
|
14495
|
+
),
|
|
14496
|
+
title: step.title
|
|
14497
|
+
}
|
|
14498
|
+
),
|
|
14499
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx(
|
|
14500
|
+
"div",
|
|
14501
|
+
{
|
|
14502
|
+
className: cn(
|
|
14503
|
+
"flex-1 h-px transition-colors",
|
|
14504
|
+
status === "complete" ? "bg-primary" : "bg-border"
|
|
14505
|
+
)
|
|
14506
|
+
}
|
|
14507
|
+
)
|
|
14508
|
+
] }, step.id);
|
|
14509
|
+
}) });
|
|
14510
|
+
}
|
|
14511
|
+
if (variant === "labels") {
|
|
14512
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0 mb-6", children: steps.map((step, i) => {
|
|
14513
|
+
const status = statuses[i];
|
|
14514
|
+
return /* @__PURE__ */ jsxs(React15__default.Fragment, { children: [
|
|
14515
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1", children: [
|
|
14516
|
+
/* @__PURE__ */ jsx(
|
|
14517
|
+
"div",
|
|
14518
|
+
{
|
|
14519
|
+
className: cn(
|
|
14520
|
+
"h-2 w-2 rounded-full",
|
|
14521
|
+
status === "complete" && "bg-primary",
|
|
14522
|
+
status === "active" && "bg-primary",
|
|
14523
|
+
status === "locked" && "bg-muted"
|
|
14524
|
+
)
|
|
14525
|
+
}
|
|
14526
|
+
),
|
|
14527
|
+
/* @__PURE__ */ jsx(
|
|
14528
|
+
"span",
|
|
14529
|
+
{
|
|
14530
|
+
className: cn(
|
|
14531
|
+
"text-xs whitespace-nowrap",
|
|
14532
|
+
status === "locked" ? "text-muted-foreground" : "text-foreground"
|
|
14533
|
+
),
|
|
14534
|
+
children: step.title
|
|
14535
|
+
}
|
|
14536
|
+
)
|
|
14537
|
+
] }),
|
|
14538
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx(
|
|
14539
|
+
"div",
|
|
14540
|
+
{
|
|
14541
|
+
className: cn(
|
|
14542
|
+
"flex-1 h-px mb-4 transition-colors",
|
|
14543
|
+
status === "complete" ? "bg-primary" : "bg-border"
|
|
14544
|
+
)
|
|
14545
|
+
}
|
|
14546
|
+
)
|
|
14547
|
+
] }, step.id);
|
|
14548
|
+
}) });
|
|
14549
|
+
}
|
|
14550
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0 mb-6", children: steps.map((step, i) => {
|
|
14551
|
+
const status = statuses[i];
|
|
14552
|
+
return /* @__PURE__ */ jsxs(React15__default.Fragment, { children: [
|
|
14553
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
14554
|
+
/* @__PURE__ */ jsx(
|
|
14555
|
+
"div",
|
|
14556
|
+
{
|
|
14557
|
+
className: cn(
|
|
14558
|
+
"flex h-7 w-7 items-center justify-center rounded-full text-xs font-semibold border-2 transition-colors",
|
|
14559
|
+
status === "complete" && "border-primary bg-primary text-primary-foreground",
|
|
14560
|
+
status === "active" && "border-primary bg-background text-primary",
|
|
14561
|
+
status === "locked" && "border-border bg-background text-muted-foreground"
|
|
14562
|
+
),
|
|
14563
|
+
children: status === "complete" ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : i + 1
|
|
14564
|
+
}
|
|
14565
|
+
),
|
|
14566
|
+
/* @__PURE__ */ jsx(
|
|
14567
|
+
"span",
|
|
14568
|
+
{
|
|
14569
|
+
className: cn(
|
|
14570
|
+
"text-sm font-medium hidden sm:block",
|
|
14571
|
+
status === "locked" ? "text-muted-foreground" : "text-foreground"
|
|
14572
|
+
),
|
|
14573
|
+
children: step.title
|
|
14574
|
+
}
|
|
14575
|
+
)
|
|
14576
|
+
] }),
|
|
14577
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx(
|
|
14578
|
+
"div",
|
|
14579
|
+
{
|
|
14580
|
+
className: cn(
|
|
14581
|
+
"flex-1 h-px mx-3 transition-colors",
|
|
14582
|
+
status === "complete" ? "bg-primary" : "bg-border"
|
|
14583
|
+
)
|
|
14584
|
+
}
|
|
14585
|
+
)
|
|
14586
|
+
] }, step.id);
|
|
14587
|
+
}) });
|
|
14588
|
+
};
|
|
14589
|
+
var ActiveStep = ({
|
|
14590
|
+
title,
|
|
14591
|
+
children
|
|
14592
|
+
}) => /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-4", children: [
|
|
14593
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-medium text-foreground", children: title }),
|
|
14594
|
+
children
|
|
14595
|
+
] });
|
|
14596
|
+
var Wizard = ({ node }) => {
|
|
14597
|
+
const store = useFormStore();
|
|
14598
|
+
const [formState, setFormState] = useState(() => ({
|
|
14599
|
+
...store.getState()
|
|
14600
|
+
}));
|
|
14601
|
+
useEffect(() => {
|
|
14602
|
+
return store.subscribe((state) => {
|
|
14603
|
+
console.log("[MultiStepForm] store update \u2192", {
|
|
14604
|
+
values: state.values,
|
|
14605
|
+
errors: state.errors,
|
|
14606
|
+
visibility: state.visibility
|
|
14607
|
+
});
|
|
14608
|
+
setFormState({ ...state });
|
|
14609
|
+
});
|
|
14610
|
+
}, [store]);
|
|
14611
|
+
const schema = store.getSchema();
|
|
14612
|
+
const fieldMap = {};
|
|
14613
|
+
schema.fields.forEach((f) => {
|
|
14614
|
+
fieldMap[f.id] = f;
|
|
14615
|
+
});
|
|
14616
|
+
const { steps, meta } = node;
|
|
14617
|
+
const showStepper = meta?.showStepper !== false;
|
|
14618
|
+
const variant = meta?.stepperVariant ?? "numbered";
|
|
14619
|
+
const collapseCompleted = meta?.collapseCompleted !== false;
|
|
14620
|
+
const stepComplete = steps.map((s) => {
|
|
14621
|
+
const fieldIds = flattenStepFieldIds(s);
|
|
14622
|
+
const complete = isStepComplete(s, formState, fieldMap);
|
|
14623
|
+
console.log(`[MultiStepForm] step "${s.id}" fieldIds=${JSON.stringify(fieldIds)} complete=${complete}`, {
|
|
14624
|
+
errors: fieldIds.map((id) => ({ id, error: formState.errors[id] })),
|
|
14625
|
+
values: fieldIds.map((id) => ({ id, value: formState.values[id] }))
|
|
14626
|
+
});
|
|
14627
|
+
return complete;
|
|
14628
|
+
});
|
|
14629
|
+
const activeIndex = stepComplete.findIndex((c) => !c) === -1 ? steps.length : stepComplete.findIndex((c) => !c);
|
|
14630
|
+
console.log(`[MultiStepForm] activeIndex=${activeIndex} stepComplete=${JSON.stringify(stepComplete)}`);
|
|
14631
|
+
const statuses = steps.map((_, i) => {
|
|
14632
|
+
if (i < activeIndex) return "complete";
|
|
14633
|
+
if (i === activeIndex) return "active";
|
|
14634
|
+
return "locked";
|
|
14635
|
+
});
|
|
14636
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
14637
|
+
node.title && /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold mb-4", children: node.title }),
|
|
14638
|
+
showStepper && /* @__PURE__ */ jsx(Stepper2, { steps, statuses, variant }),
|
|
14639
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: steps.map((step, i) => {
|
|
14640
|
+
const status = statuses[i];
|
|
14641
|
+
if (status === "locked") return null;
|
|
14642
|
+
const children = renderSectionChildren(step.children);
|
|
14643
|
+
if (status === "complete") {
|
|
14644
|
+
if (collapseCompleted) {
|
|
14645
|
+
return /* @__PURE__ */ jsx(Section, { title: step.title, children }, step.id);
|
|
14646
|
+
}
|
|
14647
|
+
return /* @__PURE__ */ jsxs(
|
|
14648
|
+
"div",
|
|
14649
|
+
{
|
|
14650
|
+
className: "mb-4 opacity-60 pointer-events-none select-none space-y-4",
|
|
14651
|
+
children: [
|
|
14652
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-medium text-foreground", children: step.title }),
|
|
14653
|
+
children
|
|
14654
|
+
]
|
|
14655
|
+
},
|
|
14656
|
+
step.id
|
|
14657
|
+
);
|
|
14658
|
+
}
|
|
14659
|
+
return /* @__PURE__ */ jsx(ActiveStep, { title: step.title, children }, step.id);
|
|
14660
|
+
}) })
|
|
14661
|
+
] });
|
|
14662
|
+
};
|
|
14663
|
+
var MultiStepForm = ({
|
|
14664
|
+
showTitle = true,
|
|
14665
|
+
className
|
|
14666
|
+
}) => {
|
|
14667
|
+
const store = useFormStore();
|
|
14668
|
+
const schema = store.getSchema();
|
|
14669
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", className), children: [
|
|
14670
|
+
showTitle && /* @__PURE__ */ jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold", children: schema.title }) }),
|
|
14671
|
+
schema.layout.map((node) => {
|
|
14672
|
+
if (node.type === "multi_step") {
|
|
14673
|
+
return /* @__PURE__ */ jsx(Wizard, { node }, node.id);
|
|
14674
|
+
}
|
|
14675
|
+
if (node.type === "section") {
|
|
14676
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-6 space-y-4", children: [
|
|
14677
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-medium text-foreground", children: node.title }),
|
|
14678
|
+
renderSectionChildren(node.children)
|
|
14679
|
+
] }, node.id);
|
|
14680
|
+
}
|
|
14681
|
+
if (node.type === "column_layout") {
|
|
14682
|
+
return /* @__PURE__ */ jsx(
|
|
14683
|
+
ColumnLayout,
|
|
14684
|
+
{
|
|
14685
|
+
columns: node.columns,
|
|
14686
|
+
label: node.label,
|
|
14687
|
+
children: node.children.map((fieldId) => /* @__PURE__ */ jsx(FieldRenderer, { fieldId }, fieldId))
|
|
14688
|
+
},
|
|
14689
|
+
node.id
|
|
14690
|
+
);
|
|
14691
|
+
}
|
|
14692
|
+
return null;
|
|
14693
|
+
})
|
|
14694
|
+
] });
|
|
14695
|
+
};
|
|
14045
14696
|
var SUGGESTION_KEYS = /* @__PURE__ */ new Set(["medications", "investigations", "procedures"]);
|
|
14046
14697
|
function shallowEqualKeys(a, b) {
|
|
14047
14698
|
const keysA = Object.keys(a);
|
|
@@ -15004,7 +15655,8 @@ var FormControls = ({
|
|
|
15004
15655
|
actionsFullWidth = false,
|
|
15005
15656
|
buttonClassName,
|
|
15006
15657
|
onSaveDraft,
|
|
15007
|
-
onSubmit
|
|
15658
|
+
onSubmit,
|
|
15659
|
+
submitLabel
|
|
15008
15660
|
}) => {
|
|
15009
15661
|
const {
|
|
15010
15662
|
state,
|
|
@@ -15093,7 +15745,7 @@ var FormControls = ({
|
|
|
15093
15745
|
disabled: !state.isValid || hasUploadsInFlight,
|
|
15094
15746
|
size: "sm",
|
|
15095
15747
|
className: buttonCn,
|
|
15096
|
-
children: hasUploadsInFlight ? "Upload in progress\u2026" : availableTransitions.length > 1 ? `Submit to ${t.to}` : "Submit"
|
|
15748
|
+
children: hasUploadsInFlight ? "Upload in progress\u2026" : availableTransitions.length > 1 ? `Submit to ${t.to}` : submitLabel ?? "Submit"
|
|
15097
15749
|
},
|
|
15098
15750
|
t.to
|
|
15099
15751
|
)) : onSubmit ? /* @__PURE__ */ jsx(
|
|
@@ -15106,7 +15758,7 @@ var FormControls = ({
|
|
|
15106
15758
|
disabled: !state.isValid || hasUploadsInFlight,
|
|
15107
15759
|
size: "sm",
|
|
15108
15760
|
className: buttonCn,
|
|
15109
|
-
children: hasUploadsInFlight ? "Upload in progress\u2026" : "Submit"
|
|
15761
|
+
children: hasUploadsInFlight ? "Upload in progress\u2026" : submitLabel ?? "Submit"
|
|
15110
15762
|
}
|
|
15111
15763
|
) : null })
|
|
15112
15764
|
]
|
|
@@ -15147,6 +15799,6 @@ function createUploadHandler(options) {
|
|
|
15147
15799
|
};
|
|
15148
15800
|
}
|
|
15149
15801
|
|
|
15150
|
-
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, DynamicFormV2, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MAR_MEDICATION_ORDERS_META_KEY, MediaUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, fieldMetaRequestsMarMedicationOrdersButton, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, usePackages, useSmartKeywords, validateField, validateForm };
|
|
15802
|
+
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, DynamicFormV2, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MAR_MEDICATION_ORDERS_META_KEY, MediaUploadWidget, MultiStepForm, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, fieldMetaRequestsMarMedicationOrdersButton, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, usePackages, useSmartKeywords, validateField, validateForm };
|
|
15151
15803
|
//# sourceMappingURL=index.mjs.map
|
|
15152
15804
|
//# sourceMappingURL=index.mjs.map
|