@btst/plugin-form-builder 0.0.0-stage → 1.0.0

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.
Files changed (213) hide show
  1. package/LICENSE.md +17 -0
  2. package/dist/api/getters.cjs +154 -0
  3. package/dist/api/getters.mjs +145 -0
  4. package/dist/api/index.cjs +25 -0
  5. package/dist/api/index.d.cts +119 -0
  6. package/dist/api/index.d.mts +119 -0
  7. package/dist/api/index.d.ts +119 -0
  8. package/dist/api/index.mjs +6 -0
  9. package/dist/api/lifecycle-migrations.cjs +15 -0
  10. package/dist/api/lifecycle-migrations.mjs +13 -0
  11. package/dist/api/operations.cjs +1093 -0
  12. package/dist/api/operations.mjs +1082 -0
  13. package/dist/api/plugin.cjs +201 -0
  14. package/dist/api/plugin.mjs +192 -0
  15. package/dist/api/query-key-defs.cjs +43 -0
  16. package/dist/api/query-key-defs.mjs +39 -0
  17. package/dist/client/components/forms/form-renderer.cjs +193 -0
  18. package/dist/client/components/forms/form-renderer.mjs +191 -0
  19. package/dist/client/components/index.cjs +29 -0
  20. package/dist/client/components/index.d.cts +97 -0
  21. package/dist/client/components/index.d.mts +97 -0
  22. package/dist/client/components/index.d.ts +97 -0
  23. package/dist/client/components/index.mjs +18 -0
  24. package/dist/client/components/loading/form-builder-skeleton.cjs +32 -0
  25. package/dist/client/components/loading/form-builder-skeleton.mjs +30 -0
  26. package/dist/client/components/loading/form-list-skeleton.cjs +21 -0
  27. package/dist/client/components/loading/form-list-skeleton.mjs +19 -0
  28. package/dist/client/components/loading/submissions-skeleton.cjs +34 -0
  29. package/dist/client/components/loading/submissions-skeleton.mjs +32 -0
  30. package/dist/client/components/pages/404-page.cjs +28 -0
  31. package/dist/client/components/pages/404-page.mjs +26 -0
  32. package/dist/client/components/pages/form-builder-page.cjs +77 -0
  33. package/dist/client/components/pages/form-builder-page.internal.cjs +217 -0
  34. package/dist/client/components/pages/form-builder-page.internal.mjs +215 -0
  35. package/dist/client/components/pages/form-builder-page.mjs +75 -0
  36. package/dist/client/components/pages/form-list-page.cjs +44 -0
  37. package/dist/client/components/pages/form-list-page.internal.cjs +282 -0
  38. package/dist/client/components/pages/form-list-page.internal.mjs +280 -0
  39. package/dist/client/components/pages/form-list-page.mjs +42 -0
  40. package/dist/client/components/pages/submissions-page.cjs +64 -0
  41. package/dist/client/components/pages/submissions-page.internal.cjs +255 -0
  42. package/dist/client/components/pages/submissions-page.internal.mjs +253 -0
  43. package/dist/client/components/pages/submissions-page.mjs +62 -0
  44. package/dist/client/components/shared/default-error.cjs +17 -0
  45. package/dist/client/components/shared/default-error.mjs +15 -0
  46. package/dist/client/components/shared/empty-state.cjs +16 -0
  47. package/dist/client/components/shared/empty-state.mjs +14 -0
  48. package/dist/client/components/shared/page-wrapper.cjs +29 -0
  49. package/dist/client/components/shared/page-wrapper.mjs +27 -0
  50. package/dist/client/components/shared/pagination.cjs +49 -0
  51. package/dist/client/components/shared/pagination.mjs +47 -0
  52. package/dist/client/constants.cjs +5 -0
  53. package/dist/client/constants.mjs +3 -0
  54. package/dist/client/hooks/form-builder-hooks.cjs +203 -0
  55. package/dist/client/hooks/form-builder-hooks.mjs +186 -0
  56. package/dist/client/hooks/form-builder-resource.cjs +13 -0
  57. package/dist/client/hooks/form-builder-resource.mjs +11 -0
  58. package/dist/client/hooks/index.cjs +22 -0
  59. package/dist/client/hooks/index.d.cts +378 -0
  60. package/dist/client/hooks/index.d.mts +378 -0
  61. package/dist/client/hooks/index.d.ts +378 -0
  62. package/dist/client/hooks/index.mjs +1 -0
  63. package/dist/client/index.cjs +13 -0
  64. package/dist/client/index.d.cts +410 -0
  65. package/dist/client/index.d.mts +410 -0
  66. package/dist/client/index.d.ts +410 -0
  67. package/dist/client/index.mjs +2 -0
  68. package/dist/client/plugin.cjs +311 -0
  69. package/dist/client/plugin.mjs +309 -0
  70. package/dist/client.css +3 -0
  71. package/dist/db.cjs +99 -0
  72. package/dist/db.mjs +97 -0
  73. package/dist/permissions.cjs +95 -0
  74. package/dist/permissions.d.cts +94 -0
  75. package/dist/permissions.d.mts +94 -0
  76. package/dist/permissions.d.ts +94 -0
  77. package/dist/permissions.mjs +93 -0
  78. package/dist/query-keys.cjs +140 -0
  79. package/dist/query-keys.d.cts +392 -0
  80. package/dist/query-keys.d.mts +392 -0
  81. package/dist/query-keys.d.ts +392 -0
  82. package/dist/query-keys.mjs +137 -0
  83. package/dist/schemas.cjs +91 -0
  84. package/dist/schemas.mjs +82 -0
  85. package/dist/shared/plugin-form-builder.BZYGyFgT.d.mts +351 -0
  86. package/dist/shared/plugin-form-builder.Bbl9NufB.d.cts +408 -0
  87. package/dist/shared/plugin-form-builder.CSP5HR2O.d.ts +408 -0
  88. package/dist/shared/plugin-form-builder.Cmk083dA.d.cts +351 -0
  89. package/dist/shared/plugin-form-builder.D258Qpb8.d.ts +351 -0
  90. package/dist/shared/plugin-form-builder.DWrQ3lRX.d.cts +118 -0
  91. package/dist/shared/plugin-form-builder.DWrQ3lRX.d.mts +118 -0
  92. package/dist/shared/plugin-form-builder.DWrQ3lRX.d.ts +118 -0
  93. package/dist/shared/plugin-form-builder.lp98rFNl.d.mts +408 -0
  94. package/dist/style.css +6 -0
  95. package/dist/types.cjs +2 -0
  96. package/dist/types.d.cts +6 -0
  97. package/dist/types.d.mts +6 -0
  98. package/dist/types.d.ts +6 -0
  99. package/dist/types.mjs +1 -0
  100. package/dist/ui/src/components/accordion.cjs +81 -0
  101. package/dist/ui/src/components/accordion.mjs +62 -0
  102. package/dist/ui/src/components/alert-dialog.cjs +157 -0
  103. package/dist/ui/src/components/alert-dialog.mjs +132 -0
  104. package/dist/ui/src/components/auto-form/common/label.cjs +18 -0
  105. package/dist/ui/src/components/auto-form/common/label.mjs +16 -0
  106. package/dist/ui/src/components/auto-form/common/tooltip.cjs +9 -0
  107. package/dist/ui/src/components/auto-form/common/tooltip.mjs +7 -0
  108. package/dist/ui/src/components/auto-form/config.cjs +40 -0
  109. package/dist/ui/src/components/auto-form/config.mjs +37 -0
  110. package/dist/ui/src/components/auto-form/dependencies.cjs +48 -0
  111. package/dist/ui/src/components/auto-form/dependencies.mjs +46 -0
  112. package/dist/ui/src/components/auto-form/fields/array.cjs +266 -0
  113. package/dist/ui/src/components/auto-form/fields/array.mjs +264 -0
  114. package/dist/ui/src/components/auto-form/fields/checkbox.cjs +38 -0
  115. package/dist/ui/src/components/auto-form/fields/checkbox.mjs +36 -0
  116. package/dist/ui/src/components/auto-form/fields/date.cjs +67 -0
  117. package/dist/ui/src/components/auto-form/fields/date.mjs +65 -0
  118. package/dist/ui/src/components/auto-form/fields/enum.cjs +73 -0
  119. package/dist/ui/src/components/auto-form/fields/enum.mjs +71 -0
  120. package/dist/ui/src/components/auto-form/fields/input.cjs +32 -0
  121. package/dist/ui/src/components/auto-form/fields/input.mjs +30 -0
  122. package/dist/ui/src/components/auto-form/fields/number.cjs +31 -0
  123. package/dist/ui/src/components/auto-form/fields/number.mjs +29 -0
  124. package/dist/ui/src/components/auto-form/fields/object.cjs +233 -0
  125. package/dist/ui/src/components/auto-form/fields/object.mjs +217 -0
  126. package/dist/ui/src/components/auto-form/fields/radio-group.cjs +67 -0
  127. package/dist/ui/src/components/auto-form/fields/radio-group.mjs +65 -0
  128. package/dist/ui/src/components/auto-form/fields/switch.cjs +38 -0
  129. package/dist/ui/src/components/auto-form/fields/switch.mjs +36 -0
  130. package/dist/ui/src/components/auto-form/fields/textarea.cjs +31 -0
  131. package/dist/ui/src/components/auto-form/fields/textarea.mjs +29 -0
  132. package/dist/ui/src/components/auto-form/helpers.cjs +270 -0
  133. package/dist/ui/src/components/auto-form/helpers.mjs +259 -0
  134. package/dist/ui/src/components/auto-form/index.cjs +92 -0
  135. package/dist/ui/src/components/auto-form/index.mjs +86 -0
  136. package/dist/ui/src/components/auto-form/stepped-auto-form.cjs +374 -0
  137. package/dist/ui/src/components/auto-form/stepped-auto-form.mjs +368 -0
  138. package/dist/ui/src/components/auto-form/types.cjs +11 -0
  139. package/dist/ui/src/components/auto-form/types.mjs +9 -0
  140. package/dist/ui/src/components/button.cjs +56 -0
  141. package/dist/ui/src/components/button.mjs +53 -0
  142. package/dist/ui/src/components/calendar.cjs +207 -0
  143. package/dist/ui/src/components/calendar.mjs +190 -0
  144. package/dist/ui/src/components/checkbox.cjs +48 -0
  145. package/dist/ui/src/components/checkbox.mjs +32 -0
  146. package/dist/ui/src/components/date-picker.cjs +41 -0
  147. package/dist/ui/src/components/date-picker.mjs +39 -0
  148. package/dist/ui/src/components/dialog.cjs +141 -0
  149. package/dist/ui/src/components/dialog.mjs +118 -0
  150. package/dist/ui/src/components/dropdown-menu.cjs +81 -0
  151. package/dist/ui/src/components/dropdown-menu.mjs +62 -0
  152. package/dist/ui/src/components/form-builder/canvas.cjs +111 -0
  153. package/dist/ui/src/components/form-builder/canvas.mjs +109 -0
  154. package/dist/ui/src/components/form-builder/components/index.cjs +571 -0
  155. package/dist/ui/src/components/form-builder/components/index.mjs +554 -0
  156. package/dist/ui/src/components/form-builder/edit-field-dialog.cjs +131 -0
  157. package/dist/ui/src/components/form-builder/edit-field-dialog.mjs +129 -0
  158. package/dist/ui/src/components/form-builder/form-preview.cjs +73 -0
  159. package/dist/ui/src/components/form-builder/form-preview.mjs +71 -0
  160. package/dist/ui/src/components/form-builder/index.cjs +350 -0
  161. package/dist/ui/src/components/form-builder/index.mjs +344 -0
  162. package/dist/ui/src/components/form-builder/nested-field-editor-dialog.cjs +263 -0
  163. package/dist/ui/src/components/form-builder/nested-field-editor-dialog.mjs +261 -0
  164. package/dist/ui/src/components/form-builder/palette.cjs +52 -0
  165. package/dist/ui/src/components/form-builder/palette.mjs +49 -0
  166. package/dist/ui/src/components/form-builder/schema-utils.cjs +128 -0
  167. package/dist/ui/src/components/form-builder/schema-utils.mjs +122 -0
  168. package/dist/ui/src/components/form-builder/sortable-field.cjs +151 -0
  169. package/dist/ui/src/components/form-builder/sortable-field.mjs +148 -0
  170. package/dist/ui/src/components/form-builder/step-tabs.cjs +180 -0
  171. package/dist/ui/src/components/form-builder/step-tabs.mjs +178 -0
  172. package/dist/ui/src/components/form-builder/types.cjs +7 -0
  173. package/dist/ui/src/components/form-builder/types.mjs +5 -0
  174. package/dist/ui/src/components/form-builder/validation-schemas.cjs +67 -0
  175. package/dist/ui/src/components/form-builder/validation-schemas.mjs +56 -0
  176. package/dist/ui/src/components/form.cjs +120 -0
  177. package/dist/ui/src/components/form.mjs +98 -0
  178. package/dist/ui/src/components/input.cjs +23 -0
  179. package/dist/ui/src/components/input.mjs +21 -0
  180. package/dist/ui/src/components/label.cjs +39 -0
  181. package/dist/ui/src/components/label.mjs +23 -0
  182. package/dist/ui/src/components/page-layout.cjs +25 -0
  183. package/dist/ui/src/components/page-layout.mjs +23 -0
  184. package/dist/ui/src/components/page-wrapper.cjs +20 -0
  185. package/dist/ui/src/components/page-wrapper.mjs +18 -0
  186. package/dist/ui/src/components/popover.cjs +60 -0
  187. package/dist/ui/src/components/popover.mjs +42 -0
  188. package/dist/ui/src/components/radio-group.cjs +62 -0
  189. package/dist/ui/src/components/radio-group.mjs +45 -0
  190. package/dist/ui/src/components/select.cjs +161 -0
  191. package/dist/ui/src/components/select.mjs +139 -0
  192. package/dist/ui/src/components/separator.cjs +43 -0
  193. package/dist/ui/src/components/separator.mjs +27 -0
  194. package/dist/ui/src/components/skeleton.cjs +17 -0
  195. package/dist/ui/src/components/skeleton.mjs +15 -0
  196. package/dist/ui/src/components/stack-attribution.cjs +24 -0
  197. package/dist/ui/src/components/stack-attribution.mjs +22 -0
  198. package/dist/ui/src/components/switch.cjs +48 -0
  199. package/dist/ui/src/components/switch.mjs +32 -0
  200. package/dist/ui/src/components/table.cjs +89 -0
  201. package/dist/ui/src/components/table.mjs +82 -0
  202. package/dist/ui/src/components/tabs.cjs +84 -0
  203. package/dist/ui/src/components/tabs.mjs +65 -0
  204. package/dist/ui/src/components/textarea.cjs +20 -0
  205. package/dist/ui/src/components/textarea.mjs +18 -0
  206. package/dist/ui/src/lib/schema-converter.cjs +133 -0
  207. package/dist/ui/src/lib/schema-converter.mjs +127 -0
  208. package/dist/ui/src/lib/utils.cjs +10 -0
  209. package/dist/ui/src/lib/utils.mjs +8 -0
  210. package/dist/utils.cjs +41 -0
  211. package/dist/utils.mjs +32 -0
  212. package/package.json +175 -3
  213. package/README.md +0 -3
