@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,280 @@
1
+ 'use client';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { useState, useRef, useEffect } from 'react';
4
+ import { useTranslate, useNotify, usePluginOverrides, usePluginSiteNavigation, PermissionAccess } from '@btst/stack/context';
5
+ import { useListState } from '@btst/stack/client/hooks';
6
+ import { Button } from '../../../ui/src/components/button.mjs';
7
+ import { Input } from '../../../ui/src/components/input.mjs';
8
+ import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from '../../../ui/src/components/table.mjs';
9
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '../../../ui/src/components/dropdown-menu.mjs';
10
+ import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '../../../ui/src/components/alert-dialog.mjs';
11
+ import { Plus, Search, Loader2, MoreHorizontal, Pencil, FileText, Trash2 } from 'lucide-react';
12
+ import { PageWrapper } from '../shared/page-wrapper.mjs';
13
+ import { EmptyState } from '../shared/empty-state.mjs';
14
+ import { Pagination } from '../shared/pagination.mjs';
15
+ import { formBuilderPermissions } from '../../../permissions.mjs';
16
+ import { FORM_BUILDER_PLUGIN_ID } from '../../constants.mjs';
17
+ import { cn } from '../../../utils.mjs';
18
+ import { useSuspenseForms, useForms, useDeleteForm } from '../../hooks/form-builder-hooks.mjs';
19
+
20
+ const LIST_STATE_SCHEMA = {
21
+ q: { type: "string", default: "", history: "replace" }
22
+ };
23
+ const SEARCH_DEBOUNCE_MS = 300;
24
+ function FormListPage() {
25
+ const t = useTranslate();
26
+ const notify = useNotify();
27
+ const { localization, classNames } = usePluginOverrides(FORM_BUILDER_PLUGIN_ID);
28
+ const { Link, navigate, resolve } = usePluginSiteNavigation(
29
+ FORM_BUILDER_PLUGIN_ID
30
+ );
31
+ const [{ q: search }, setListState] = useListState(
32
+ "form-builder-forms",
33
+ LIST_STATE_SCHEMA
34
+ );
35
+ const [searchInput, setSearchInput] = useState(search);
36
+ const lastSyncedSearch = useRef(search);
37
+ useEffect(() => {
38
+ if (search !== lastSyncedSearch.current) {
39
+ lastSyncedSearch.current = search;
40
+ setSearchInput(search);
41
+ }
42
+ }, [search]);
43
+ useEffect(() => {
44
+ if (searchInput === search) return;
45
+ const timeout = setTimeout(() => {
46
+ lastSyncedSearch.current = searchInput;
47
+ setListState({ q: searchInput });
48
+ }, SEARCH_DEBOUNCE_MS);
49
+ return () => clearTimeout(timeout);
50
+ }, [searchInput, search, setListState]);
51
+ const hasSearch = search.trim().length > 0;
52
+ const defaultList = useSuspenseForms();
53
+ const searchedList = useForms({ search, enabled: hasSearch });
54
+ const activeList = hasSearch ? searchedList : defaultList;
55
+ const { forms, total, hasMore, isLoadingMore, loadMore } = activeList;
56
+ const isSearchLoading = hasSearch && searchedList.isLoading;
57
+ const deleteMutation = useDeleteForm();
58
+ const [deleteId, setDeleteId] = useState(null);
59
+ const LinkComponent = Link || "a";
60
+ const handleDelete = async () => {
61
+ if (!deleteId) return;
62
+ try {
63
+ await deleteMutation.mutateAsync(deleteId);
64
+ } catch {
65
+ notify.error(
66
+ localization?.FORM_BUILDER_TOAST_ERROR ?? t("formBuilder.toasts.error", "An error occurred. Please try again.")
67
+ );
68
+ return;
69
+ }
70
+ notify.success(
71
+ localization?.FORM_BUILDER_TOAST_DELETE_SUCCESS ?? t("formBuilder.toasts.deleteSuccess", "Form deleted successfully")
72
+ );
73
+ setDeleteId(null);
74
+ };
75
+ const getStatusBadge = (status) => {
76
+ const colors = {
77
+ active: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
78
+ inactive: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200",
79
+ archived: "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200"
80
+ };
81
+ return /* @__PURE__ */ jsx(
82
+ "span",
83
+ {
84
+ className: `px-2 py-1 rounded-full text-xs font-medium ${colors[status] || colors.inactive}`,
85
+ children: status
86
+ }
87
+ );
88
+ };
89
+ const newFormButton = /* @__PURE__ */ jsx(PermissionAccess, { permission: formBuilderPermissions.form.create(), children: /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsxs(LinkComponent, { href: resolve("forms", "new").href, children: [
90
+ /* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4" }),
91
+ localization?.FORM_BUILDER_BUTTON_NEW_FORM ?? t("formBuilder.common.buttonNewForm", "New Form")
92
+ ] }) }) });
93
+ return /* @__PURE__ */ jsxs(PageWrapper, { testId: "form-list-page", children: [
94
+ /* @__PURE__ */ jsxs("div", { className: "w-full max-w-5xl space-y-6", children: [
95
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
96
+ /* @__PURE__ */ jsxs("div", { children: [
97
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold", children: localization?.FORM_BUILDER_LIST_TITLE ?? t("formBuilder.list.title", "Forms") }),
98
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_LIST_SUBTITLE ?? t("formBuilder.list.subtitle", "Manage your forms") })
99
+ ] }),
100
+ newFormButton
101
+ ] }),
102
+ /* @__PURE__ */ jsxs("div", { className: "relative max-w-sm", children: [
103
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
104
+ /* @__PURE__ */ jsx(
105
+ Input,
106
+ {
107
+ "data-testid": "form-builder-list-search",
108
+ value: searchInput,
109
+ onChange: (e) => setSearchInput(e.target.value),
110
+ placeholder: localization?.FORM_BUILDER_LIST_SEARCH_PLACEHOLDER ?? t("formBuilder.list.searchPlaceholder", "Search forms..."),
111
+ className: "pl-9"
112
+ }
113
+ ),
114
+ isSearchLoading && /* @__PURE__ */ jsx(Loader2, { className: "absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-muted-foreground" })
115
+ ] }),
116
+ forms.length === 0 ? isSearchLoading ? null : hasSearch ? /* @__PURE__ */ jsx(
117
+ EmptyState,
118
+ {
119
+ title: localization?.FORM_BUILDER_LIST_SEARCH_EMPTY ?? t("formBuilder.list.searchEmpty", "No forms match your search"),
120
+ description: localization?.FORM_BUILDER_LIST_SEARCH_EMPTY_DESCRIPTION ?? t(
121
+ "formBuilder.list.searchEmptyDescription",
122
+ "Try a different search term."
123
+ )
124
+ }
125
+ ) : /* @__PURE__ */ jsx(
126
+ EmptyState,
127
+ {
128
+ title: localization?.FORM_BUILDER_LIST_EMPTY ?? t("formBuilder.list.empty", "No forms yet"),
129
+ description: localization?.FORM_BUILDER_LIST_EMPTY_DESCRIPTION ?? t(
130
+ "formBuilder.list.emptyDescription",
131
+ "Create your first form to get started."
132
+ ),
133
+ action: newFormButton
134
+ }
135
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
136
+ /* @__PURE__ */ jsx(
137
+ "div",
138
+ {
139
+ className: cn("rounded-lg border", classNames?.table),
140
+ "data-testid": "form-builder-list-table",
141
+ children: /* @__PURE__ */ jsxs(Table, { children: [
142
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
143
+ /* @__PURE__ */ jsx(TableHead, { children: localization?.FORM_BUILDER_LIST_COLUMN_NAME ?? t("formBuilder.list.columnName", "Name") }),
144
+ /* @__PURE__ */ jsx(TableHead, { children: localization?.FORM_BUILDER_LIST_COLUMN_SLUG ?? t("formBuilder.list.columnSlug", "Slug") }),
145
+ /* @__PURE__ */ jsx(TableHead, { children: localization?.FORM_BUILDER_LIST_COLUMN_STATUS ?? t("formBuilder.list.columnStatus", "Status") }),
146
+ /* @__PURE__ */ jsx(TableHead, { children: localization?.FORM_BUILDER_LIST_COLUMN_CREATED ?? t("formBuilder.list.columnCreated", "Created") }),
147
+ /* @__PURE__ */ jsx(TableHead, { className: "w-12", children: localization?.FORM_BUILDER_LIST_COLUMN_ACTIONS ?? t("formBuilder.list.columnActions", "Actions") })
148
+ ] }) }),
149
+ /* @__PURE__ */ jsx(TableBody, { children: forms.map((form) => /* @__PURE__ */ jsxs(TableRow, { className: classNames?.tableRow, children: [
150
+ /* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: form.name }),
151
+ /* @__PURE__ */ jsx(TableCell, { className: "text-muted-foreground font-mono text-sm", children: form.slug }),
152
+ /* @__PURE__ */ jsx(TableCell, { children: getStatusBadge(form.status) }),
153
+ /* @__PURE__ */ jsx(TableCell, { className: "text-muted-foreground", children: new Date(form.createdAt).toLocaleDateString() }),
154
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
155
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "icon", children: [
156
+ /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }),
157
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: localization?.FORM_BUILDER_LIST_COLUMN_ACTIONS ?? t(
158
+ "formBuilder.list.columnActions",
159
+ "Actions"
160
+ ) })
161
+ ] }) }),
162
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
163
+ /* @__PURE__ */ jsx(
164
+ PermissionAccess,
165
+ {
166
+ permission: formBuilderPermissions.form.update({
167
+ formId: form.id,
168
+ ...form.createdBy ? { ownerId: form.createdBy } : {},
169
+ status: form.status
170
+ }),
171
+ children: /* @__PURE__ */ jsxs(
172
+ DropdownMenuItem,
173
+ {
174
+ onClick: () => navigate("forms", form.id, "edit"),
175
+ children: [
176
+ /* @__PURE__ */ jsx(Pencil, { className: "mr-2 h-4 w-4" }),
177
+ localization?.FORM_BUILDER_LIST_ACTION_EDIT ?? t("formBuilder.list.actionEdit", "Edit")
178
+ ]
179
+ }
180
+ )
181
+ }
182
+ ),
183
+ /* @__PURE__ */ jsx(
184
+ PermissionAccess,
185
+ {
186
+ permission: formBuilderPermissions.submission.read(
187
+ {
188
+ scope: "collection",
189
+ formId: form.id,
190
+ formExists: true,
191
+ ...form.createdBy ? { ownerId: form.createdBy } : {}
192
+ }
193
+ ),
194
+ children: /* @__PURE__ */ jsxs(
195
+ DropdownMenuItem,
196
+ {
197
+ onClick: () => navigate("forms", form.id, "submissions"),
198
+ children: [
199
+ /* @__PURE__ */ jsx(FileText, { className: "mr-2 h-4 w-4" }),
200
+ localization?.FORM_BUILDER_LIST_ACTION_SUBMISSIONS ?? t(
201
+ "formBuilder.list.actionSubmissions",
202
+ "Submissions"
203
+ )
204
+ ]
205
+ }
206
+ )
207
+ }
208
+ ),
209
+ /* @__PURE__ */ jsx(
210
+ PermissionAccess,
211
+ {
212
+ permission: formBuilderPermissions.form.delete({
213
+ formId: form.id,
214
+ ...form.createdBy ? { ownerId: form.createdBy } : {},
215
+ status: form.status
216
+ }),
217
+ children: /* @__PURE__ */ jsxs(
218
+ DropdownMenuItem,
219
+ {
220
+ className: "text-destructive",
221
+ onClick: () => setDeleteId(form.id),
222
+ children: [
223
+ /* @__PURE__ */ jsx(Trash2, { className: "mr-2 h-4 w-4" }),
224
+ localization?.FORM_BUILDER_LIST_ACTION_DELETE ?? t("formBuilder.list.actionDelete", "Delete")
225
+ ]
226
+ }
227
+ )
228
+ }
229
+ )
230
+ ] })
231
+ ] }) })
232
+ ] }, form.id)) })
233
+ ] })
234
+ }
235
+ ),
236
+ /* @__PURE__ */ jsx(
237
+ Pagination,
238
+ {
239
+ total,
240
+ showing: forms.length,
241
+ hasMore,
242
+ isLoadingMore,
243
+ onLoadMore: loadMore,
244
+ className: classNames?.pagination,
245
+ labels: {
246
+ showing: localization?.FORM_BUILDER_LIST_PAGINATION_SHOWING ?? t(
247
+ "formBuilder.list.paginationShowing",
248
+ "Showing {count} of {total}"
249
+ ),
250
+ next: localization?.FORM_BUILDER_LIST_PAGINATION_NEXT ?? t("formBuilder.list.paginationNext", "Load More"),
251
+ loading: localization?.FORM_BUILDER_STATUS_LOADING ?? t("formBuilder.common.statusLoading", "Loading...")
252
+ }
253
+ }
254
+ )
255
+ ] })
256
+ ] }),
257
+ /* @__PURE__ */ jsx(AlertDialog, { open: !!deleteId, onOpenChange: () => setDeleteId(null), children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
258
+ /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
259
+ /* @__PURE__ */ jsx(AlertDialogTitle, { children: localization?.FORM_BUILDER_LIST_DELETE_TITLE ?? t("formBuilder.list.deleteTitle", "Delete Form") }),
260
+ /* @__PURE__ */ jsx(AlertDialogDescription, { children: localization?.FORM_BUILDER_EDITOR_DELETE_CONFIRM ?? t(
261
+ "formBuilder.editor.deleteConfirm",
262
+ "Are you sure you want to delete this form? All submissions will also be deleted."
263
+ ) })
264
+ ] }),
265
+ /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
266
+ /* @__PURE__ */ jsx(AlertDialogCancel, { children: localization?.FORM_BUILDER_BUTTON_CANCEL ?? t("formBuilder.common.buttonCancel", "Cancel") }),
267
+ /* @__PURE__ */ jsx(
268
+ AlertDialogAction,
269
+ {
270
+ onClick: handleDelete,
271
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
272
+ children: deleteMutation.isPending ? localization?.FORM_BUILDER_STATUS_DELETING ?? t("formBuilder.common.statusDeleting", "Deleting...") : localization?.FORM_BUILDER_BUTTON_DELETE ?? t("formBuilder.common.buttonDelete", "Delete")
273
+ }
274
+ )
275
+ ] })
276
+ ] }) })
277
+ ] });
278
+ }
279
+
280
+ export { FormListPage };
@@ -0,0 +1,42 @@
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 } from '@btst/stack/client/components';
6
+ import { DefaultError } from '../shared/default-error.mjs';
7
+ import { FormListSkeleton } from '../loading/form-list-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
+
12
+ const FormListPage = lazy(
13
+ () => import('./form-list-page.internal.mjs').then((m) => ({
14
+ default: m.FormListPage
15
+ }))
16
+ );
17
+ function FormListPageComponent() {
18
+ const { onRouteError } = usePluginOverrides(
19
+ FORM_BUILDER_PLUGIN_ID
20
+ );
21
+ return /* @__PURE__ */ jsx(
22
+ ComposedRoute,
23
+ {
24
+ path: "/forms",
25
+ permission: formBuilderPermissions.form.read({ scope: "collection" }),
26
+ PageComponent: FormListPage,
27
+ ErrorComponent: DefaultError,
28
+ LoadingComponent: FormListSkeleton,
29
+ NotFoundComponent: NotFoundPage,
30
+ onError: (error) => {
31
+ if (onRouteError) {
32
+ onRouteError("formList", error, {
33
+ path: "/forms",
34
+ isSSR: typeof window === "undefined"
35
+ });
36
+ }
37
+ }
38
+ }
39
+ );
40
+ }
41
+
42
+ export { FormListPageComponent };
@@ -0,0 +1,64 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const context = require('@btst/stack/context');
7
+ const components = require('@btst/stack/client/components');
8
+ const defaultError = require('../shared/default-error.cjs');
9
+ const submissionsSkeleton = require('../loading/submissions-skeleton.cjs');
10
+ const _404Page = require('./404-page.cjs');
11
+ const permissions = require('../../../permissions.cjs');
12
+ const constants = require('../../constants.cjs');
13
+ const formBuilderHooks = require('../../hooks/form-builder-hooks.cjs');
14
+
15
+ const SubmissionsPage = React.lazy(
16
+ () => import('./submissions-page.internal.cjs').then((m) => ({
17
+ default: m.SubmissionsPage
18
+ }))
19
+ );
20
+ function SubmissionsPageComponent({ formId }) {
21
+ const { onRouteError } = context.usePluginOverrides(
22
+ constants.FORM_BUILDER_PLUGIN_ID
23
+ );
24
+ const path = `/forms/${formId}/submissions`;
25
+ return /* @__PURE__ */ jsxRuntime.jsx(
26
+ components.ComposedRoute,
27
+ {
28
+ path,
29
+ PageComponent: AuthorizedSubmissionsPage,
30
+ ErrorComponent: defaultError.DefaultError,
31
+ LoadingComponent: submissionsSkeleton.SubmissionsSkeleton,
32
+ NotFoundComponent: _404Page.NotFoundPage,
33
+ props: { formId },
34
+ onError: (error) => {
35
+ if (onRouteError) {
36
+ onRouteError("submissions", error, {
37
+ path,
38
+ params: { formId },
39
+ isSSR: typeof window === "undefined"
40
+ });
41
+ }
42
+ }
43
+ }
44
+ );
45
+ }
46
+ function AuthorizedSubmissionsPage({ formId }) {
47
+ const { form } = formBuilderHooks.useSuspenseSubmissions(formId);
48
+ if (!form) return /* @__PURE__ */ jsxRuntime.jsx(_404Page.NotFoundPage, {});
49
+ return /* @__PURE__ */ jsxRuntime.jsx(
50
+ components.PermissionRouteAccess,
51
+ {
52
+ permission: permissions.formBuilderPermissions.submission.read({
53
+ scope: "collection",
54
+ formId,
55
+ formExists: form !== null,
56
+ ...form?.createdBy ? { ownerId: form.createdBy } : {}
57
+ }),
58
+ LoadingComponent: submissionsSkeleton.SubmissionsSkeleton,
59
+ children: /* @__PURE__ */ jsxRuntime.jsx(SubmissionsPage, { formId })
60
+ }
61
+ );
62
+ }
63
+
64
+ exports.SubmissionsPageComponent = SubmissionsPageComponent;
@@ -0,0 +1,255 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const context = require('@btst/stack/context');
7
+ const button = require('../../../ui/src/components/button.cjs');
8
+ const table = require('../../../ui/src/components/table.cjs');
9
+ const alertDialog = require('../../../ui/src/components/alert-dialog.cjs');
10
+ const dialog = require('../../../ui/src/components/dialog.cjs');
11
+ const lucideReact = require('lucide-react');
12
+ const pageWrapper = require('../shared/page-wrapper.cjs');
13
+ const emptyState = require('../shared/empty-state.cjs');
14
+ const pagination = require('../shared/pagination.cjs');
15
+ const permissions = require('../../../permissions.cjs');
16
+ const constants = require('../../constants.cjs');
17
+ const utils = require('../../../utils.cjs');
18
+ const formBuilderHooks = require('../../hooks/form-builder-hooks.cjs');
19
+
20
+ function SubmissionsPage({ formId }) {
21
+ const t = context.useTranslate();
22
+ const notify = context.useNotify();
23
+ const { localization, classNames } = context.usePluginOverrides(constants.FORM_BUILDER_PLUGIN_ID);
24
+ const { identity } = context.useIdentity();
25
+ const { Link: LinkComponent, resolve } = context.usePluginSiteNavigation(
26
+ constants.FORM_BUILDER_PLUGIN_ID
27
+ );
28
+ const { form, submissions, total, hasMore, isLoadingMore, loadMore } = formBuilderHooks.useSuspenseSubmissions(formId);
29
+ const deleteMutation = formBuilderHooks.useDeleteSubmission(formId);
30
+ const [deleteId, setDeleteId] = React.useState(null);
31
+ const [viewSubmissionId, setViewSubmissionId] = React.useState(null);
32
+ const {
33
+ submission: viewSubmission,
34
+ isLoading: isViewLoading,
35
+ error: viewError
36
+ } = formBuilderHooks.useSubmission(formId, viewSubmissionId ?? void 0);
37
+ React.useEffect(() => {
38
+ setViewSubmissionId(null);
39
+ }, [identity]);
40
+ const handleDelete = async () => {
41
+ if (!deleteId) return;
42
+ try {
43
+ await deleteMutation.mutateAsync(deleteId);
44
+ } catch {
45
+ notify.error(
46
+ localization?.FORM_BUILDER_TOAST_ERROR ?? t("formBuilder.toasts.error", "An error occurred. Please try again.")
47
+ );
48
+ return;
49
+ }
50
+ notify.success(
51
+ localization?.FORM_BUILDER_TOAST_SUBMISSION_DELETED ?? t(
52
+ "formBuilder.toasts.submissionDeleted",
53
+ "Submission deleted successfully"
54
+ )
55
+ );
56
+ setDeleteId(null);
57
+ };
58
+ return /* @__PURE__ */ jsxRuntime.jsxs(pageWrapper.PageWrapper, { testId: "submissions-page", children: [
59
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-5xl space-y-6", children: [
60
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "ghost", size: "icon", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(LinkComponent, { href: resolve("forms").href, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-4 w-4" }) }) }),
62
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
63
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold", children: form?.name || (localization?.FORM_BUILDER_SUBMISSIONS_TITLE ?? t("formBuilder.submissions.title", "Submissions")) }),
64
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_SUBTITLE ?? t("formBuilder.submissions.subtitle", "View form submissions") })
65
+ ] })
66
+ ] }),
67
+ submissions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
68
+ emptyState.EmptyState,
69
+ {
70
+ title: localization?.FORM_BUILDER_SUBMISSIONS_EMPTY ?? t("formBuilder.submissions.empty", "No submissions yet"),
71
+ description: localization?.FORM_BUILDER_SUBMISSIONS_EMPTY_DESCRIPTION ?? t(
72
+ "formBuilder.submissions.emptyDescription",
73
+ "Submissions will appear here when users submit this form."
74
+ )
75
+ }
76
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
77
+ /* @__PURE__ */ jsxRuntime.jsx(
78
+ "div",
79
+ {
80
+ className: utils.cn("rounded-lg border", classNames?.table),
81
+ "data-testid": "form-builder-submissions-table",
82
+ children: /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
83
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
84
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-24", children: localization?.FORM_BUILDER_SUBMISSIONS_COLUMN_ID ?? t("formBuilder.submissions.columnId", "ID") }),
85
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.FORM_BUILDER_SUBMISSIONS_COLUMN_SUBMITTED_AT ?? t(
86
+ "formBuilder.submissions.columnSubmittedAt",
87
+ "Submitted"
88
+ ) }),
89
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-24", children: localization?.FORM_BUILDER_SUBMISSIONS_COLUMN_ACTIONS ?? t("formBuilder.submissions.columnActions", "Actions") })
90
+ ] }) }),
91
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: submissions.map((sub) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { className: classNames?.tableRow, children: [
92
+ /* @__PURE__ */ jsxRuntime.jsxs(table.TableCell, { className: "font-mono text-xs", children: [
93
+ sub.id.slice(0, 8),
94
+ "..."
95
+ ] }),
96
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "text-muted-foreground", children: new Date(sub.submittedAt).toLocaleString() }),
97
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1", children: [
98
+ /* @__PURE__ */ jsxRuntime.jsx(
99
+ context.PermissionAccess,
100
+ {
101
+ permission: permissions.formBuilderPermissions.submission.read({
102
+ scope: "record",
103
+ formId,
104
+ submissionId: sub.id,
105
+ exists: true,
106
+ ...form?.createdBy ? { ownerId: form.createdBy } : {},
107
+ ...sub.submittedBy ? { submittedBy: sub.submittedBy } : {}
108
+ }),
109
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
110
+ button.Button,
111
+ {
112
+ variant: "ghost",
113
+ size: "icon",
114
+ onClick: () => setViewSubmissionId(sub.id),
115
+ children: [
116
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "h-4 w-4" }),
117
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: localization?.FORM_BUILDER_SUBMISSIONS_ACTION_VIEW ?? t(
118
+ "formBuilder.submissions.actionView",
119
+ "View"
120
+ ) })
121
+ ]
122
+ }
123
+ )
124
+ }
125
+ ),
126
+ /* @__PURE__ */ jsxRuntime.jsx(
127
+ context.PermissionAccess,
128
+ {
129
+ permission: permissions.formBuilderPermissions.submission.delete(
130
+ {
131
+ formId,
132
+ submissionId: sub.id,
133
+ exists: true,
134
+ ...form?.createdBy ? { ownerId: form.createdBy } : {},
135
+ ...sub.submittedBy ? { submittedBy: sub.submittedBy } : {}
136
+ }
137
+ ),
138
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
139
+ button.Button,
140
+ {
141
+ variant: "ghost",
142
+ size: "icon",
143
+ className: "text-destructive",
144
+ onClick: () => setDeleteId(sub.id),
145
+ children: [
146
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4" }),
147
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: localization?.FORM_BUILDER_SUBMISSIONS_ACTION_DELETE ?? t(
148
+ "formBuilder.submissions.actionDelete",
149
+ "Delete"
150
+ ) })
151
+ ]
152
+ }
153
+ )
154
+ }
155
+ )
156
+ ] }) })
157
+ ] }, sub.id)) })
158
+ ] })
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsxRuntime.jsx(
162
+ pagination.Pagination,
163
+ {
164
+ total,
165
+ showing: submissions.length,
166
+ hasMore,
167
+ isLoadingMore,
168
+ onLoadMore: loadMore,
169
+ className: classNames?.pagination,
170
+ labels: {
171
+ showing: localization?.FORM_BUILDER_LIST_PAGINATION_SHOWING ?? t(
172
+ "formBuilder.list.paginationShowing",
173
+ "Showing {count} of {total}"
174
+ ),
175
+ next: localization?.FORM_BUILDER_LIST_PAGINATION_NEXT ?? t("formBuilder.list.paginationNext", "Load More"),
176
+ loading: localization?.FORM_BUILDER_STATUS_LOADING ?? t("formBuilder.common.statusLoading", "Loading...")
177
+ }
178
+ }
179
+ )
180
+ ] })
181
+ ] }),
182
+ /* @__PURE__ */ jsxRuntime.jsx(
183
+ dialog.Dialog,
184
+ {
185
+ open: !!viewSubmissionId,
186
+ onOpenChange: (open) => {
187
+ if (!open) setViewSubmissionId(null);
188
+ },
189
+ children: /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogContent, { className: "max-w-2xl max-h-[80vh] overflow-auto", children: [
190
+ /* @__PURE__ */ jsxRuntime.jsxs(dialog.DialogHeader, { children: [
191
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogTitle, { children: localization?.FORM_BUILDER_SUBMISSIONS_DETAILS_TITLE ?? t("formBuilder.submissions.detailsTitle", "Submission Details") }),
192
+ /* @__PURE__ */ jsxRuntime.jsx(dialog.DialogDescription, { className: "sr-only", children: t(
193
+ "formBuilder.submissions.detailsDescription",
194
+ "Submitted form data and request metadata."
195
+ ) })
196
+ ] }),
197
+ isViewLoading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: localization?.FORM_BUILDER_STATUS_LOADING ?? t("formBuilder.common.statusLoading", "Loading...") }),
198
+ viewError && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: localization?.FORM_BUILDER_TOAST_ERROR ?? t(
199
+ "formBuilder.toasts.error",
200
+ "An error occurred. Please try again."
201
+ ) }),
202
+ !isViewLoading && !viewError && viewSubmission && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
203
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 text-sm", children: [
204
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
205
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_ID ?? t("formBuilder.submissions.fieldId", "ID:") }),
206
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono truncate", children: viewSubmission.id })
207
+ ] }),
208
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
209
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_SUBMITTED ?? t("formBuilder.submissions.fieldSubmitted", "Submitted:") }),
210
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate", children: new Date(viewSubmission.submittedAt).toLocaleString() })
211
+ ] }),
212
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
213
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_IP ?? t("formBuilder.submissions.fieldIp", "IP Address:") }),
214
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono truncate", children: viewSubmission.ipAddress || "-" })
215
+ ] }),
216
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
217
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_USER_AGENT ?? t(
218
+ "formBuilder.submissions.fieldUserAgent",
219
+ "User Agent:"
220
+ ) }),
221
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs truncate", children: viewSubmission.userAgent || "-" })
222
+ ] })
223
+ ] }),
224
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
225
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: localization?.FORM_BUILDER_SUBMISSIONS_FIELD_DATA ?? t("formBuilder.submissions.fieldData", "Data:") }),
226
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-2 p-4 bg-muted rounded-lg text-sm overflow-auto", children: JSON.stringify(viewSubmission.parsedData, null, 2) })
227
+ ] })
228
+ ] })
229
+ ] })
230
+ }
231
+ ),
232
+ /* @__PURE__ */ jsxRuntime.jsx(alertDialog.AlertDialog, { open: !!deleteId, onOpenChange: () => setDeleteId(null), children: /* @__PURE__ */ jsxRuntime.jsxs(alertDialog.AlertDialogContent, { children: [
233
+ /* @__PURE__ */ jsxRuntime.jsxs(alertDialog.AlertDialogHeader, { children: [
234
+ /* @__PURE__ */ jsxRuntime.jsx(alertDialog.AlertDialogTitle, { children: localization?.FORM_BUILDER_SUBMISSIONS_DELETE_TITLE ?? t("formBuilder.submissions.deleteTitle", "Delete Submission") }),
235
+ /* @__PURE__ */ jsxRuntime.jsx(alertDialog.AlertDialogDescription, { children: localization?.FORM_BUILDER_SUBMISSIONS_DELETE_CONFIRM ?? t(
236
+ "formBuilder.submissions.deleteConfirm",
237
+ "Are you sure you want to delete this submission?"
238
+ ) })
239
+ ] }),
240
+ /* @__PURE__ */ jsxRuntime.jsxs(alertDialog.AlertDialogFooter, { children: [
241
+ /* @__PURE__ */ jsxRuntime.jsx(alertDialog.AlertDialogCancel, { children: localization?.FORM_BUILDER_BUTTON_CANCEL ?? t("formBuilder.common.buttonCancel", "Cancel") }),
242
+ /* @__PURE__ */ jsxRuntime.jsx(
243
+ alertDialog.AlertDialogAction,
244
+ {
245
+ onClick: handleDelete,
246
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
247
+ children: deleteMutation.isPending ? localization?.FORM_BUILDER_STATUS_DELETING ?? t("formBuilder.common.statusDeleting", "Deleting...") : localization?.FORM_BUILDER_BUTTON_DELETE ?? t("formBuilder.common.buttonDelete", "Delete")
248
+ }
249
+ )
250
+ ] })
251
+ ] }) })
252
+ ] });
253
+ }
254
+
255
+ exports.SubmissionsPage = SubmissionsPage;