@nextlyhq/plugin-form-builder 0.0.2-alpha.58 → 0.0.2-alpha.60
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/admin/index.js +708 -713
- package/dist/admin/index.js.map +1 -1
- package/package.json +11 -11
package/dist/admin/index.js
CHANGED
|
@@ -872,6 +872,9 @@ function SubmissionsView({ collectionSlug }) {
|
|
|
872
872
|
// src/admin/FormBuilderView.tsx
|
|
873
873
|
import {
|
|
874
874
|
Button as Button8,
|
|
875
|
+
FieldShell as FieldShell2,
|
|
876
|
+
FormActions,
|
|
877
|
+
FormLayout,
|
|
875
878
|
Input as Input6,
|
|
876
879
|
toast,
|
|
877
880
|
Tabs as Tabs4,
|
|
@@ -1339,6 +1342,7 @@ function AddFieldDialog({
|
|
|
1339
1342
|
// src/admin/components/builder/FieldEditor.tsx
|
|
1340
1343
|
import {
|
|
1341
1344
|
FieldOptionsEditor,
|
|
1345
|
+
ValidationNumberField,
|
|
1342
1346
|
withOptionIds
|
|
1343
1347
|
} from "@nextlyhq/plugin-sdk/admin";
|
|
1344
1348
|
import {
|
|
@@ -2010,102 +2014,46 @@ function ValidationTab({
|
|
|
2010
2014
|
)
|
|
2011
2015
|
] }),
|
|
2012
2016
|
(field.type === "text" || field.type === "textarea") && /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
2013
|
-
/* @__PURE__ */
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
className: "bg-transparent"
|
|
2034
|
-
}
|
|
2035
|
-
)
|
|
2036
|
-
] }),
|
|
2037
|
-
/* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
2038
|
-
/* @__PURE__ */ jsx6(
|
|
2039
|
-
FormLabelWithTooltip2,
|
|
2040
|
-
{
|
|
2041
|
-
label: "Max Length",
|
|
2042
|
-
htmlFor: "max-len",
|
|
2043
|
-
description: "Maximum characters allowed."
|
|
2044
|
-
}
|
|
2045
|
-
),
|
|
2046
|
-
/* @__PURE__ */ jsx6(
|
|
2047
|
-
Input2,
|
|
2048
|
-
{
|
|
2049
|
-
id: "max-len",
|
|
2050
|
-
type: "number",
|
|
2051
|
-
min: 0,
|
|
2052
|
-
value: field.validation?.maxLength ?? "",
|
|
2053
|
-
onChange: (e) => updateValidation(
|
|
2054
|
-
"maxLength",
|
|
2055
|
-
e.target.value ? parseInt(e.target.value) : void 0
|
|
2056
|
-
),
|
|
2057
|
-
className: "bg-transparent"
|
|
2058
|
-
}
|
|
2059
|
-
)
|
|
2060
|
-
] })
|
|
2017
|
+
/* @__PURE__ */ jsx6(
|
|
2018
|
+
ValidationNumberField,
|
|
2019
|
+
{
|
|
2020
|
+
label: "Min Length",
|
|
2021
|
+
description: "Minimum characters required.",
|
|
2022
|
+
counts: true,
|
|
2023
|
+
value: field.validation?.minLength,
|
|
2024
|
+
onChange: (n) => updateValidation("minLength", n)
|
|
2025
|
+
}
|
|
2026
|
+
),
|
|
2027
|
+
/* @__PURE__ */ jsx6(
|
|
2028
|
+
ValidationNumberField,
|
|
2029
|
+
{
|
|
2030
|
+
label: "Max Length",
|
|
2031
|
+
description: "Maximum characters allowed.",
|
|
2032
|
+
counts: true,
|
|
2033
|
+
value: field.validation?.maxLength,
|
|
2034
|
+
onChange: (n) => updateValidation("maxLength", n)
|
|
2035
|
+
}
|
|
2036
|
+
)
|
|
2061
2037
|
] }),
|
|
2062
2038
|
field.type === "number" && /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
),
|
|
2082
|
-
className: "bg-transparent"
|
|
2083
|
-
}
|
|
2084
|
-
)
|
|
2085
|
-
] }),
|
|
2086
|
-
/* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
2087
|
-
/* @__PURE__ */ jsx6(
|
|
2088
|
-
FormLabelWithTooltip2,
|
|
2089
|
-
{
|
|
2090
|
-
label: "Max Value",
|
|
2091
|
-
htmlFor: "max-val",
|
|
2092
|
-
description: "Maximum numerical value."
|
|
2093
|
-
}
|
|
2094
|
-
),
|
|
2095
|
-
/* @__PURE__ */ jsx6(
|
|
2096
|
-
Input2,
|
|
2097
|
-
{
|
|
2098
|
-
id: "max-val",
|
|
2099
|
-
type: "number",
|
|
2100
|
-
value: field.validation?.max ?? "",
|
|
2101
|
-
onChange: (e) => updateValidation(
|
|
2102
|
-
"max",
|
|
2103
|
-
e.target.value ? parseFloat(e.target.value) : void 0
|
|
2104
|
-
),
|
|
2105
|
-
className: "bg-transparent"
|
|
2106
|
-
}
|
|
2107
|
-
)
|
|
2108
|
-
] })
|
|
2039
|
+
/* @__PURE__ */ jsx6(
|
|
2040
|
+
ValidationNumberField,
|
|
2041
|
+
{
|
|
2042
|
+
label: "Min Value",
|
|
2043
|
+
description: "Minimum numerical value.",
|
|
2044
|
+
value: field.validation?.min,
|
|
2045
|
+
onChange: (n) => updateValidation("min", n)
|
|
2046
|
+
}
|
|
2047
|
+
),
|
|
2048
|
+
/* @__PURE__ */ jsx6(
|
|
2049
|
+
ValidationNumberField,
|
|
2050
|
+
{
|
|
2051
|
+
label: "Max Value",
|
|
2052
|
+
description: "Maximum numerical value.",
|
|
2053
|
+
value: field.validation?.max,
|
|
2054
|
+
onChange: (n) => updateValidation("max", n)
|
|
2055
|
+
}
|
|
2056
|
+
)
|
|
2109
2057
|
] }),
|
|
2110
2058
|
(field.type === "text" || field.type === "email" || field.type === "phone" || field.type === "url") && /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
2111
2059
|
/* @__PURE__ */ jsx6(
|
|
@@ -2543,6 +2491,8 @@ import {
|
|
|
2543
2491
|
DropdownMenuItem as DropdownMenuItem3,
|
|
2544
2492
|
DropdownMenuSeparator as DropdownMenuSeparator2,
|
|
2545
2493
|
DropdownMenuTrigger as DropdownMenuTrigger3,
|
|
2494
|
+
FieldShell,
|
|
2495
|
+
Grid,
|
|
2546
2496
|
Input as Input3,
|
|
2547
2497
|
Label as Label2,
|
|
2548
2498
|
Select as Select5,
|
|
@@ -2938,235 +2888,269 @@ function NotificationSheet({
|
|
|
2938
2888
|
/* @__PURE__ */ jsx8(SheetDescription2, { children: "Sent when someone submits this form." })
|
|
2939
2889
|
] }),
|
|
2940
2890
|
/* @__PURE__ */ jsxs7("div", { className: "flex-1 overflow-y-auto p-4 space-y-6", children: [
|
|
2941
|
-
/* @__PURE__ */
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2891
|
+
/* @__PURE__ */ jsx8(FieldShell, { label: "Name", htmlFor: "notification-name", width: "half", children: /* @__PURE__ */ jsx8(
|
|
2892
|
+
Input3,
|
|
2893
|
+
{
|
|
2894
|
+
type: "text",
|
|
2895
|
+
value: form.name,
|
|
2896
|
+
onChange: (e) => update("name", e.target.value),
|
|
2897
|
+
placeholder: "e.g. Admin notification"
|
|
2898
|
+
}
|
|
2899
|
+
) }),
|
|
2900
|
+
/* @__PURE__ */ jsxs7(Grid, { cols: 2, responsive: true, children: [
|
|
2901
|
+
/* @__PURE__ */ jsx8(FieldShell, { label: "Email provider", htmlFor: "notification-provider", children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
2902
|
+
Select5,
|
|
2945
2903
|
{
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2904
|
+
value: form.providerId ?? "__default",
|
|
2905
|
+
onValueChange: (value) => update(
|
|
2906
|
+
"providerId",
|
|
2907
|
+
value === "__default" ? void 0 : value
|
|
2908
|
+
),
|
|
2909
|
+
children: [
|
|
2910
|
+
/* @__PURE__ */ jsx8(
|
|
2911
|
+
SelectTrigger5,
|
|
2912
|
+
{
|
|
2913
|
+
id,
|
|
2914
|
+
"aria-describedby": describedBy,
|
|
2915
|
+
"aria-invalid": invalid,
|
|
2916
|
+
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
2917
|
+
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
2918
|
+
}
|
|
2919
|
+
),
|
|
2920
|
+
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
2921
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "__default", children: defaultProviderLabel }),
|
|
2922
|
+
providers.map((p) => /* @__PURE__ */ jsxs7(SelectItem5, { value: p.id, children: [
|
|
2923
|
+
p.name,
|
|
2924
|
+
p.isDefault ? " (Default)" : ""
|
|
2925
|
+
] }, p.id))
|
|
2926
|
+
] })
|
|
2927
|
+
]
|
|
2951
2928
|
}
|
|
2952
|
-
)
|
|
2953
|
-
] }),
|
|
2954
|
-
/* @__PURE__ */ jsxs7("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
|
|
2929
|
+
) }),
|
|
2955
2930
|
/* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
2956
|
-
/* @__PURE__ */ jsx8(
|
|
2957
|
-
|
|
2931
|
+
/* @__PURE__ */ jsx8(
|
|
2932
|
+
FieldShell,
|
|
2933
|
+
{
|
|
2934
|
+
label: "Email template",
|
|
2935
|
+
htmlFor: "notification-template",
|
|
2936
|
+
children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
2937
|
+
Select5,
|
|
2938
|
+
{
|
|
2939
|
+
value: form.templateSlug ?? "__none",
|
|
2940
|
+
onValueChange: (value) => update(
|
|
2941
|
+
"templateSlug",
|
|
2942
|
+
value === "__none" ? void 0 : value
|
|
2943
|
+
),
|
|
2944
|
+
children: [
|
|
2945
|
+
/* @__PURE__ */ jsx8(
|
|
2946
|
+
SelectTrigger5,
|
|
2947
|
+
{
|
|
2948
|
+
id,
|
|
2949
|
+
"aria-describedby": describedBy,
|
|
2950
|
+
"aria-invalid": invalid,
|
|
2951
|
+
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
2952
|
+
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
2953
|
+
}
|
|
2954
|
+
),
|
|
2955
|
+
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
2956
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "__none", children: "Select a template" }),
|
|
2957
|
+
templates.filter((t) => t.isActive && t.kind !== "layout").map((t) => /* @__PURE__ */ jsx8(SelectItem5, { value: t.slug, children: t.name }, t.id))
|
|
2958
|
+
] })
|
|
2959
|
+
]
|
|
2960
|
+
}
|
|
2961
|
+
)
|
|
2962
|
+
}
|
|
2963
|
+
),
|
|
2964
|
+
!form.templateSlug && /* @__PURE__ */ jsxs7("p", { className: "flex items-center gap-1 text-xs text-destructive", children: [
|
|
2965
|
+
/* @__PURE__ */ jsx8(TriangleAlert2, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
2966
|
+
"Required \u2014 a notification without a template is never sent."
|
|
2967
|
+
] })
|
|
2968
|
+
] })
|
|
2969
|
+
] }),
|
|
2970
|
+
/* @__PURE__ */ jsx8(
|
|
2971
|
+
FieldShell,
|
|
2972
|
+
{
|
|
2973
|
+
label: "Sender email",
|
|
2974
|
+
htmlFor: "notification-sender",
|
|
2975
|
+
width: "half",
|
|
2976
|
+
description: addressErrors.senderEmail ? void 0 : senderHelp,
|
|
2977
|
+
error: addressErrors.senderEmail,
|
|
2978
|
+
children: /* @__PURE__ */ jsx8(
|
|
2979
|
+
Input3,
|
|
2980
|
+
{
|
|
2981
|
+
type: "email",
|
|
2982
|
+
value: form.senderEmail ?? "",
|
|
2983
|
+
onChange: (e) => update("senderEmail", e.target.value || void 0),
|
|
2984
|
+
placeholder: senderPlaceholder
|
|
2985
|
+
}
|
|
2986
|
+
)
|
|
2987
|
+
}
|
|
2988
|
+
),
|
|
2989
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-4 pt-4 border-t border-border", children: [
|
|
2990
|
+
/* @__PURE__ */ jsxs7(Grid, { cols: 2, responsive: true, children: [
|
|
2991
|
+
/* @__PURE__ */ jsx8(FieldShell, { label: "Send to", htmlFor: "notification-recipient-type", children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
2958
2992
|
Select5,
|
|
2959
2993
|
{
|
|
2960
|
-
value: form.
|
|
2961
|
-
onValueChange: (value) =>
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2994
|
+
value: form.recipientType,
|
|
2995
|
+
onValueChange: (value) => {
|
|
2996
|
+
setForm((prev) => ({
|
|
2997
|
+
...prev,
|
|
2998
|
+
recipientType: value,
|
|
2999
|
+
to: ""
|
|
3000
|
+
}));
|
|
3001
|
+
},
|
|
2965
3002
|
children: [
|
|
2966
3003
|
/* @__PURE__ */ jsx8(
|
|
2967
3004
|
SelectTrigger5,
|
|
2968
3005
|
{
|
|
2969
|
-
id
|
|
3006
|
+
id,
|
|
3007
|
+
"aria-describedby": describedBy,
|
|
3008
|
+
"aria-invalid": invalid,
|
|
2970
3009
|
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
2971
3010
|
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
2972
3011
|
}
|
|
2973
3012
|
),
|
|
2974
3013
|
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
2975
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "
|
|
2976
|
-
|
|
2977
|
-
p.name,
|
|
2978
|
-
p.isDefault ? " (Default)" : ""
|
|
2979
|
-
] }, p.id))
|
|
3014
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "static", children: "A specific address" }),
|
|
3015
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "field", children: "The visitor (email field)" })
|
|
2980
3016
|
] })
|
|
2981
3017
|
]
|
|
2982
3018
|
}
|
|
3019
|
+
) }),
|
|
3020
|
+
form.recipientType === "field" ? /* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
3021
|
+
/* @__PURE__ */ jsx8(
|
|
3022
|
+
FieldShell,
|
|
3023
|
+
{
|
|
3024
|
+
label: "Visitor email field",
|
|
3025
|
+
htmlFor: "notification-to",
|
|
3026
|
+
children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
3027
|
+
Select5,
|
|
3028
|
+
{
|
|
3029
|
+
value: toRef ?? "__none",
|
|
3030
|
+
onValueChange: (value) => update(
|
|
3031
|
+
"to",
|
|
3032
|
+
value === "__none" ? "" : toFieldRef(value)
|
|
3033
|
+
),
|
|
3034
|
+
children: [
|
|
3035
|
+
/* @__PURE__ */ jsx8(
|
|
3036
|
+
SelectTrigger5,
|
|
3037
|
+
{
|
|
3038
|
+
id,
|
|
3039
|
+
"aria-describedby": describedBy,
|
|
3040
|
+
"aria-invalid": invalid,
|
|
3041
|
+
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3042
|
+
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3043
|
+
}
|
|
3044
|
+
),
|
|
3045
|
+
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3046
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "__none", children: "Select a field" }),
|
|
3047
|
+
toFieldOptions.map((f) => /* @__PURE__ */ jsx8(SelectItem5, { value: f.name, children: f.label }, f.name))
|
|
3048
|
+
] })
|
|
3049
|
+
]
|
|
3050
|
+
}
|
|
3051
|
+
)
|
|
3052
|
+
}
|
|
3053
|
+
),
|
|
3054
|
+
toFieldOptions.length === 0 && /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: "Add an email field to the form first." })
|
|
3055
|
+
] }) : /* @__PURE__ */ jsx8(
|
|
3056
|
+
FieldShell,
|
|
3057
|
+
{
|
|
3058
|
+
label: "Recipient address",
|
|
3059
|
+
htmlFor: "notification-to",
|
|
3060
|
+
width: "half",
|
|
3061
|
+
error: addressErrors.to,
|
|
3062
|
+
children: /* @__PURE__ */ jsx8(
|
|
3063
|
+
Input3,
|
|
3064
|
+
{
|
|
3065
|
+
type: "email",
|
|
3066
|
+
value: form.to,
|
|
3067
|
+
onChange: (e) => update("to", e.target.value),
|
|
3068
|
+
placeholder: defaults?.defaultToEmail || "admin@example.com"
|
|
3069
|
+
}
|
|
3070
|
+
)
|
|
3071
|
+
}
|
|
2983
3072
|
)
|
|
2984
3073
|
] }),
|
|
2985
|
-
/* @__PURE__ */ jsxs7(
|
|
2986
|
-
/* @__PURE__ */ jsx8(
|
|
2987
|
-
/* @__PURE__ */ jsxs7(
|
|
3074
|
+
/* @__PURE__ */ jsxs7(Grid, { cols: 2, responsive: true, children: [
|
|
3075
|
+
/* @__PURE__ */ jsx8(FieldShell, { label: "Reply-To", htmlFor: "notification-replyto-mode", children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
2988
3076
|
Select5,
|
|
2989
3077
|
{
|
|
2990
|
-
value:
|
|
2991
|
-
onValueChange: (value) =>
|
|
3078
|
+
value: replyToMode,
|
|
3079
|
+
onValueChange: (value) => {
|
|
3080
|
+
const mode = value;
|
|
3081
|
+
setReplyToMode(mode);
|
|
3082
|
+
update("replyTo", void 0);
|
|
3083
|
+
},
|
|
2992
3084
|
children: [
|
|
2993
3085
|
/* @__PURE__ */ jsx8(
|
|
2994
3086
|
SelectTrigger5,
|
|
2995
3087
|
{
|
|
2996
|
-
id
|
|
3088
|
+
id,
|
|
3089
|
+
"aria-describedby": describedBy,
|
|
3090
|
+
"aria-invalid": invalid,
|
|
2997
3091
|
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
2998
3092
|
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
2999
3093
|
}
|
|
3000
3094
|
),
|
|
3001
3095
|
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3002
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "
|
|
3003
|
-
|
|
3096
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "none", children: "None" }),
|
|
3097
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "field", children: "The visitor (email field)" }),
|
|
3098
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "custom", children: "A custom address" })
|
|
3004
3099
|
] })
|
|
3005
3100
|
]
|
|
3006
3101
|
}
|
|
3007
|
-
),
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
type: "email",
|
|
3021
|
-
value: form.senderEmail ?? "",
|
|
3022
|
-
onChange: (e) => update("senderEmail", e.target.value || void 0),
|
|
3023
|
-
placeholder: senderPlaceholder,
|
|
3024
|
-
"aria-invalid": addressErrors.senderEmail ? true : void 0
|
|
3025
|
-
}
|
|
3026
|
-
),
|
|
3027
|
-
addressErrors.senderEmail ? /* @__PURE__ */ jsx8("p", { className: "text-xs text-destructive", children: addressErrors.senderEmail }) : /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: senderHelp })
|
|
3028
|
-
] }),
|
|
3029
|
-
/* @__PURE__ */ jsxs7("div", { className: "space-y-4 pt-4 border-t border-border", children: [
|
|
3030
|
-
/* @__PURE__ */ jsxs7("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
|
|
3031
|
-
/* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
3032
|
-
/* @__PURE__ */ jsx8(Label2, { htmlFor: "notification-recipient-type", children: "Send to" }),
|
|
3033
|
-
/* @__PURE__ */ jsxs7(
|
|
3034
|
-
Select5,
|
|
3035
|
-
{
|
|
3036
|
-
value: form.recipientType,
|
|
3037
|
-
onValueChange: (value) => {
|
|
3038
|
-
setForm((prev) => ({
|
|
3039
|
-
...prev,
|
|
3040
|
-
recipientType: value,
|
|
3041
|
-
to: ""
|
|
3042
|
-
}));
|
|
3043
|
-
},
|
|
3044
|
-
children: [
|
|
3045
|
-
/* @__PURE__ */ jsx8(
|
|
3046
|
-
SelectTrigger5,
|
|
3047
|
-
{
|
|
3048
|
-
id: "notification-recipient-type",
|
|
3049
|
-
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3050
|
-
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3051
|
-
}
|
|
3052
|
-
),
|
|
3053
|
-
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3054
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "static", children: "A specific address" }),
|
|
3055
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "field", children: "The visitor (email field)" })
|
|
3056
|
-
] })
|
|
3057
|
-
]
|
|
3058
|
-
}
|
|
3059
|
-
)
|
|
3060
|
-
] }),
|
|
3061
|
-
/* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
3062
|
-
/* @__PURE__ */ jsx8(Label2, { htmlFor: "notification-to", children: form.recipientType === "field" ? "Visitor email field" : "Recipient address" }),
|
|
3063
|
-
form.recipientType === "field" ? /* @__PURE__ */ jsxs7(
|
|
3064
|
-
Select5,
|
|
3065
|
-
{
|
|
3066
|
-
value: toRef ?? "__none",
|
|
3067
|
-
onValueChange: (value) => update("to", value === "__none" ? "" : toFieldRef(value)),
|
|
3068
|
-
children: [
|
|
3069
|
-
/* @__PURE__ */ jsx8(
|
|
3070
|
-
SelectTrigger5,
|
|
3071
|
-
{
|
|
3072
|
-
id: "notification-to",
|
|
3073
|
-
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3074
|
-
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3075
|
-
}
|
|
3076
|
-
),
|
|
3077
|
-
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3078
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "__none", children: "Select a field" }),
|
|
3079
|
-
toFieldOptions.map((f) => /* @__PURE__ */ jsx8(SelectItem5, { value: f.name, children: f.label }, f.name))
|
|
3080
|
-
] })
|
|
3081
|
-
]
|
|
3082
|
-
}
|
|
3083
|
-
) : /* @__PURE__ */ jsx8(
|
|
3084
|
-
Input3,
|
|
3085
|
-
{
|
|
3086
|
-
id: "notification-to",
|
|
3087
|
-
type: "email",
|
|
3088
|
-
value: form.to,
|
|
3089
|
-
onChange: (e) => update("to", e.target.value),
|
|
3090
|
-
placeholder: defaults?.defaultToEmail || "admin@example.com",
|
|
3091
|
-
"aria-invalid": addressErrors.to ? true : void 0
|
|
3092
|
-
}
|
|
3093
|
-
),
|
|
3094
|
-
addressErrors.to && /* @__PURE__ */ jsx8("p", { className: "text-xs text-destructive", children: addressErrors.to }),
|
|
3095
|
-
form.recipientType === "field" && toFieldOptions.length === 0 && /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: "Add an email field to the form first." })
|
|
3096
|
-
] })
|
|
3097
|
-
] }),
|
|
3098
|
-
/* @__PURE__ */ jsxs7("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
|
|
3099
|
-
/* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
3100
|
-
/* @__PURE__ */ jsx8(Label2, { htmlFor: "notification-replyto-mode", children: "Reply-To" }),
|
|
3101
|
-
/* @__PURE__ */ jsxs7(
|
|
3102
|
-
Select5,
|
|
3103
|
-
{
|
|
3104
|
-
value: replyToMode,
|
|
3105
|
-
onValueChange: (value) => {
|
|
3106
|
-
const mode = value;
|
|
3107
|
-
setReplyToMode(mode);
|
|
3108
|
-
update("replyTo", void 0);
|
|
3109
|
-
},
|
|
3110
|
-
children: [
|
|
3111
|
-
/* @__PURE__ */ jsx8(
|
|
3112
|
-
SelectTrigger5,
|
|
3113
|
-
{
|
|
3114
|
-
id: "notification-replyto-mode",
|
|
3115
|
-
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3116
|
-
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3117
|
-
}
|
|
3118
|
-
),
|
|
3119
|
-
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3120
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "none", children: "None" }),
|
|
3121
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "field", children: "The visitor (email field)" }),
|
|
3122
|
-
/* @__PURE__ */ jsx8(SelectItem5, { value: "custom", children: "A custom address" })
|
|
3123
|
-
] })
|
|
3124
|
-
]
|
|
3125
|
-
}
|
|
3126
|
-
)
|
|
3127
|
-
] }),
|
|
3128
|
-
replyToMode === "field" && /* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
3129
|
-
/* @__PURE__ */ jsx8(Label2, { htmlFor: "notification-replyto", children: "Visitor email field" }),
|
|
3130
|
-
/* @__PURE__ */ jsxs7(
|
|
3131
|
-
Select5,
|
|
3132
|
-
{
|
|
3133
|
-
value: replyToRef ?? "__none",
|
|
3134
|
-
onValueChange: (value) => update(
|
|
3135
|
-
"replyTo",
|
|
3136
|
-
value === "__none" ? void 0 : toFieldRef(value)
|
|
3137
|
-
),
|
|
3138
|
-
children: [
|
|
3139
|
-
/* @__PURE__ */ jsx8(
|
|
3140
|
-
SelectTrigger5,
|
|
3141
|
-
{
|
|
3142
|
-
id: "notification-replyto",
|
|
3143
|
-
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3144
|
-
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3145
|
-
}
|
|
3102
|
+
) }),
|
|
3103
|
+
replyToMode === "field" && /* @__PURE__ */ jsx8(
|
|
3104
|
+
FieldShell,
|
|
3105
|
+
{
|
|
3106
|
+
label: "Visitor email field",
|
|
3107
|
+
htmlFor: "notification-replyto",
|
|
3108
|
+
children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
3109
|
+
Select5,
|
|
3110
|
+
{
|
|
3111
|
+
value: replyToRef ?? "__none",
|
|
3112
|
+
onValueChange: (value) => update(
|
|
3113
|
+
"replyTo",
|
|
3114
|
+
value === "__none" ? void 0 : toFieldRef(value)
|
|
3146
3115
|
),
|
|
3147
|
-
|
|
3148
|
-
/* @__PURE__ */ jsx8(
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3116
|
+
children: [
|
|
3117
|
+
/* @__PURE__ */ jsx8(
|
|
3118
|
+
SelectTrigger5,
|
|
3119
|
+
{
|
|
3120
|
+
id,
|
|
3121
|
+
"aria-describedby": describedBy,
|
|
3122
|
+
"aria-invalid": invalid,
|
|
3123
|
+
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3124
|
+
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3125
|
+
}
|
|
3126
|
+
),
|
|
3127
|
+
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3128
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "__none", children: "Select a field" }),
|
|
3129
|
+
replyToFieldOptions.map((f) => /* @__PURE__ */ jsx8(SelectItem5, { value: f.name, children: f.label }, f.name))
|
|
3130
|
+
] })
|
|
3131
|
+
]
|
|
3132
|
+
}
|
|
3133
|
+
)
|
|
3134
|
+
}
|
|
3135
|
+
),
|
|
3136
|
+
replyToMode === "custom" && /* @__PURE__ */ jsx8(
|
|
3137
|
+
FieldShell,
|
|
3138
|
+
{
|
|
3139
|
+
label: "Reply-To address",
|
|
3140
|
+
htmlFor: "notification-replyto",
|
|
3141
|
+
width: "half",
|
|
3142
|
+
error: addressErrors.replyTo,
|
|
3143
|
+
children: /* @__PURE__ */ jsx8(
|
|
3144
|
+
Input3,
|
|
3145
|
+
{
|
|
3146
|
+
type: "email",
|
|
3147
|
+
value: form.replyTo ?? "",
|
|
3148
|
+
onChange: (e) => update("replyTo", e.target.value || void 0),
|
|
3149
|
+
placeholder: "replies@example.com"
|
|
3150
|
+
}
|
|
3151
|
+
)
|
|
3152
|
+
}
|
|
3153
|
+
)
|
|
3170
3154
|
] }),
|
|
3171
3155
|
replyToMode === "field" && /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground -mt-2", children: "Replying to this email answers the person who submitted the form." }),
|
|
3172
3156
|
/* @__PURE__ */ jsx8(
|
|
@@ -3216,74 +3200,92 @@ function NotificationSheet({
|
|
|
3216
3200
|
)
|
|
3217
3201
|
] }),
|
|
3218
3202
|
condition && /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-end gap-2 border border-border bg-muted/40 p-3", children: [
|
|
3219
|
-
/* @__PURE__ */
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3203
|
+
/* @__PURE__ */ jsx8(
|
|
3204
|
+
FieldShell,
|
|
3205
|
+
{
|
|
3206
|
+
label: "Field",
|
|
3207
|
+
htmlFor: "notification-condition-field",
|
|
3208
|
+
className: "min-w-36 flex-1",
|
|
3209
|
+
children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
3210
|
+
Select5,
|
|
3211
|
+
{
|
|
3212
|
+
value: condition.field || "__none",
|
|
3213
|
+
onValueChange: (value) => update("condition", {
|
|
3214
|
+
...condition,
|
|
3215
|
+
field: value === "__none" ? "" : value
|
|
3216
|
+
}),
|
|
3217
|
+
children: [
|
|
3218
|
+
/* @__PURE__ */ jsx8(
|
|
3219
|
+
SelectTrigger5,
|
|
3220
|
+
{
|
|
3221
|
+
id,
|
|
3222
|
+
"aria-describedby": describedBy,
|
|
3223
|
+
"aria-invalid": invalid,
|
|
3224
|
+
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3225
|
+
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3226
|
+
}
|
|
3227
|
+
),
|
|
3228
|
+
/* @__PURE__ */ jsxs7(SelectContent5, { children: [
|
|
3229
|
+
/* @__PURE__ */ jsx8(SelectItem5, { value: "__none", children: "Select a field" }),
|
|
3230
|
+
fields.map((f) => /* @__PURE__ */ jsx8(SelectItem5, { value: f.name, children: f.label }, f.name))
|
|
3231
|
+
] })
|
|
3232
|
+
]
|
|
3233
|
+
}
|
|
3234
|
+
)
|
|
3235
|
+
}
|
|
3236
|
+
),
|
|
3237
|
+
/* @__PURE__ */ jsx8(
|
|
3238
|
+
FieldShell,
|
|
3239
|
+
{
|
|
3240
|
+
label: "Comparison",
|
|
3241
|
+
htmlFor: "notification-condition-comparison",
|
|
3242
|
+
className: "min-w-36 flex-1",
|
|
3243
|
+
children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs7(
|
|
3244
|
+
Select5,
|
|
3245
|
+
{
|
|
3246
|
+
value: condition.comparison,
|
|
3247
|
+
onValueChange: (value) => update("condition", {
|
|
3248
|
+
...condition,
|
|
3249
|
+
comparison: value
|
|
3250
|
+
}),
|
|
3251
|
+
children: [
|
|
3252
|
+
/* @__PURE__ */ jsx8(
|
|
3253
|
+
SelectTrigger5,
|
|
3254
|
+
{
|
|
3255
|
+
id,
|
|
3256
|
+
"aria-describedby": describedBy,
|
|
3257
|
+
"aria-invalid": invalid,
|
|
3258
|
+
className: "w-full bg-transparent border-input dark:bg-muted/50",
|
|
3259
|
+
children: /* @__PURE__ */ jsx8(SelectValue5, {})
|
|
3260
|
+
}
|
|
3261
|
+
),
|
|
3262
|
+
/* @__PURE__ */ jsx8(SelectContent5, { children: Object.entries(COMPARISON_LABELS).map(
|
|
3263
|
+
([value, label]) => /* @__PURE__ */ jsx8(SelectItem5, { value, children: label }, value)
|
|
3264
|
+
) })
|
|
3265
|
+
]
|
|
3266
|
+
}
|
|
3267
|
+
)
|
|
3268
|
+
}
|
|
3269
|
+
),
|
|
3270
|
+
!VALUELESS_COMPARISONS.has(condition.comparison) && /* @__PURE__ */ jsx8(
|
|
3271
|
+
FieldShell,
|
|
3272
|
+
{
|
|
3273
|
+
label: "Value",
|
|
3274
|
+
htmlFor: "notification-condition-value",
|
|
3275
|
+
className: "min-w-36 flex-1",
|
|
3276
|
+
children: /* @__PURE__ */ jsx8(
|
|
3277
|
+
Input3,
|
|
3278
|
+
{
|
|
3279
|
+
type: "text",
|
|
3280
|
+
value: typeof condition.value === "string" || typeof condition.value === "number" ? String(condition.value) : "",
|
|
3281
|
+
onChange: (e) => update("condition", {
|
|
3282
|
+
...condition,
|
|
3283
|
+
value: e.target.value
|
|
3284
|
+
})
|
|
3285
|
+
}
|
|
3286
|
+
)
|
|
3287
|
+
}
|
|
3288
|
+
),
|
|
3287
3289
|
/* @__PURE__ */ jsx8(
|
|
3288
3290
|
Button6,
|
|
3289
3291
|
{
|
|
@@ -3382,52 +3384,55 @@ function FormNotificationsTab({ defaults }) {
|
|
|
3382
3384
|
[providers]
|
|
3383
3385
|
);
|
|
3384
3386
|
const initialNotification = sheetState.editing ?? createNotification();
|
|
3385
|
-
return
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
/* @__PURE__ */
|
|
3387
|
+
return (
|
|
3388
|
+
// The measure belongs to `FormLayout` now, not to this tab.
|
|
3389
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
3390
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between mb-8 pb-4 border-b border-border", children: [
|
|
3391
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
3392
|
+
/* @__PURE__ */ jsx8("h3", { className: "text-xl font-semibold text-foreground", children: "Notifications" }),
|
|
3393
|
+
/* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground mt-1", children: "Emails sent when someone submits this form." })
|
|
3394
|
+
] }),
|
|
3395
|
+
/* @__PURE__ */ jsxs7(Button6, { type: "button", onClick: openAddSheet, children: [
|
|
3396
|
+
/* @__PURE__ */ jsx8(Plus2, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
3397
|
+
"Add notification"
|
|
3398
|
+
] })
|
|
3390
3399
|
] }),
|
|
3391
|
-
/* @__PURE__ */ jsxs7(
|
|
3392
|
-
/* @__PURE__ */ jsx8(
|
|
3393
|
-
"
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
/* @__PURE__ */ jsx8("
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
onClose: closeSheet
|
|
3428
|
-
}
|
|
3429
|
-
)
|
|
3430
|
-
] });
|
|
3400
|
+
notifications.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center justify-center p-12 mt-6 border-2 border-dashed border-border rounded-none bg-muted", children: [
|
|
3401
|
+
/* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center w-12 h-12 rounded-none border border-border bg-background mb-4 text-primary", children: /* @__PURE__ */ jsx8(Mail, { className: "h-6 w-6", "aria-hidden": "true" }) }),
|
|
3402
|
+
/* @__PURE__ */ jsx8("p", { className: "text-base font-medium text-foreground mb-1", children: "No notifications yet" }),
|
|
3403
|
+
/* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground mb-6 text-center max-w-sm", children: "Add a notification to email someone when this form is submitted." }),
|
|
3404
|
+
/* @__PURE__ */ jsxs7(Button6, { type: "button", onClick: openAddSheet, children: [
|
|
3405
|
+
/* @__PURE__ */ jsx8(Plus2, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
3406
|
+
"Add notification"
|
|
3407
|
+
] })
|
|
3408
|
+
] }) : /* @__PURE__ */ jsx8("div", { className: "space-y-2", children: notifications.map((notification) => /* @__PURE__ */ jsx8(
|
|
3409
|
+
NotificationCard,
|
|
3410
|
+
{
|
|
3411
|
+
notification,
|
|
3412
|
+
providerName: getProviderName(notification.providerId),
|
|
3413
|
+
fields: fieldList,
|
|
3414
|
+
onEdit: () => openEditSheet(notification),
|
|
3415
|
+
onDuplicate: () => duplicateNotification(notification.id),
|
|
3416
|
+
onDelete: () => deleteNotification(notification.id),
|
|
3417
|
+
onToggleEnabled: (enabled) => updateNotification(notification.id, { enabled })
|
|
3418
|
+
},
|
|
3419
|
+
notification.id
|
|
3420
|
+
)) }),
|
|
3421
|
+
sheetState.open && /* @__PURE__ */ jsx8(
|
|
3422
|
+
NotificationSheet,
|
|
3423
|
+
{
|
|
3424
|
+
initial: initialNotification,
|
|
3425
|
+
isEditing: !!sheetState.editing,
|
|
3426
|
+
providers,
|
|
3427
|
+
templates,
|
|
3428
|
+
fields: fieldList,
|
|
3429
|
+
defaults,
|
|
3430
|
+
onSave: handleSave,
|
|
3431
|
+
onClose: closeSheet
|
|
3432
|
+
}
|
|
3433
|
+
)
|
|
3434
|
+
] })
|
|
3435
|
+
);
|
|
3431
3436
|
}
|
|
3432
3437
|
|
|
3433
3438
|
// src/admin/components/builder/FormPreview.tsx
|
|
@@ -3750,7 +3755,7 @@ function SettingRow({
|
|
|
3750
3755
|
children
|
|
3751
3756
|
}) {
|
|
3752
3757
|
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-6 py-2", children: [
|
|
3753
|
-
/* @__PURE__ */ jsxs9("div", { className: "space-y-1
|
|
3758
|
+
/* @__PURE__ */ jsxs9("div", { className: "space-y-1", children: [
|
|
3754
3759
|
/* @__PURE__ */ jsx10(
|
|
3755
3760
|
Label4,
|
|
3756
3761
|
{
|
|
@@ -3799,172 +3804,175 @@ function InheritToggle({
|
|
|
3799
3804
|
}
|
|
3800
3805
|
function FormSettingsTab({ spamDefaults }) {
|
|
3801
3806
|
const { settings, updateSettings } = useFormBuilder();
|
|
3802
|
-
return
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
/* @__PURE__ */ jsxs9("
|
|
3806
|
-
/* @__PURE__ */ jsx10(
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
/* @__PURE__ */ jsxs9("
|
|
3845
|
-
|
|
3846
|
-
/* @__PURE__ */ jsxs9(
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
id: "settings-confirm-message",
|
|
3861
|
-
className: "mt-0.5"
|
|
3862
|
-
}
|
|
3863
|
-
),
|
|
3864
|
-
/* @__PURE__ */ jsxs9("div", { className: "w-full space-y-2", children: [
|
|
3865
|
-
/* @__PURE__ */ jsx10(Label4, { htmlFor: "settings-confirm-message", children: "Show a message" }),
|
|
3866
|
-
(settings.confirmationType ?? "message") === "message" && /* @__PURE__ */ jsx10(
|
|
3867
|
-
Textarea3,
|
|
3807
|
+
return (
|
|
3808
|
+
// The measure belongs to `FormLayout` now, not to this tab.
|
|
3809
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-10", children: [
|
|
3810
|
+
/* @__PURE__ */ jsxs9("section", { children: [
|
|
3811
|
+
/* @__PURE__ */ jsx10(SectionHeading, { children: "Submission" }),
|
|
3812
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1 pt-2", children: [
|
|
3813
|
+
/* @__PURE__ */ jsx10(
|
|
3814
|
+
SettingRow,
|
|
3815
|
+
{
|
|
3816
|
+
label: "Submit button text",
|
|
3817
|
+
description: "Label on the form's primary action button",
|
|
3818
|
+
htmlFor: "settings-submit-text",
|
|
3819
|
+
children: /* @__PURE__ */ jsx10(
|
|
3820
|
+
Input5,
|
|
3821
|
+
{
|
|
3822
|
+
id: "settings-submit-text",
|
|
3823
|
+
type: "text",
|
|
3824
|
+
className: "w-56",
|
|
3825
|
+
value: settings.submitButtonText ?? "",
|
|
3826
|
+
onChange: (e) => updateSettings({ submitButtonText: e.target.value })
|
|
3827
|
+
}
|
|
3828
|
+
)
|
|
3829
|
+
}
|
|
3830
|
+
),
|
|
3831
|
+
/* @__PURE__ */ jsx10(
|
|
3832
|
+
SettingRow,
|
|
3833
|
+
{
|
|
3834
|
+
label: "Allow multiple submissions",
|
|
3835
|
+
description: "When off, the same visitor (by IP) can submit this form only once. Best-effort: IP-based, so shared networks count as one visitor.",
|
|
3836
|
+
htmlFor: "settings-multiple",
|
|
3837
|
+
children: /* @__PURE__ */ jsx10(
|
|
3838
|
+
Switch3,
|
|
3839
|
+
{
|
|
3840
|
+
id: "settings-multiple",
|
|
3841
|
+
checked: settings.allowMultipleSubmissions ?? true,
|
|
3842
|
+
onCheckedChange: (checked) => updateSettings({ allowMultipleSubmissions: checked })
|
|
3843
|
+
}
|
|
3844
|
+
)
|
|
3845
|
+
}
|
|
3846
|
+
)
|
|
3847
|
+
] })
|
|
3848
|
+
] }),
|
|
3849
|
+
/* @__PURE__ */ jsxs9("section", { children: [
|
|
3850
|
+
/* @__PURE__ */ jsx10(SectionHeading, { children: "After submission" }),
|
|
3851
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-4 pt-4", children: [
|
|
3852
|
+
settings.confirmationType === "relationship" && /* @__PURE__ */ jsx10("p", { className: "border border-border bg-muted/40 p-3 text-sm text-muted-foreground", children: "This form redirects to a linked page (configured via the API). Picking an option below replaces that behavior." }),
|
|
3853
|
+
/* @__PURE__ */ jsxs9(
|
|
3854
|
+
RadioGroup2,
|
|
3855
|
+
{
|
|
3856
|
+
value: settings.confirmationType ?? "message",
|
|
3857
|
+
onValueChange: (value) => updateSettings({
|
|
3858
|
+
confirmationType: value
|
|
3859
|
+
}),
|
|
3860
|
+
className: "flex flex-col gap-3",
|
|
3861
|
+
children: [
|
|
3862
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-3", children: [
|
|
3863
|
+
/* @__PURE__ */ jsx10(
|
|
3864
|
+
RadioGroupItem2,
|
|
3868
3865
|
{
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
rows: 3,
|
|
3873
|
-
placeholder: "Thank you for your submission!"
|
|
3866
|
+
value: "message",
|
|
3867
|
+
id: "settings-confirm-message",
|
|
3868
|
+
className: "mt-0.5"
|
|
3874
3869
|
}
|
|
3875
|
-
)
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3870
|
+
),
|
|
3871
|
+
/* @__PURE__ */ jsxs9("div", { className: "w-full space-y-2", children: [
|
|
3872
|
+
/* @__PURE__ */ jsx10(Label4, { htmlFor: "settings-confirm-message", children: "Show a message" }),
|
|
3873
|
+
(settings.confirmationType ?? "message") === "message" && /* @__PURE__ */ jsx10(
|
|
3874
|
+
Textarea3,
|
|
3875
|
+
{
|
|
3876
|
+
"aria-label": "Success message",
|
|
3877
|
+
value: settings.successMessage ?? "",
|
|
3878
|
+
onChange: (e) => updateSettings({ successMessage: e.target.value }),
|
|
3879
|
+
rows: 3,
|
|
3880
|
+
placeholder: "Thank you for your submission!"
|
|
3881
|
+
}
|
|
3882
|
+
)
|
|
3883
|
+
] })
|
|
3884
|
+
] }),
|
|
3885
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-3", children: [
|
|
3886
|
+
/* @__PURE__ */ jsx10(
|
|
3887
|
+
RadioGroupItem2,
|
|
3891
3888
|
{
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
onChange: (e) => updateSettings({
|
|
3896
|
-
redirectUrl: e.target.value || void 0
|
|
3897
|
-
}),
|
|
3898
|
-
placeholder: "https://example.com/thanks"
|
|
3889
|
+
value: "redirect",
|
|
3890
|
+
id: "settings-confirm-redirect",
|
|
3891
|
+
className: "mt-0.5"
|
|
3899
3892
|
}
|
|
3900
|
-
)
|
|
3893
|
+
),
|
|
3894
|
+
/* @__PURE__ */ jsxs9("div", { className: "w-full space-y-2", children: [
|
|
3895
|
+
/* @__PURE__ */ jsx10(Label4, { htmlFor: "settings-confirm-redirect", children: "Redirect to a URL" }),
|
|
3896
|
+
settings.confirmationType === "redirect" && /* @__PURE__ */ jsx10(
|
|
3897
|
+
Input5,
|
|
3898
|
+
{
|
|
3899
|
+
"aria-label": "Redirect URL",
|
|
3900
|
+
type: "url",
|
|
3901
|
+
value: settings.redirectUrl ?? "",
|
|
3902
|
+
onChange: (e) => updateSettings({
|
|
3903
|
+
redirectUrl: e.target.value || void 0
|
|
3904
|
+
}),
|
|
3905
|
+
placeholder: "https://example.com/thanks"
|
|
3906
|
+
}
|
|
3907
|
+
)
|
|
3908
|
+
] })
|
|
3901
3909
|
] })
|
|
3902
|
-
]
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
)
|
|
3906
|
-
] })
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
}
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
)
|
|
3910
|
+
]
|
|
3911
|
+
}
|
|
3912
|
+
)
|
|
3913
|
+
] })
|
|
3914
|
+
] }),
|
|
3915
|
+
/* @__PURE__ */ jsxs9("section", { children: [
|
|
3916
|
+
/* @__PURE__ */ jsx10(SectionHeading, { children: "Spam protection" }),
|
|
3917
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1 pt-2", children: [
|
|
3918
|
+
/* @__PURE__ */ jsx10(
|
|
3919
|
+
SettingRow,
|
|
3920
|
+
{
|
|
3921
|
+
label: "Honeypot",
|
|
3922
|
+
description: "Invisible trap field for bots. Inherits the plugin default unless overridden here.",
|
|
3923
|
+
htmlFor: "settings-honeypot",
|
|
3924
|
+
children: /* @__PURE__ */ jsx10(
|
|
3925
|
+
InheritToggle,
|
|
3926
|
+
{
|
|
3927
|
+
id: "settings-honeypot",
|
|
3928
|
+
value: settings.honeypotEnabled,
|
|
3929
|
+
inherited: spamDefaults?.honeypot,
|
|
3930
|
+
onChange: (honeypotEnabled) => updateSettings({ honeypotEnabled })
|
|
3931
|
+
}
|
|
3932
|
+
)
|
|
3933
|
+
}
|
|
3934
|
+
),
|
|
3935
|
+
/* @__PURE__ */ jsx10(
|
|
3936
|
+
SettingRow,
|
|
3937
|
+
{
|
|
3938
|
+
label: "reCAPTCHA",
|
|
3939
|
+
description: "Challenge-based bot check. Inherits the plugin default unless overridden here.",
|
|
3940
|
+
htmlFor: "settings-captcha",
|
|
3941
|
+
children: /* @__PURE__ */ jsx10(
|
|
3942
|
+
InheritToggle,
|
|
3943
|
+
{
|
|
3944
|
+
id: "settings-captcha",
|
|
3945
|
+
value: settings.captchaEnabled,
|
|
3946
|
+
inherited: spamDefaults?.recaptchaEnabled,
|
|
3947
|
+
onChange: (captchaEnabled) => updateSettings({ captchaEnabled })
|
|
3948
|
+
}
|
|
3949
|
+
)
|
|
3950
|
+
}
|
|
3951
|
+
),
|
|
3952
|
+
settings.captchaEnabled === true && /* @__PURE__ */ jsx10(
|
|
3953
|
+
SettingRow,
|
|
3954
|
+
{
|
|
3955
|
+
label: "reCAPTCHA site key",
|
|
3956
|
+
description: "The client-facing site key for this form",
|
|
3957
|
+
htmlFor: "settings-captcha-key",
|
|
3958
|
+
children: /* @__PURE__ */ jsx10(
|
|
3959
|
+
Input5,
|
|
3960
|
+
{
|
|
3961
|
+
id: "settings-captcha-key",
|
|
3962
|
+
type: "text",
|
|
3963
|
+
className: "w-72 font-mono",
|
|
3964
|
+
value: settings.captchaSiteKey ?? "",
|
|
3965
|
+
onChange: (e) => updateSettings({
|
|
3966
|
+
captchaSiteKey: e.target.value || void 0
|
|
3967
|
+
})
|
|
3968
|
+
}
|
|
3969
|
+
)
|
|
3970
|
+
}
|
|
3971
|
+
)
|
|
3972
|
+
] })
|
|
3965
3973
|
] })
|
|
3966
3974
|
] })
|
|
3967
|
-
|
|
3975
|
+
);
|
|
3968
3976
|
}
|
|
3969
3977
|
|
|
3970
3978
|
// src/admin/FormBuilderView.tsx
|
|
@@ -4157,88 +4165,22 @@ function FormBuilderViewInner({
|
|
|
4157
4165
|
count: notifications.length > 0 ? notifications.length : null
|
|
4158
4166
|
}
|
|
4159
4167
|
];
|
|
4160
|
-
return /* @__PURE__ */ jsxs10(
|
|
4161
|
-
/* @__PURE__ */ jsxs10("div", { className: "
|
|
4162
|
-
/* @__PURE__ */
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
/* @__PURE__ */ jsxs10("div", { className: "flex
|
|
4167
|
-
isDirty && // Full-strength warning border so the unsaved-changes badge boundary is perceivable over its tinted fill.
|
|
4168
|
-
/* @__PURE__ */ jsx11("span", { className: "text-xs font-medium bg-warning-100 text-warning-700 dark:bg-warning-900 dark:text-warning-100 border border-warning px-2.5 py-1 rounded-none whitespace-nowrap", children: "Unsaved changes" }),
|
|
4169
|
-
/* @__PURE__ */ jsx11(
|
|
4170
|
-
Button8,
|
|
4171
|
-
{
|
|
4172
|
-
type: "button",
|
|
4173
|
-
variant: "outline",
|
|
4174
|
-
size: "sm",
|
|
4175
|
-
onClick: handleCancel,
|
|
4176
|
-
disabled: isSaving,
|
|
4177
|
-
children: "Cancel"
|
|
4178
|
-
}
|
|
4179
|
-
),
|
|
4168
|
+
return /* @__PURE__ */ jsxs10(FormLayout, { children: [
|
|
4169
|
+
/* @__PURE__ */ jsxs10("div", { className: "mb-6", children: [
|
|
4170
|
+
/* @__PURE__ */ jsx11("h1", { className: "text-2xl font-semibold text-foreground tracking-tight", children: isCreating ? "Create Form" : "Edit Form" }),
|
|
4171
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm text-muted-foreground mt-1", children: isCreating ? "Design a new form with drag-and-drop fields." : "Modify your form fields and settings." })
|
|
4172
|
+
] }),
|
|
4173
|
+
/* @__PURE__ */ jsxs10("div", { className: "border-b border-border space-y-4 pb-4 mb-6", children: [
|
|
4174
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap gap-4", children: [
|
|
4180
4175
|
/* @__PURE__ */ jsx11(
|
|
4181
|
-
|
|
4176
|
+
FieldShell2,
|
|
4182
4177
|
{
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
},
|
|
4188
|
-
disabled: isSaving,
|
|
4189
|
-
className: "flex items-center gap-1.5",
|
|
4190
|
-
children: isSaving ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
4191
|
-
/* @__PURE__ */ jsxs10(
|
|
4192
|
-
"svg",
|
|
4193
|
-
{
|
|
4194
|
-
className: "animate-spin h-3.5 w-3.5",
|
|
4195
|
-
viewBox: "0 0 24 24",
|
|
4196
|
-
fill: "none",
|
|
4197
|
-
children: [
|
|
4198
|
-
/* @__PURE__ */ jsx11(
|
|
4199
|
-
"circle",
|
|
4200
|
-
{
|
|
4201
|
-
className: "opacity-25",
|
|
4202
|
-
cx: "12",
|
|
4203
|
-
cy: "12",
|
|
4204
|
-
r: "10",
|
|
4205
|
-
stroke: "currentColor",
|
|
4206
|
-
strokeWidth: "4"
|
|
4207
|
-
}
|
|
4208
|
-
),
|
|
4209
|
-
/* @__PURE__ */ jsx11(
|
|
4210
|
-
"path",
|
|
4211
|
-
{
|
|
4212
|
-
className: "opacity-75",
|
|
4213
|
-
fill: "currentColor",
|
|
4214
|
-
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
4215
|
-
}
|
|
4216
|
-
)
|
|
4217
|
-
]
|
|
4218
|
-
}
|
|
4219
|
-
),
|
|
4220
|
-
"Saving\u2026"
|
|
4221
|
-
] }) : isCreating ? "Create" : "Save Changes"
|
|
4222
|
-
}
|
|
4223
|
-
)
|
|
4224
|
-
] })
|
|
4225
|
-
] }),
|
|
4226
|
-
/* @__PURE__ */ jsx11("div", { className: "flex border border-border bg-background overflow-hidden", children: /* @__PURE__ */ jsx11("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs10("div", { className: "w-full px-8 pt-8 pb-12 space-y-6", children: [
|
|
4227
|
-
/* @__PURE__ */ jsxs10("div", { className: "bg-background -mx-8 px-8 border-b border-border space-y-4", children: [
|
|
4228
|
-
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap gap-4", children: [
|
|
4229
|
-
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-[200px] max-w-sm space-y-1.5", children: [
|
|
4230
|
-
/* @__PURE__ */ jsx11(
|
|
4231
|
-
"label",
|
|
4232
|
-
{
|
|
4233
|
-
htmlFor: "form-name",
|
|
4234
|
-
className: "text-sm font-medium text-foreground",
|
|
4235
|
-
children: "Form Name"
|
|
4236
|
-
}
|
|
4237
|
-
),
|
|
4238
|
-
/* @__PURE__ */ jsx11(
|
|
4178
|
+
label: "Form Name",
|
|
4179
|
+
htmlFor: "form-name",
|
|
4180
|
+
className: "flex-1 min-w-[200px]",
|
|
4181
|
+
children: /* @__PURE__ */ jsx11(
|
|
4239
4182
|
Input6,
|
|
4240
4183
|
{
|
|
4241
|
-
id: "form-name",
|
|
4242
4184
|
type: "text",
|
|
4243
4185
|
value: formData.name || "",
|
|
4244
4186
|
onChange: (e) => handleNameChange(e.target.value),
|
|
@@ -4246,20 +4188,17 @@ function FormBuilderViewInner({
|
|
|
4246
4188
|
className: "bg-transparent"
|
|
4247
4189
|
}
|
|
4248
4190
|
)
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
),
|
|
4259
|
-
/* @__PURE__ */ jsx11(
|
|
4191
|
+
}
|
|
4192
|
+
),
|
|
4193
|
+
/* @__PURE__ */ jsx11(
|
|
4194
|
+
FieldShell2,
|
|
4195
|
+
{
|
|
4196
|
+
label: "Slug",
|
|
4197
|
+
htmlFor: "form-slug",
|
|
4198
|
+
className: "flex-1 min-w-[160px]",
|
|
4199
|
+
children: /* @__PURE__ */ jsx11(
|
|
4260
4200
|
Input6,
|
|
4261
4201
|
{
|
|
4262
|
-
id: "form-slug",
|
|
4263
4202
|
type: "text",
|
|
4264
4203
|
value: formData.slug || "",
|
|
4265
4204
|
onChange: (e) => updateFormData({ slug: e.target.value }),
|
|
@@ -4267,75 +4206,131 @@ function FormBuilderViewInner({
|
|
|
4267
4206
|
className: "bg-transparent placeholder:text-muted-foreground"
|
|
4268
4207
|
}
|
|
4269
4208
|
)
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
{
|
|
4275
|
-
htmlFor: "form-status",
|
|
4276
|
-
className: "text-sm font-medium text-foreground",
|
|
4277
|
-
children: "Status"
|
|
4278
|
-
}
|
|
4279
|
-
),
|
|
4280
|
-
/* @__PURE__ */ jsxs10(
|
|
4281
|
-
Select8,
|
|
4282
|
-
{
|
|
4283
|
-
value: formData.status || "draft",
|
|
4284
|
-
onValueChange: (value) => updateFormData({
|
|
4285
|
-
status: value
|
|
4286
|
-
}),
|
|
4287
|
-
children: [
|
|
4288
|
-
/* @__PURE__ */ jsx11(SelectTrigger8, { id: "form-status", className: "bg-transparent", children: /* @__PURE__ */ jsx11(SelectValue8, { placeholder: "Status" }) }),
|
|
4289
|
-
/* @__PURE__ */ jsxs10(SelectContent8, { children: [
|
|
4290
|
-
/* @__PURE__ */ jsx11(SelectItem8, { value: "draft", children: "Draft" }),
|
|
4291
|
-
/* @__PURE__ */ jsx11(SelectItem8, { value: "published", children: "Published" }),
|
|
4292
|
-
/* @__PURE__ */ jsx11(SelectItem8, { value: "closed", children: "Closed" })
|
|
4293
|
-
] })
|
|
4294
|
-
]
|
|
4295
|
-
}
|
|
4296
|
-
)
|
|
4297
|
-
] })
|
|
4298
|
-
] }),
|
|
4299
|
-
/* @__PURE__ */ jsx11(
|
|
4300
|
-
Tabs4,
|
|
4209
|
+
}
|
|
4210
|
+
),
|
|
4211
|
+
/* @__PURE__ */ jsx11("div", { className: "w-36", children: /* @__PURE__ */ jsx11(FieldShell2, { label: "Status", htmlFor: "form-status", children: ({ id, describedBy, invalid }) => /* @__PURE__ */ jsxs10(
|
|
4212
|
+
Select8,
|
|
4301
4213
|
{
|
|
4302
|
-
value:
|
|
4303
|
-
onValueChange: (
|
|
4304
|
-
|
|
4305
|
-
|
|
4214
|
+
value: formData.status || "draft",
|
|
4215
|
+
onValueChange: (value) => updateFormData({
|
|
4216
|
+
status: value
|
|
4217
|
+
}),
|
|
4218
|
+
children: [
|
|
4219
|
+
/* @__PURE__ */ jsx11(
|
|
4220
|
+
SelectTrigger8,
|
|
4221
|
+
{
|
|
4222
|
+
id,
|
|
4223
|
+
"aria-describedby": describedBy,
|
|
4224
|
+
"aria-invalid": invalid,
|
|
4225
|
+
className: "bg-transparent",
|
|
4226
|
+
children: /* @__PURE__ */ jsx11(SelectValue8, { placeholder: "Status" })
|
|
4227
|
+
}
|
|
4228
|
+
),
|
|
4229
|
+
/* @__PURE__ */ jsxs10(SelectContent8, { children: [
|
|
4230
|
+
/* @__PURE__ */ jsx11(SelectItem8, { value: "draft", children: "Draft" }),
|
|
4231
|
+
/* @__PURE__ */ jsx11(SelectItem8, { value: "published", children: "Published" }),
|
|
4232
|
+
/* @__PURE__ */ jsx11(SelectItem8, { value: "closed", children: "Closed" })
|
|
4233
|
+
] })
|
|
4234
|
+
]
|
|
4235
|
+
}
|
|
4236
|
+
) }) })
|
|
4237
|
+
] }),
|
|
4238
|
+
/* @__PURE__ */ jsx11(
|
|
4239
|
+
Tabs4,
|
|
4240
|
+
{
|
|
4241
|
+
value: activeTab,
|
|
4242
|
+
onValueChange: (v) => setActiveTab(v),
|
|
4243
|
+
children: /* @__PURE__ */ jsx11(TabsList4, { className: "bg-transparent justify-start gap-0 max-w-full overflow-x-auto", children: mainTabs.map((tab) => /* @__PURE__ */ jsxs10(
|
|
4244
|
+
TabsTrigger4,
|
|
4245
|
+
{
|
|
4246
|
+
value: tab.value,
|
|
4247
|
+
className: "shrink-0 whitespace-nowrap",
|
|
4248
|
+
children: [
|
|
4249
|
+
tab.label,
|
|
4250
|
+
tab.count !== null && /* @__PURE__ */ jsx11(
|
|
4251
|
+
"span",
|
|
4252
|
+
{
|
|
4253
|
+
className: `inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 text-[10px] font-semibold rounded-sm ml-2 transition-colors ${activeTab === tab.value ? "bg-primary/5 text-primary" : "bg-primary/5 text-muted-foreground"}`,
|
|
4254
|
+
children: tab.count
|
|
4255
|
+
}
|
|
4256
|
+
)
|
|
4257
|
+
]
|
|
4258
|
+
},
|
|
4259
|
+
tab.value
|
|
4260
|
+
)) })
|
|
4261
|
+
}
|
|
4262
|
+
)
|
|
4263
|
+
] }),
|
|
4264
|
+
activeTab === "builder" && /* @__PURE__ */ jsx11(
|
|
4265
|
+
FieldCards,
|
|
4266
|
+
{
|
|
4267
|
+
enabledTypes,
|
|
4268
|
+
disabledFieldTypes,
|
|
4269
|
+
onAddField: handleAddField
|
|
4270
|
+
}
|
|
4271
|
+
),
|
|
4272
|
+
activeTab === "preview" && /* @__PURE__ */ jsx11(FormPreview, { fields, formData }),
|
|
4273
|
+
activeTab === "settings" && /* @__PURE__ */ jsx11(FormSettingsTab, { spamDefaults }),
|
|
4274
|
+
activeTab === "notifications" && /* @__PURE__ */ jsx11(FormNotificationsTab, { defaults: notificationDefaults }),
|
|
4275
|
+
saveError && // Full-strength destructive border so the error box boundary is perceivable over its tinted fill.
|
|
4276
|
+
/* @__PURE__ */ jsx11("div", { className: "mt-6 p-3 text-sm text-destructive bg-destructive/10 border border-destructive rounded-none", children: saveError }),
|
|
4277
|
+
/* @__PURE__ */ jsxs10(FormActions, { dirty: isDirty, children: [
|
|
4278
|
+
/* @__PURE__ */ jsx11(
|
|
4279
|
+
Button8,
|
|
4280
|
+
{
|
|
4281
|
+
type: "button",
|
|
4282
|
+
variant: "outline",
|
|
4283
|
+
size: "sm",
|
|
4284
|
+
onClick: handleCancel,
|
|
4285
|
+
disabled: isSaving,
|
|
4286
|
+
children: "Cancel"
|
|
4287
|
+
}
|
|
4288
|
+
),
|
|
4289
|
+
/* @__PURE__ */ jsx11(
|
|
4290
|
+
Button8,
|
|
4291
|
+
{
|
|
4292
|
+
type: "button",
|
|
4293
|
+
size: "sm",
|
|
4294
|
+
onClick: () => {
|
|
4295
|
+
void handleSave();
|
|
4296
|
+
},
|
|
4297
|
+
disabled: isSaving,
|
|
4298
|
+
className: "flex items-center gap-1.5",
|
|
4299
|
+
children: isSaving ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
4300
|
+
/* @__PURE__ */ jsxs10(
|
|
4301
|
+
"svg",
|
|
4306
4302
|
{
|
|
4307
|
-
|
|
4308
|
-
|
|
4303
|
+
className: "animate-spin h-3.5 w-3.5",
|
|
4304
|
+
viewBox: "0 0 24 24",
|
|
4305
|
+
fill: "none",
|
|
4309
4306
|
children: [
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4307
|
+
/* @__PURE__ */ jsx11(
|
|
4308
|
+
"circle",
|
|
4309
|
+
{
|
|
4310
|
+
className: "opacity-25",
|
|
4311
|
+
cx: "12",
|
|
4312
|
+
cy: "12",
|
|
4313
|
+
r: "10",
|
|
4314
|
+
stroke: "currentColor",
|
|
4315
|
+
strokeWidth: "4"
|
|
4316
|
+
}
|
|
4317
|
+
),
|
|
4318
|
+
/* @__PURE__ */ jsx11(
|
|
4319
|
+
"path",
|
|
4313
4320
|
{
|
|
4314
|
-
className:
|
|
4315
|
-
|
|
4321
|
+
className: "opacity-75",
|
|
4322
|
+
fill: "currentColor",
|
|
4323
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
4316
4324
|
}
|
|
4317
4325
|
)
|
|
4318
4326
|
]
|
|
4319
|
-
}
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
}
|
|
4323
|
-
)
|
|
4324
|
-
] }),
|
|
4325
|
-
activeTab === "builder" && /* @__PURE__ */ jsx11(
|
|
4326
|
-
FieldCards,
|
|
4327
|
-
{
|
|
4328
|
-
enabledTypes,
|
|
4329
|
-
disabledFieldTypes,
|
|
4330
|
-
onAddField: handleAddField
|
|
4327
|
+
}
|
|
4328
|
+
),
|
|
4329
|
+
"Saving\u2026"
|
|
4330
|
+
] }) : isCreating ? "Create" : "Save Changes"
|
|
4331
4331
|
}
|
|
4332
|
-
)
|
|
4333
|
-
|
|
4334
|
-
activeTab === "settings" && /* @__PURE__ */ jsx11("div", { className: "w-full", children: /* @__PURE__ */ jsx11(FormSettingsTab, { spamDefaults }) }),
|
|
4335
|
-
activeTab === "notifications" && /* @__PURE__ */ jsx11("div", { className: "w-full", children: /* @__PURE__ */ jsx11(FormNotificationsTab, { defaults: notificationDefaults }) }),
|
|
4336
|
-
saveError && // Full-strength destructive border so the error box boundary is perceivable over its tinted fill.
|
|
4337
|
-
/* @__PURE__ */ jsx11("div", { className: "p-3 text-sm text-destructive bg-destructive/10 border border-destructive rounded-none", children: saveError })
|
|
4338
|
-
] }) }) })
|
|
4332
|
+
)
|
|
4333
|
+
] })
|
|
4339
4334
|
] });
|
|
4340
4335
|
}
|
|
4341
4336
|
function FormBuilderView({
|