@@ -0,0 +1,253 @@
1
+ 'use client';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { useState, useEffect } from 'react';
4
+ import { useTranslate, useNotify, usePluginOverrides, useIdentity, usePluginSiteNavigation, PermissionAccess } from '@btst/stack/context';
5
+ import { Button } from '../../../ui/src/components/button.mjs';
6
+ import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from '../../../ui/src/components/table.mjs';
7
+ import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '../../../ui/src/components/alert-dialog.mjs';
8
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '../../../ui/src/components/dialog.mjs';
9
+ import { ArrowLeft, Eye, Trash2 } from 'lucide-react';
10
+ import { PageWrapper } from '../shared/page-wrapper.mjs';
11
+ import { EmptyState } from '../shared/empty-state.mjs';
12
+ import { Pagination } from '../shared/pagination.mjs';
13
+ import { formBuilderPermissions } from '../../../permissions.mjs';
14
+ import { FORM_BUILDER_PLUGIN_ID } from '../../constants.mjs';
15
+ import { cn } from '../../../utils.mjs';
16
+ import { useSuspenseSubmissions, useDeleteSubmission, useSubmission } from '../../hooks/form-builder-hooks.mjs';
17
+
18
+ function SubmissionsPage({ formId }) {
19
+ const t = useTranslate();
20
+ const notify = useNotify();
21
+ const { localization, classNames } = usePluginOverrides(FORM_BUILDER_PLUGIN_ID);
22
+ const { identity } = useIdentity();
23
+ const { Link: LinkComponent, resolve } = usePluginSiteNavigation(
24
+ FORM_BUILDER_PLUGIN_ID
25
+ );
26
+ const { form, submissions, total, hasMore, isLoadingMore, loadMore } = useSuspenseSubmissions(formId);
27
+ const deleteMutation = useDeleteSubmission(formId);
28
+ const [deleteId, setDeleteId] = useState(null);
29
+ const [viewSubmissionId, setViewSubmissionId] = useState(null);
30
+ const {
31
+ submission: viewSubmission,
32
+ isLoading: isViewLoading,
33
+ error: viewError
34
+ } = useSubmission(formId, viewSubmissionId ?? void 0);
35
+ useEffect(() => {
36
+ setViewSubmissionId(null);
37
+ }, [identity]);
38
+ const handleDelete = async () => {
39
+ if (!deleteId) return;
40
+ try {
41
+ await deleteMutation.mutateAsync(deleteId);
42
+ } catch {
43
+ notify.error(
44
+ localization?.FORM_BUILDER_TOAST_ERROR ?? t("formBuilder.toasts.error", "An error occurred. Please try again.")
45
+ );
46
+ return;
47
+ }
48
+ notify.success(
49
+ localization?.FORM_BUILDER_TOAST_SUBMISSION_DELETED ?? t(
50
+ "formBuilder.toasts.submissionDeleted",
51
+ "Submission deleted successfully"
52
+ )
53
+ );
54
+ setDeleteId(null);
55
+ };
56
+ return /* @__PURE__ */ jsxs(PageWrapper, { testId: "submissions-page", children: [
57
+ /* @__PURE__ */ jsxs("div", { className: "w-full max-w-5xl space-y-6", children: [
58
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
59
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: resolve("forms").href, children: /* @__PURE__ */ jsx(ArrowLeft, { className: "h-4 w-4" }) }) }),
60
+ /* @__PURE__ */ jsxs("div", { children: [
61
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold", children: form?.name || (localization?.FORM_BUILDER_SUBMISSIONS_TITLE ?? t("formBuilder.submissions.title", "Submissions")) }),
62
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_SUBTITLE ?? t("formBuilder.submissions.subtitle", "View form submissions") })
63
+ ] })
64
+ ] }),
65
+ submissions.length === 0 ? /* @__PURE__ */ jsx(
66
+ EmptyState,
67
+ {
68
+ title: localization?.FORM_BUILDER_SUBMISSIONS_EMPTY ?? t("formBuilder.submissions.empty", "No submissions yet"),
69
+ description: localization?.FORM_BUILDER_SUBMISSIONS_EMPTY_DESCRIPTION ?? t(
70
+ "formBuilder.submissions.emptyDescription",
71
+ "Submissions will appear here when users submit this form."
72
+ )
73
+ }
74
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
75
+ /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ className: cn("rounded-lg border", classNames?.table),
79
+ "data-testid": "form-builder-submissions-table",
80
+ children: /* @__PURE__ */ jsxs(Table, { children: [
81
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
82
+ /* @__PURE__ */ jsx(TableHead, { className: "w-24", children: localization?.FORM_BUILDER_SUBMISSIONS_COLUMN_ID ?? t("formBuilder.submissions.columnId", "ID") }),
83
+ /* @__PURE__ */ jsx(TableHead, { children: localization?.FORM_BUILDER_SUBMISSIONS_COLUMN_SUBMITTED_AT ?? t(
84
+ "formBuilder.submissions.columnSubmittedAt",
85
+ "Submitted"
86
+ ) }),
87
+ /* @__PURE__ */ jsx(TableHead, { className: "w-24", children: localization?.FORM_BUILDER_SUBMISSIONS_COLUMN_ACTIONS ?? t("formBuilder.submissions.columnActions", "Actions") })
88
+ ] }) }),
89
+ /* @__PURE__ */ jsx(TableBody, { children: submissions.map((sub) => /* @__PURE__ */ jsxs(TableRow, { className: classNames?.tableRow, children: [
90
+ /* @__PURE__ */ jsxs(TableCell, { className: "font-mono text-xs", children: [
91
+ sub.id.slice(0, 8),
92
+ "..."
93
+ ] }),
94
+ /* @__PURE__ */ jsx(TableCell, { className: "text-muted-foreground", children: new Date(sub.submittedAt).toLocaleString() }),
95
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
96
+ /* @__PURE__ */ jsx(
97
+ PermissionAccess,
98
+ {
99
+ permission: formBuilderPermissions.submission.read({
100
+ scope: "record",
101
+ formId,
102
+ submissionId: sub.id,
103
+ exists: true,
104
+ ...form?.createdBy ? { ownerId: form.createdBy } : {},
105
+ ...sub.submittedBy ? { submittedBy: sub.submittedBy } : {}
106
+ }),
107
+ children: /* @__PURE__ */ jsxs(
108
+ Button,
109
+ {
110
+ variant: "ghost",
111
+ size: "icon",
112
+ onClick: () => setViewSubmissionId(sub.id),
113
+ children: [
114
+ /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4" }),
115
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: localization?.FORM_BUILDER_SUBMISSIONS_ACTION_VIEW ?? t(
116
+ "formBuilder.submissions.actionView",
117
+ "View"
118
+ ) })
119
+ ]
120
+ }
121
+ )
122
+ }
123
+ ),
124
+ /* @__PURE__ */ jsx(
125
+ PermissionAccess,
126
+ {
127
+ permission: formBuilderPermissions.submission.delete(
128
+ {
129
+ formId,
130
+ submissionId: sub.id,
131
+ exists: true,
132
+ ...form?.createdBy ? { ownerId: form.createdBy } : {},
133
+ ...sub.submittedBy ? { submittedBy: sub.submittedBy } : {}
134
+ }
135
+ ),
136
+ children: /* @__PURE__ */ jsxs(
137
+ Button,
138
+ {
139
+ variant: "ghost",
140
+ size: "icon",
141
+ className: "text-destructive",
142
+ onClick: () => setDeleteId(sub.id),
143
+ children: [
144
+ /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" }),
145
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: localization?.FORM_BUILDER_SUBMISSIONS_ACTION_DELETE ?? t(
146
+ "formBuilder.submissions.actionDelete",
147
+ "Delete"
148
+ ) })
149
+ ]
150
+ }
151
+ )
152
+ }
153
+ )
154
+ ] }) })
155
+ ] }, sub.id)) })
156
+ ] })
157
+ }
158
+ ),
159
+ /* @__PURE__ */ jsx(
160
+ Pagination,
161
+ {
162
+ total,
163
+ showing: submissions.length,
164
+ hasMore,
165
+ isLoadingMore,
166
+ onLoadMore: loadMore,
167
+ className: classNames?.pagination,
168
+ labels: {
169
+ showing: localization?.FORM_BUILDER_LIST_PAGINATION_SHOWING ?? t(
170
+ "formBuilder.list.paginationShowing",
171
+ "Showing {count} of {total}"
172
+ ),
173
+ next: localization?.FORM_BUILDER_LIST_PAGINATION_NEXT ?? t("formBuilder.list.paginationNext", "Load More"),
174
+ loading: localization?.FORM_BUILDER_STATUS_LOADING ?? t("formBuilder.common.statusLoading", "Loading...")
175
+ }
176
+ }
177
+ )
178
+ ] })
179
+ ] }),
180
+ /* @__PURE__ */ jsx(
181
+ Dialog,
182
+ {
183
+ open: !!viewSubmissionId,
184
+ onOpenChange: (open) => {
185
+ if (!open) setViewSubmissionId(null);
186
+ },
187
+ children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-2xl max-h-[80vh] overflow-auto", children: [
188
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
189
+ /* @__PURE__ */ jsx(DialogTitle, { children: localization?.FORM_BUILDER_SUBMISSIONS_DETAILS_TITLE ?? t("formBuilder.submissions.detailsTitle", "Submission Details") }),
190
+ /* @__PURE__ */ jsx(DialogDescription, { className: "sr-only", children: t(
191
+ "formBuilder.submissions.detailsDescription",
192
+ "Submitted form data and request metadata."
193
+ ) })
194
+ ] }),
195
+ isViewLoading && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: localization?.FORM_BUILDER_STATUS_LOADING ?? t("formBuilder.common.statusLoading", "Loading...") }),
196
+ viewError && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-destructive", children: localization?.FORM_BUILDER_TOAST_ERROR ?? t(
197
+ "formBuilder.toasts.error",
198
+ "An error occurred. Please try again."
199
+ ) }),
200
+ !isViewLoading && !viewError && viewSubmission && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
201
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4 text-sm", children: [
202
+ /* @__PURE__ */ jsxs("div", { children: [
203
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_ID ?? t("formBuilder.submissions.fieldId", "ID:") }),
204
+ /* @__PURE__ */ jsx("p", { className: "font-mono truncate", children: viewSubmission.id })
205
+ ] }),
206
+ /* @__PURE__ */ jsxs("div", { children: [
207
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_SUBMITTED ?? t("formBuilder.submissions.fieldSubmitted", "Submitted:") }),
208
+ /* @__PURE__ */ jsx("p", { className: "truncate", children: new Date(viewSubmission.submittedAt).toLocaleString() })
209
+ ] }),
210
+ /* @__PURE__ */ jsxs("div", { children: [
211
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_IP ?? t("formBuilder.submissions.fieldIp", "IP Address:") }),
212
+ /* @__PURE__ */ jsx("p", { className: "font-mono truncate", children: viewSubmission.ipAddress || "-" })
213
+ ] }),
214
+ /* @__PURE__ */ jsxs("div", { children: [
215
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_USER_AGENT ?? t(
216
+ "formBuilder.submissions.fieldUserAgent",
217
+ "User Agent:"
218
+ ) }),
219
+ /* @__PURE__ */ jsx("p", { className: "text-xs truncate", children: viewSubmission.userAgent || "-" })
220
+ ] })
221
+ ] }),
222
+ /* @__PURE__ */ jsxs("div", { children: [
223
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_DATA ?? t("formBuilder.submissions.fieldData", "Data:") }),
224
+ /* @__PURE__ */ jsx("pre", { className: "mt-2 p-4 bg-muted rounded-lg text-sm overflow-auto", children: JSON.stringify(viewSubmission.parsedData, null, 2) })
225
+ ] })
226
+ ] })
227
+ ] })
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx(AlertDialog, { open: !!deleteId, onOpenChange: () => setDeleteId(null), children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
231
+ /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
232
+ /* @__PURE__ */ jsx(AlertDialogTitle, { children: localization?.FORM_BUILDER_SUBMISSIONS_DELETE_TITLE ?? t("formBuilder.submissions.deleteTitle", "Delete Submission") }),
233
+ /* @__PURE__ */ jsx(AlertDialogDescription, { children: localization?.FORM_BUILDER_SUBMISSIONS_DELETE_CONFIRM ?? t(
234
+ "formBuilder.submissions.deleteConfirm",
235
+ "Are you sure you want to delete this submission?"
236
+ ) })
237
+ ] }),
238
+ /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
239
+ /* @__PURE__ */ jsx(AlertDialogCancel, { children: localization?.FORM_BUILDER_BUTTON_CANCEL ?? t("formBuilder.common.buttonCancel", "Cancel") }),
240
+ /* @__PURE__ */ jsx(
241
+ AlertDialogAction,
242
+ {
243
+ onClick: handleDelete,
244
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
245
+ children: deleteMutation.isPending ? localization?.FORM_BUILDER_STATUS_DELETING ?? t("formBuilder.common.statusDeleting", "Deleting...") : localization?.FORM_BUILDER_BUTTON_DELETE ?? t("formBuilder.common.buttonDelete", "Delete")
246
+ }
247
+ )
248
+ ] })
249
+ ] }) })
250
+ ] });
251
+ }
252
+
253
+ export { SubmissionsPage };
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { lazy } from 'react';
4
+ import { usePluginOverrides } from '@btst/stack/context';
5
+ import { ComposedRoute, PermissionRouteAccess } from '@btst/stack/client/components';
6
+ import { DefaultError } from '../shared/default-error.mjs';
7
+ import { SubmissionsSkeleton } from '../loading/submissions-skeleton.mjs';
8
+ import { NotFoundPage } from './404-page.mjs';
9
+ import { formBuilderPermissions } from '../../../permissions.mjs';
10
+ import { FORM_BUILDER_PLUGIN_ID } from '../../constants.mjs';
11
+ import { useSuspenseSubmissions } from '../../hooks/form-builder-hooks.mjs';
12
+
13
+ const SubmissionsPage = lazy(
14
+ () => import('./submissions-page.internal.mjs').then((m) => ({
15
+ default: m.SubmissionsPage
16
+ }))
17
+ );
18
+ function SubmissionsPageComponent({ formId }) {
19
+ const { onRouteError } = usePluginOverrides(
20
+ FORM_BUILDER_PLUGIN_ID
21
+ );
22
+ const path = `/forms/${formId}/submissions`;
23
+ return /* @__PURE__ */ jsx(
24
+ ComposedRoute,
25
+ {
26
+ path,
27
+ PageComponent: AuthorizedSubmissionsPage,
28
+ ErrorComponent: DefaultError,
29
+ LoadingComponent: SubmissionsSkeleton,
30
+ NotFoundComponent: NotFoundPage,
31
+ props: { formId },
32
+ onError: (error) => {
33
+ if (onRouteError) {
34
+ onRouteError("submissions", error, {
35
+ path,
36
+ params: { formId },
37
+ isSSR: typeof window === "undefined"
38
+ });
39
+ }
40
+ }
41
+ }
42
+ );
43
+ }
44
+ function AuthorizedSubmissionsPage({ formId }) {
45
+ const { form } = useSuspenseSubmissions(formId);
46
+ if (!form) return /* @__PURE__ */ jsx(NotFoundPage, {});
47
+ return /* @__PURE__ */ jsx(
48
+ PermissionRouteAccess,
49
+ {
50
+ permission: formBuilderPermissions.submission.read({
51
+ scope: "collection",
52
+ formId,
53
+ formExists: form !== null,
54
+ ...form?.createdBy ? { ownerId: form.createdBy } : {}
55
+ }),
56
+ LoadingComponent: SubmissionsSkeleton,
57
+ children: /* @__PURE__ */ jsx(SubmissionsPage, { formId })
58
+ }
59
+ );
60
+ }
61
+
62
+ export { SubmissionsPageComponent };
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const lucideReact = require('lucide-react');
6
+ const button = require('../../../ui/src/components/button.cjs');
7
+
8
+ function DefaultError({ error, resetErrorBoundary }) {
9
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
10
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-full bg-destructive/10 p-4 mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "h-8 w-8 text-destructive" }) }),
11
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-medium text-foreground mb-2", children: "Something went wrong" }),
12
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-4 max-w-sm", children: (error instanceof Error ? error.message : void 0) || "An unexpected error occurred" }),
13
+ resetErrorBoundary && /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", onClick: resetErrorBoundary, children: "Try again" })
14
+ ] });
15
+ }
16
+
17
+ exports.DefaultError = DefaultError;
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { AlertCircle } from 'lucide-react';
4
+ import { Button } from '../../../ui/src/components/button.mjs';
5
+
6
+ function DefaultError({ error, resetErrorBoundary }) {
7
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
8
+ /* @__PURE__ */ jsx("div", { className: "rounded-full bg-destructive/10 p-4 mb-4", children: /* @__PURE__ */ jsx(AlertCircle, { className: "h-8 w-8 text-destructive" }) }),
9
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-foreground mb-2", children: "Something went wrong" }),
10
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-4 max-w-sm", children: (error instanceof Error ? error.message : void 0) || "An unexpected error occurred" }),
11
+ resetErrorBoundary && /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: resetErrorBoundary, children: "Try again" })
12
+ ] });
13
+ }
14
+
15
+ export { DefaultError };
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const lucideReact = require('lucide-react');
6
+
7
+ function EmptyState({ title, description, action }) {
8
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
9
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-full bg-muted p-4 mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Inbox, { className: "h-8 w-8 text-muted-foreground" }) }),
10
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-medium text-foreground mb-2", children: title }),
11
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-4 max-w-sm", children: description }),
12
+ action
13
+ ] });
14
+ }
15
+
16
+ exports.EmptyState = EmptyState;
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { Inbox } from 'lucide-react';
4
+
5
+ function EmptyState({ title, description, action }) {
6
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
7
+ /* @__PURE__ */ jsx("div", { className: "rounded-full bg-muted p-4 mb-4", children: /* @__PURE__ */ jsx(Inbox, { className: "h-8 w-8 text-muted-foreground" }) }),
8
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-foreground mb-2", children: title }),
9
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-4 max-w-sm", children: description }),
10
+ action
11
+ ] });
12
+ }
13
+
14
+ export { EmptyState };
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const context = require('@btst/stack/context');
6
+ const pageWrapper = require('../../../ui/src/components/page-wrapper.cjs');
7
+ const constants = require('../../constants.cjs');
8
+ const utils = require('../../../utils.cjs');
9
+
10
+ function PageWrapper({
11
+ children,
12
+ className,
13
+ testId
14
+ }) {
15
+ const { showAttribution, classNames } = context.usePluginOverrides(constants.FORM_BUILDER_PLUGIN_ID, {
16
+ showAttribution: true
17
+ });
18
+ return /* @__PURE__ */ jsxRuntime.jsx(
19
+ pageWrapper.PageWrapper,
20
+ {
21
+ className: utils.cn(className, classNames?.container),
22
+ testId,
23
+ showAttribution,
24
+ children
25
+ }
26
+ );
27
+ }
28
+
29
+ exports.PageWrapper = PageWrapper;
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { usePluginOverrides } from '@btst/stack/context';
4
+ import { PageWrapper as PageWrapper$1 } from '../../../ui/src/components/page-wrapper.mjs';
5
+ import { FORM_BUILDER_PLUGIN_ID } from '../../constants.mjs';
6
+ import { cn } from '../../../utils.mjs';
7
+
8
+ function PageWrapper({
9
+ children,
10
+ className,
11
+ testId
12
+ }) {
13
+ const { showAttribution, classNames } = usePluginOverrides(FORM_BUILDER_PLUGIN_ID, {
14
+ showAttribution: true
15
+ });
16
+ return /* @__PURE__ */ jsx(
17
+ PageWrapper$1,
18
+ {
19
+ className: cn(className, classNames?.container),
20
+ testId,
21
+ showAttribution,
22
+ children
23
+ }
24
+ );
25
+ }
26
+
27
+ export { PageWrapper };
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const button = require('../../../ui/src/components/button.cjs');
6
+ const lucideReact = require('lucide-react');
7
+ const utils = require('../../../utils.cjs');
8
+
9
+ function Pagination({
10
+ total,
11
+ showing,
12
+ hasMore,
13
+ isLoadingMore,
14
+ onLoadMore,
15
+ className,
16
+ labels = {}
17
+ }) {
18
+ const {
19
+ showing: showingLabel = "Showing {count} of {total}",
20
+ next = "Load More",
21
+ loading = "Loading..."
22
+ } = labels;
23
+ const showingText = showingLabel.replace("{count}", String(showing)).replace("{total}", String(total));
24
+ return /* @__PURE__ */ jsxRuntime.jsxs(
25
+ "div",
26
+ {
27
+ className: utils.cn("flex items-center justify-between py-4", className),
28
+ "data-testid": "form-builder-pagination",
29
+ children: [
30
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: showingText }),
31
+ hasMore && /* @__PURE__ */ jsxRuntime.jsxs(
32
+ button.Button,
33
+ {
34
+ variant: "outline",
35
+ size: "sm",
36
+ onClick: onLoadMore,
37
+ disabled: isLoadingMore,
38
+ children: [
39
+ isLoadingMore ? loading : next,
40
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "ml-2 h-4 w-4" })
41
+ ]
42
+ }
43
+ )
44
+ ]
45
+ }
46
+ );
47
+ }
48
+
49
+ exports.Pagination = Pagination;
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { Button } from '../../../ui/src/components/button.mjs';
4
+ import { ChevronRight } from 'lucide-react';
5
+ import { cn } from '../../../utils.mjs';
6
+
7
+ function Pagination({
8
+ total,
9
+ showing,
10
+ hasMore,
11
+ isLoadingMore,
12
+ onLoadMore,
13
+ className,
14
+ labels = {}
15
+ }) {
16
+ const {
17
+ showing: showingLabel = "Showing {count} of {total}",
18
+ next = "Load More",
19
+ loading = "Loading..."
20
+ } = labels;
21
+ const showingText = showingLabel.replace("{count}", String(showing)).replace("{total}", String(total));
22
+ return /* @__PURE__ */ jsxs(
23
+ "div",
24
+ {
25
+ className: cn("flex items-center justify-between py-4", className),
26
+ "data-testid": "form-builder-pagination",
27
+ children: [
28
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: showingText }),
29
+ hasMore && /* @__PURE__ */ jsxs(
30
+ Button,
31
+ {
32
+ variant: "outline",
33
+ size: "sm",
34
+ onClick: onLoadMore,
35
+ disabled: isLoadingMore,
36
+ children: [
37
+ isLoadingMore ? loading : next,
38
+ /* @__PURE__ */ jsx(ChevronRight, { className: "ml-2 h-4 w-4" })
39
+ ]
40
+ }
41
+ )
42
+ ]
43
+ }
44
+ );
45
+ }
46
+
47
+ export { Pagination };
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const FORM_BUILDER_PLUGIN_ID = "formBuilder";
4
+
5
+ exports.FORM_BUILDER_PLUGIN_ID = FORM_BUILDER_PLUGIN_ID;
@@ -0,0 +1,3 @@
1
+ const FORM_BUILDER_PLUGIN_ID = "formBuilder";
2
+
3
+ export { FORM_BUILDER_PLUGIN_ID };