@actuate-media/cms-admin 0.8.0 → 0.8.2

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 (433) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +44 -42
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/lib/search.test.js +10 -10
  5. package/dist/__tests__/lib/search.test.js.map +1 -1
  6. package/dist/__tests__/lib/utils.test.js.map +1 -1
  7. package/dist/__tests__/router/match-route.test.js.map +1 -1
  8. package/dist/__tests__/router/strip-base.test.js.map +1 -1
  9. package/dist/actuate-admin.css +1 -1
  10. package/dist/components/Breadcrumbs.d.ts.map +1 -1
  11. package/dist/components/Breadcrumbs.js +2 -4
  12. package/dist/components/Breadcrumbs.js.map +1 -1
  13. package/dist/components/CommandPalette.d.ts.map +1 -1
  14. package/dist/components/CommandPalette.js +7 -3
  15. package/dist/components/CommandPalette.js.map +1 -1
  16. package/dist/components/ContentOverviewChart.d.ts.map +1 -1
  17. package/dist/components/ContentOverviewChart.js.map +1 -1
  18. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  19. package/dist/components/ErrorBoundary.js.map +1 -1
  20. package/dist/components/FocalPointPicker.d.ts.map +1 -1
  21. package/dist/components/FocalPointPicker.js +4 -2
  22. package/dist/components/FocalPointPicker.js.map +1 -1
  23. package/dist/components/FolderTree.d.ts.map +1 -1
  24. package/dist/components/FolderTree.js +18 -10
  25. package/dist/components/FolderTree.js.map +1 -1
  26. package/dist/components/LivePreview.d.ts +1 -1
  27. package/dist/components/LivePreview.d.ts.map +1 -1
  28. package/dist/components/LivePreview.js +6 -2
  29. package/dist/components/LivePreview.js.map +1 -1
  30. package/dist/components/LocaleProvider.d.ts.map +1 -1
  31. package/dist/components/LocaleProvider.js.map +1 -1
  32. package/dist/components/LocaleSwitcher.d.ts.map +1 -1
  33. package/dist/components/LocaleSwitcher.js +1 -1
  34. package/dist/components/LocaleSwitcher.js.map +1 -1
  35. package/dist/components/MediaPickerModal.d.ts.map +1 -1
  36. package/dist/components/MediaPickerModal.js.map +1 -1
  37. package/dist/components/PresenceIndicator.d.ts.map +1 -1
  38. package/dist/components/PresenceIndicator.js +5 -2
  39. package/dist/components/PresenceIndicator.js.map +1 -1
  40. package/dist/components/SEOPanel.d.ts +1 -1
  41. package/dist/components/SEOPanel.d.ts.map +1 -1
  42. package/dist/components/SEOPanel.js +110 -24
  43. package/dist/components/SEOPanel.js.map +1 -1
  44. package/dist/components/SEOPerformance.d.ts.map +1 -1
  45. package/dist/components/SEOPerformance.js +2 -2
  46. package/dist/components/SEOPerformance.js.map +1 -1
  47. package/dist/components/ThemeProvider.d.ts.map +1 -1
  48. package/dist/components/ThemeProvider.js.map +1 -1
  49. package/dist/components/TipTapEditor.d.ts.map +1 -1
  50. package/dist/components/TipTapEditor.js +5 -1
  51. package/dist/components/TipTapEditor.js.map +1 -1
  52. package/dist/components/VersionHistory.d.ts +1 -1
  53. package/dist/components/VersionHistory.d.ts.map +1 -1
  54. package/dist/components/VersionHistory.js +1 -1
  55. package/dist/components/VersionHistory.js.map +1 -1
  56. package/dist/components/ui/Avatar.d.ts.map +1 -1
  57. package/dist/components/ui/Avatar.js.map +1 -1
  58. package/dist/components/ui/Badge.d.ts.map +1 -1
  59. package/dist/components/ui/Badge.js.map +1 -1
  60. package/dist/components/ui/Button.d.ts.map +1 -1
  61. package/dist/components/ui/Button.js.map +1 -1
  62. package/dist/components/ui/CommandPalette.d.ts.map +1 -1
  63. package/dist/components/ui/CommandPalette.js +8 -2
  64. package/dist/components/ui/CommandPalette.js.map +1 -1
  65. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -1
  66. package/dist/components/ui/ConfirmDialog.js.map +1 -1
  67. package/dist/components/ui/DataTable.d.ts.map +1 -1
  68. package/dist/components/ui/DataTable.js +1 -3
  69. package/dist/components/ui/DataTable.js.map +1 -1
  70. package/dist/components/ui/EmptyState.d.ts.map +1 -1
  71. package/dist/components/ui/EmptyState.js +1 -1
  72. package/dist/components/ui/EmptyState.js.map +1 -1
  73. package/dist/components/ui/Modal.d.ts.map +1 -1
  74. package/dist/components/ui/Modal.js.map +1 -1
  75. package/dist/components/ui/Pagination.d.ts +1 -1
  76. package/dist/components/ui/Pagination.d.ts.map +1 -1
  77. package/dist/components/ui/Pagination.js +7 -2
  78. package/dist/components/ui/Pagination.js.map +1 -1
  79. package/dist/components/ui/SearchInput.d.ts.map +1 -1
  80. package/dist/components/ui/SearchInput.js.map +1 -1
  81. package/dist/components/ui/Skeleton.d.ts.map +1 -1
  82. package/dist/components/ui/Skeleton.js.map +1 -1
  83. package/dist/components/ui/Toast.d.ts.map +1 -1
  84. package/dist/components/ui/Toast.js.map +1 -1
  85. package/dist/components/ui/index.d.ts.map +1 -1
  86. package/dist/components/ui/index.js.map +1 -1
  87. package/dist/fields/ArrayField.d.ts.map +1 -1
  88. package/dist/fields/ArrayField.js +1 -1
  89. package/dist/fields/ArrayField.js.map +1 -1
  90. package/dist/fields/BlockBuilderField.d.ts.map +1 -1
  91. package/dist/fields/BlockBuilderField.js +7 -7
  92. package/dist/fields/BlockBuilderField.js.map +1 -1
  93. package/dist/fields/DateField.d.ts.map +1 -1
  94. package/dist/fields/DateField.js +1 -1
  95. package/dist/fields/DateField.js.map +1 -1
  96. package/dist/fields/FieldRenderer.d.ts.map +1 -1
  97. package/dist/fields/FieldRenderer.js.map +1 -1
  98. package/dist/fields/GroupField.d.ts.map +1 -1
  99. package/dist/fields/GroupField.js +1 -1
  100. package/dist/fields/GroupField.js.map +1 -1
  101. package/dist/fields/MediaField.d.ts.map +1 -1
  102. package/dist/fields/MediaField.js +1 -1
  103. package/dist/fields/MediaField.js.map +1 -1
  104. package/dist/fields/NavBuilderField.d.ts.map +1 -1
  105. package/dist/fields/NavBuilderField.js +2 -5
  106. package/dist/fields/NavBuilderField.js.map +1 -1
  107. package/dist/fields/NumberField.d.ts +1 -1
  108. package/dist/fields/NumberField.d.ts.map +1 -1
  109. package/dist/fields/NumberField.js +2 -2
  110. package/dist/fields/NumberField.js.map +1 -1
  111. package/dist/fields/RelationshipField.d.ts.map +1 -1
  112. package/dist/fields/RelationshipField.js +7 -3
  113. package/dist/fields/RelationshipField.js.map +1 -1
  114. package/dist/fields/RichTextField.d.ts +1 -1
  115. package/dist/fields/RichTextField.d.ts.map +1 -1
  116. package/dist/fields/RichTextField.js +2 -2
  117. package/dist/fields/RichTextField.js.map +1 -1
  118. package/dist/fields/SelectField.d.ts.map +1 -1
  119. package/dist/fields/SelectField.js +9 -7
  120. package/dist/fields/SelectField.js.map +1 -1
  121. package/dist/fields/SlugField.d.ts.map +1 -1
  122. package/dist/fields/SlugField.js +1 -1
  123. package/dist/fields/SlugField.js.map +1 -1
  124. package/dist/fields/TextField.d.ts +1 -1
  125. package/dist/fields/TextField.d.ts.map +1 -1
  126. package/dist/fields/TextField.js +2 -2
  127. package/dist/fields/TextField.js.map +1 -1
  128. package/dist/fields/ToggleField.d.ts.map +1 -1
  129. package/dist/fields/ToggleField.js +1 -1
  130. package/dist/fields/ToggleField.js.map +1 -1
  131. package/dist/fields/block-types.d.ts.map +1 -1
  132. package/dist/fields/block-types.js +28 -8
  133. package/dist/fields/block-types.js.map +1 -1
  134. package/dist/fields/index.d.ts.map +1 -1
  135. package/dist/fields/index.js.map +1 -1
  136. package/dist/hooks/useBuilderState.d.ts.map +1 -1
  137. package/dist/hooks/useBuilderState.js.map +1 -1
  138. package/dist/hooks/useContentLock.d.ts.map +1 -1
  139. package/dist/hooks/useContentLock.js.map +1 -1
  140. package/dist/hooks/useDebounce.js.map +1 -1
  141. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  142. package/dist/hooks/useKeyboardShortcuts.js.map +1 -1
  143. package/dist/index.d.ts +2 -2
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js.map +1 -1
  146. package/dist/layout/Header.d.ts.map +1 -1
  147. package/dist/layout/Header.js.map +1 -1
  148. package/dist/layout/Layout.d.ts.map +1 -1
  149. package/dist/layout/Layout.js.map +1 -1
  150. package/dist/layout/Sidebar.d.ts +1 -1
  151. package/dist/layout/Sidebar.d.ts.map +1 -1
  152. package/dist/layout/Sidebar.js +5 -8
  153. package/dist/layout/Sidebar.js.map +1 -1
  154. package/dist/lib/api.js.map +1 -1
  155. package/dist/lib/search.d.ts.map +1 -1
  156. package/dist/lib/search.js +3 -5
  157. package/dist/lib/search.js.map +1 -1
  158. package/dist/lib/useApiData.d.ts.map +1 -1
  159. package/dist/lib/useApiData.js.map +1 -1
  160. package/dist/lib/utils.d.ts.map +1 -1
  161. package/dist/lib/utils.js.map +1 -1
  162. package/dist/router/index.d.ts.map +1 -1
  163. package/dist/router/index.js +1 -3
  164. package/dist/router/index.js.map +1 -1
  165. package/dist/views/CollectionList.d.ts.map +1 -1
  166. package/dist/views/CollectionList.js +56 -17
  167. package/dist/views/CollectionList.js.map +1 -1
  168. package/dist/views/Dashboard.d.ts.map +1 -1
  169. package/dist/views/Dashboard.js +26 -13
  170. package/dist/views/Dashboard.js.map +1 -1
  171. package/dist/views/DocumentEdit.d.ts +1 -1
  172. package/dist/views/DocumentEdit.d.ts.map +1 -1
  173. package/dist/views/DocumentEdit.js +33 -15
  174. package/dist/views/DocumentEdit.js.map +1 -1
  175. package/dist/views/ForgotPassword.d.ts.map +1 -1
  176. package/dist/views/ForgotPassword.js.map +1 -1
  177. package/dist/views/FormEditor.d.ts.map +1 -1
  178. package/dist/views/FormEditor.js +8 -2
  179. package/dist/views/FormEditor.js.map +1 -1
  180. package/dist/views/FormSubmissions.d.ts.map +1 -1
  181. package/dist/views/FormSubmissions.js +6 -6
  182. package/dist/views/FormSubmissions.js.map +1 -1
  183. package/dist/views/Forms.d.ts.map +1 -1
  184. package/dist/views/Forms.js.map +1 -1
  185. package/dist/views/Login.d.ts.map +1 -1
  186. package/dist/views/Login.js +5 -2
  187. package/dist/views/Login.js.map +1 -1
  188. package/dist/views/MediaBrowser.d.ts.map +1 -1
  189. package/dist/views/MediaBrowser.js +39 -19
  190. package/dist/views/MediaBrowser.js.map +1 -1
  191. package/dist/views/PageEditor.d.ts.map +1 -1
  192. package/dist/views/PageEditor.js.map +1 -1
  193. package/dist/views/Pages.d.ts.map +1 -1
  194. package/dist/views/Pages.js +20 -10
  195. package/dist/views/Pages.js.map +1 -1
  196. package/dist/views/PostEditor.d.ts.map +1 -1
  197. package/dist/views/PostEditor.js.map +1 -1
  198. package/dist/views/Posts.d.ts.map +1 -1
  199. package/dist/views/Posts.js +13 -7
  200. package/dist/views/Posts.js.map +1 -1
  201. package/dist/views/Redirects.d.ts.map +1 -1
  202. package/dist/views/Redirects.js +17 -5
  203. package/dist/views/Redirects.js.map +1 -1
  204. package/dist/views/ResetPassword.d.ts.map +1 -1
  205. package/dist/views/ResetPassword.js.map +1 -1
  206. package/dist/views/SEO.d.ts.map +1 -1
  207. package/dist/views/SEO.js +40 -17
  208. package/dist/views/SEO.js.map +1 -1
  209. package/dist/views/ScriptTagEditor.d.ts.map +1 -1
  210. package/dist/views/ScriptTagEditor.js +2 -1
  211. package/dist/views/ScriptTagEditor.js.map +1 -1
  212. package/dist/views/ScriptTags.d.ts.map +1 -1
  213. package/dist/views/ScriptTags.js.map +1 -1
  214. package/dist/views/Settings.d.ts.map +1 -1
  215. package/dist/views/Settings.js +38 -11
  216. package/dist/views/Settings.js.map +1 -1
  217. package/dist/views/SetupWizard.d.ts.map +1 -1
  218. package/dist/views/SetupWizard.js.map +1 -1
  219. package/dist/views/Users.d.ts.map +1 -1
  220. package/dist/views/Users.js +5 -3
  221. package/dist/views/Users.js.map +1 -1
  222. package/dist/views/page-builder/AIBlockAssist.d.ts.map +1 -1
  223. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  224. package/dist/views/page-builder/AIBlockAssist.js.map +1 -1
  225. package/dist/views/page-builder/AIGenerateDialog.d.ts.map +1 -1
  226. package/dist/views/page-builder/AIGenerateDialog.js +4 -1
  227. package/dist/views/page-builder/AIGenerateDialog.js.map +1 -1
  228. package/dist/views/page-builder/BlockEditor.d.ts.map +1 -1
  229. package/dist/views/page-builder/BlockEditor.js +1 -1
  230. package/dist/views/page-builder/BlockEditor.js.map +1 -1
  231. package/dist/views/page-builder/BlockPicker.d.ts.map +1 -1
  232. package/dist/views/page-builder/BlockPicker.js.map +1 -1
  233. package/dist/views/page-builder/BottomBar.d.ts.map +1 -1
  234. package/dist/views/page-builder/BottomBar.js.map +1 -1
  235. package/dist/views/page-builder/BuilderToolbar.d.ts.map +1 -1
  236. package/dist/views/page-builder/BuilderToolbar.js.map +1 -1
  237. package/dist/views/page-builder/ContextPanel.d.ts.map +1 -1
  238. package/dist/views/page-builder/ContextPanel.js +4 -1
  239. package/dist/views/page-builder/ContextPanel.js.map +1 -1
  240. package/dist/views/page-builder/DesignScore.d.ts.map +1 -1
  241. package/dist/views/page-builder/DesignScore.js.map +1 -1
  242. package/dist/views/page-builder/NodeSettings.d.ts.map +1 -1
  243. package/dist/views/page-builder/NodeSettings.js +1 -1
  244. package/dist/views/page-builder/NodeSettings.js.map +1 -1
  245. package/dist/views/page-builder/PageBuilder.d.ts +1 -1
  246. package/dist/views/page-builder/PageBuilder.d.ts.map +1 -1
  247. package/dist/views/page-builder/PageBuilder.js +4 -2
  248. package/dist/views/page-builder/PageBuilder.js.map +1 -1
  249. package/dist/views/page-builder/PageSettings.d.ts.map +1 -1
  250. package/dist/views/page-builder/PageSettings.js.map +1 -1
  251. package/dist/views/page-builder/PageTemplates.d.ts.map +1 -1
  252. package/dist/views/page-builder/PageTemplates.js.map +1 -1
  253. package/dist/views/page-builder/SEOPanel.d.ts.map +1 -1
  254. package/dist/views/page-builder/SEOPanel.js +1 -3
  255. package/dist/views/page-builder/SEOPanel.js.map +1 -1
  256. package/dist/views/page-builder/SavedSections.d.ts.map +1 -1
  257. package/dist/views/page-builder/SavedSections.js +3 -7
  258. package/dist/views/page-builder/SavedSections.js.map +1 -1
  259. package/dist/views/page-builder/TemplatePicker.d.ts.map +1 -1
  260. package/dist/views/page-builder/TemplatePicker.js.map +1 -1
  261. package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +1 -1
  262. package/dist/views/page-builder/block-renderers/CTAPreview.js +1 -1
  263. package/dist/views/page-builder/block-renderers/CTAPreview.js.map +1 -1
  264. package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +1 -1
  265. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  266. package/dist/views/page-builder/block-renderers/CardsPreview.js.map +1 -1
  267. package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +1 -1
  268. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -5
  269. package/dist/views/page-builder/block-renderers/CodePreview.js.map +1 -1
  270. package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +1 -1
  271. package/dist/views/page-builder/block-renderers/FAQPreview.js +4 -1
  272. package/dist/views/page-builder/block-renderers/FAQPreview.js.map +1 -1
  273. package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +1 -1
  274. package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +1 -1
  275. package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +1 -1
  276. package/dist/views/page-builder/block-renderers/FormPreview.js +2 -2
  277. package/dist/views/page-builder/block-renderers/FormPreview.js.map +1 -1
  278. package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +1 -1
  279. package/dist/views/page-builder/block-renderers/GalleryPreview.js +1 -3
  280. package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +1 -1
  281. package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +1 -1
  282. package/dist/views/page-builder/block-renderers/HeroPreview.js.map +1 -1
  283. package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +1 -1
  284. package/dist/views/page-builder/block-renderers/ImagePreview.js.map +1 -1
  285. package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +1 -1
  286. package/dist/views/page-builder/block-renderers/TextPreview.js +2 -6
  287. package/dist/views/page-builder/block-renderers/TextPreview.js.map +1 -1
  288. package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +1 -1
  289. package/dist/views/page-builder/block-renderers/VideoPreview.js +2 -5
  290. package/dist/views/page-builder/block-renderers/VideoPreview.js.map +1 -1
  291. package/dist/views/page-builder/block-renderers/index.d.ts.map +1 -1
  292. package/dist/views/page-builder/block-renderers/index.js.map +1 -1
  293. package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +1 -1
  294. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -5
  295. package/dist/views/page-builder/canvas/BlockRenderer.js.map +1 -1
  296. package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +1 -1
  297. package/dist/views/page-builder/canvas/BuilderCanvas.js.map +1 -1
  298. package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +1 -1
  299. package/dist/views/page-builder/canvas/ColumnRenderer.js +1 -5
  300. package/dist/views/page-builder/canvas/ColumnRenderer.js.map +1 -1
  301. package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +1 -1
  302. package/dist/views/page-builder/canvas/ContainerRenderer.js +1 -5
  303. package/dist/views/page-builder/canvas/ContainerRenderer.js.map +1 -1
  304. package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +1 -1
  305. package/dist/views/page-builder/canvas/RowRenderer.js +1 -5
  306. package/dist/views/page-builder/canvas/RowRenderer.js.map +1 -1
  307. package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +1 -1
  308. package/dist/views/page-builder/canvas/SectionRenderer.js +1 -5
  309. package/dist/views/page-builder/canvas/SectionRenderer.js.map +1 -1
  310. package/dist/views/page-builder/canvas/index.d.ts.map +1 -1
  311. package/dist/views/page-builder/canvas/index.js.map +1 -1
  312. package/package.json +2 -2
  313. package/src/AdminRoot.tsx +263 -191
  314. package/src/__tests__/lib/search.test.ts +60 -69
  315. package/src/__tests__/lib/utils.test.ts +12 -12
  316. package/src/__tests__/router/match-route.test.ts +24 -26
  317. package/src/__tests__/router/strip-base.test.ts +15 -15
  318. package/src/components/Breadcrumbs.tsx +27 -24
  319. package/src/components/CommandPalette.tsx +115 -99
  320. package/src/components/ContentOverviewChart.tsx +19 -14
  321. package/src/components/ErrorBoundary.tsx +13 -13
  322. package/src/components/FocalPointPicker.tsx +31 -20
  323. package/src/components/FolderTree.tsx +172 -139
  324. package/src/components/LivePreview.tsx +68 -41
  325. package/src/components/LocaleProvider.tsx +26 -20
  326. package/src/components/LocaleSwitcher.tsx +9 -11
  327. package/src/components/MediaPickerModal.tsx +46 -45
  328. package/src/components/PresenceIndicator.tsx +30 -27
  329. package/src/components/SEOPanel.tsx +378 -228
  330. package/src/components/SEOPerformance.tsx +52 -30
  331. package/src/components/ThemeProvider.tsx +46 -46
  332. package/src/components/TipTapEditor.tsx +60 -64
  333. package/src/components/VersionHistory.tsx +63 -52
  334. package/src/components/ui/Avatar.tsx +8 -8
  335. package/src/components/ui/Badge.tsx +7 -5
  336. package/src/components/ui/Button.tsx +24 -13
  337. package/src/components/ui/CommandPalette.tsx +56 -42
  338. package/src/components/ui/ConfirmDialog.tsx +14 -14
  339. package/src/components/ui/DataTable.tsx +37 -39
  340. package/src/components/ui/EmptyState.tsx +9 -11
  341. package/src/components/ui/Modal.tsx +21 -15
  342. package/src/components/ui/Pagination.tsx +34 -19
  343. package/src/components/ui/SearchInput.tsx +17 -7
  344. package/src/components/ui/Skeleton.tsx +7 -7
  345. package/src/components/ui/Toast.tsx +29 -22
  346. package/src/components/ui/index.ts +24 -24
  347. package/src/fields/ArrayField.tsx +43 -25
  348. package/src/fields/BlockBuilderField.tsx +80 -99
  349. package/src/fields/DateField.tsx +20 -12
  350. package/src/fields/FieldRenderer.tsx +34 -34
  351. package/src/fields/GroupField.tsx +8 -10
  352. package/src/fields/MediaField.tsx +8 -10
  353. package/src/fields/NavBuilderField.tsx +24 -25
  354. package/src/fields/NumberField.tsx +21 -14
  355. package/src/fields/RelationshipField.tsx +105 -91
  356. package/src/fields/RichTextField.tsx +16 -12
  357. package/src/fields/SelectField.tsx +42 -34
  358. package/src/fields/SlugField.tsx +29 -17
  359. package/src/fields/TextField.tsx +24 -16
  360. package/src/fields/ToggleField.tsx +7 -9
  361. package/src/fields/block-types.ts +50 -24
  362. package/src/fields/index.ts +17 -17
  363. package/src/hooks/useBuilderState.ts +260 -221
  364. package/src/hooks/useContentLock.ts +23 -20
  365. package/src/hooks/useDebounce.ts +7 -7
  366. package/src/hooks/useKeyboardShortcuts.ts +16 -16
  367. package/src/index.ts +69 -58
  368. package/src/layout/Header.tsx +21 -20
  369. package/src/layout/Layout.tsx +22 -24
  370. package/src/layout/Sidebar.tsx +107 -72
  371. package/src/lib/api.ts +34 -34
  372. package/src/lib/search.ts +30 -34
  373. package/src/lib/useApiData.ts +65 -62
  374. package/src/lib/utils.ts +3 -3
  375. package/src/router/index.ts +33 -35
  376. package/src/styles/build-input.css +2 -2
  377. package/src/styles/tailwind.css +1 -1
  378. package/src/styles/theme.css +26 -2
  379. package/src/views/CollectionList.tsx +275 -121
  380. package/src/views/Dashboard.tsx +164 -117
  381. package/src/views/DocumentEdit.tsx +298 -253
  382. package/src/views/ForgotPassword.tsx +27 -23
  383. package/src/views/FormEditor.tsx +165 -99
  384. package/src/views/FormSubmissions.tsx +261 -117
  385. package/src/views/Forms.tsx +56 -26
  386. package/src/views/Login.tsx +107 -84
  387. package/src/views/MediaBrowser.tsx +717 -523
  388. package/src/views/PageEditor.tsx +44 -46
  389. package/src/views/Pages.tsx +312 -149
  390. package/src/views/PostEditor.tsx +57 -51
  391. package/src/views/Posts.tsx +206 -74
  392. package/src/views/Redirects.tsx +173 -117
  393. package/src/views/ResetPassword.tsx +43 -32
  394. package/src/views/SEO.tsx +607 -160
  395. package/src/views/ScriptTagEditor.tsx +69 -69
  396. package/src/views/ScriptTags.tsx +54 -42
  397. package/src/views/Settings.tsx +430 -220
  398. package/src/views/SetupWizard.tsx +69 -46
  399. package/src/views/Users.tsx +154 -120
  400. package/src/views/page-builder/AIBlockAssist.tsx +21 -25
  401. package/src/views/page-builder/AIGenerateDialog.tsx +134 -127
  402. package/src/views/page-builder/BlockEditor.tsx +94 -96
  403. package/src/views/page-builder/BlockPicker.tsx +73 -88
  404. package/src/views/page-builder/BottomBar.tsx +15 -11
  405. package/src/views/page-builder/BuilderToolbar.tsx +32 -29
  406. package/src/views/page-builder/ContextPanel.tsx +57 -57
  407. package/src/views/page-builder/DesignScore.tsx +52 -59
  408. package/src/views/page-builder/NodeSettings.tsx +59 -59
  409. package/src/views/page-builder/PageBuilder.tsx +156 -155
  410. package/src/views/page-builder/PageSettings.tsx +16 -15
  411. package/src/views/page-builder/PageTemplates.tsx +23 -17
  412. package/src/views/page-builder/SEOPanel.tsx +90 -111
  413. package/src/views/page-builder/SavedSections.tsx +99 -105
  414. package/src/views/page-builder/TemplatePicker.tsx +44 -48
  415. package/src/views/page-builder/block-renderers/CTAPreview.tsx +11 -13
  416. package/src/views/page-builder/block-renderers/CardsPreview.tsx +13 -15
  417. package/src/views/page-builder/block-renderers/CodePreview.tsx +16 -16
  418. package/src/views/page-builder/block-renderers/FAQPreview.tsx +20 -23
  419. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +5 -5
  420. package/src/views/page-builder/block-renderers/FormPreview.tsx +9 -13
  421. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +22 -28
  422. package/src/views/page-builder/block-renderers/HeroPreview.tsx +17 -30
  423. package/src/views/page-builder/block-renderers/ImagePreview.tsx +12 -12
  424. package/src/views/page-builder/block-renderers/TextPreview.tsx +22 -22
  425. package/src/views/page-builder/block-renderers/VideoPreview.tsx +13 -18
  426. package/src/views/page-builder/block-renderers/index.ts +17 -17
  427. package/src/views/page-builder/canvas/BlockRenderer.tsx +19 -23
  428. package/src/views/page-builder/canvas/BuilderCanvas.tsx +17 -20
  429. package/src/views/page-builder/canvas/ColumnRenderer.tsx +22 -26
  430. package/src/views/page-builder/canvas/ContainerRenderer.tsx +20 -24
  431. package/src/views/page-builder/canvas/RowRenderer.tsx +19 -23
  432. package/src/views/page-builder/canvas/SectionRenderer.tsx +30 -34
  433. package/src/views/page-builder/canvas/index.ts +2 -2
@@ -1,45 +1,45 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, type FormEvent } from 'react';
4
- import { Shield, ArrowLeft, Loader2, CheckCircle2, AlertTriangle } from 'lucide-react';
5
- import { cmsApi } from '../lib/api.js';
3
+ import { useState, type FormEvent } from 'react'
4
+ import { Shield, ArrowLeft, Loader2, CheckCircle2, AlertTriangle } from 'lucide-react'
5
+ import { cmsApi } from '../lib/api.js'
6
6
 
7
7
  export interface ForgotPasswordProps {
8
- onNavigate: (path: string) => void;
8
+ onNavigate: (path: string) => void
9
9
  }
10
10
 
11
11
  export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
12
- const [email, setEmail] = useState('');
13
- const [submitting, setSubmitting] = useState(false);
14
- const [sent, setSent] = useState(false);
15
- const [error, setError] = useState('');
12
+ const [email, setEmail] = useState('')
13
+ const [submitting, setSubmitting] = useState(false)
14
+ const [sent, setSent] = useState(false)
15
+ const [error, setError] = useState('')
16
16
 
17
- const canSubmit = email.trim() && !submitting;
17
+ const canSubmit = email.trim() && !submitting
18
18
 
19
19
  const handleSubmit = async (e: FormEvent) => {
20
- e.preventDefault();
21
- if (!canSubmit) return;
20
+ e.preventDefault()
21
+ if (!canSubmit) return
22
22
 
23
- setError('');
24
- setSubmitting(true);
23
+ setError('')
24
+ setSubmitting(true)
25
25
 
26
26
  try {
27
27
  const result = await cmsApi('/auth/forgot-password', {
28
28
  method: 'POST',
29
29
  body: JSON.stringify({ email: email.trim() }),
30
- });
30
+ })
31
31
 
32
32
  if (result.error && result.status === 429) {
33
- setError('Too many requests. Please try again later.');
33
+ setError('Too many requests. Please try again later.')
34
34
  } else {
35
- setSent(true);
35
+ setSent(true)
36
36
  }
37
37
  } catch {
38
- setError('An unexpected error occurred. Please try again.');
38
+ setError('An unexpected error occurred. Please try again.')
39
39
  } finally {
40
- setSubmitting(false);
40
+ setSubmitting(false)
41
41
  }
42
- };
42
+ }
43
43
 
44
44
  return (
45
45
  <div className="min-h-screen flex items-center justify-center bg-gray-50 px-4">
@@ -63,7 +63,8 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
63
63
  <CheckCircle2 className="w-6 h-6 text-green-600" />
64
64
  </div>
65
65
  <p className="text-sm text-gray-600">
66
- If an account exists for <strong>{email}</strong>, you will receive a password reset email shortly.
66
+ If an account exists for <strong>{email}</strong>, you will receive a password reset
67
+ email shortly.
67
68
  </p>
68
69
  <p className="text-xs text-gray-500">
69
70
  The link expires in 1 hour. Check your spam folder if you don't see it.
@@ -86,7 +87,10 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
86
87
  )}
87
88
 
88
89
  <div>
89
- <label htmlFor="forgot-email" className="block text-sm font-medium text-gray-700 mb-1.5">
90
+ <label
91
+ htmlFor="forgot-email"
92
+ className="block text-sm font-medium text-gray-700 mb-1.5"
93
+ >
90
94
  Email Address
91
95
  </label>
92
96
  <input
@@ -132,5 +136,5 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
132
136
  </div>
133
137
  </div>
134
138
  </div>
135
- );
139
+ )
136
140
  }
@@ -1,39 +1,47 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useCallback, useEffect } from 'react';
3
+ import { useState, useCallback, useEffect } from 'react'
4
4
  import {
5
- Save, ArrowLeft, Plus, Trash2, GripVertical,
6
- MessageSquare, ExternalLink, BarChart3, ChevronDown, ChevronRight,
5
+ Save,
6
+ ArrowLeft,
7
+ Plus,
8
+ Trash2,
9
+ GripVertical,
10
+ MessageSquare,
11
+ ExternalLink,
12
+ BarChart3,
13
+ ChevronDown,
14
+ ChevronRight,
7
15
  Loader2,
8
- } from 'lucide-react';
9
- import { useApiData } from '../lib/useApiData.js';
10
- import { cmsApi } from '../lib/api.js';
16
+ } from 'lucide-react'
17
+ import { useApiData } from '../lib/useApiData.js'
18
+ import { cmsApi } from '../lib/api.js'
11
19
 
12
20
  interface FormField {
13
- id: string;
14
- type: string;
15
- label: string;
16
- placeholder?: string;
17
- required: boolean;
18
- options?: string[];
21
+ id: string
22
+ type: string
23
+ label: string
24
+ placeholder?: string
25
+ required: boolean
26
+ options?: string[]
19
27
  }
20
28
 
21
29
  interface ConfirmationConfig {
22
- type: 'message' | 'redirect';
23
- message: string;
24
- redirectUrl: string;
25
- redirectDelay: number;
30
+ type: 'message' | 'redirect'
31
+ message: string
32
+ redirectUrl: string
33
+ redirectDelay: number
26
34
  }
27
35
 
28
36
  interface AnalyticsConfig {
29
- enabled: boolean;
30
- measurementId: string;
31
- submitEventName: string;
32
- startEventName: string;
33
- trackAsConversion: boolean;
34
- conversionValue: number;
35
- conversionCurrency: string;
36
- customParameters: Record<string, string>;
37
+ enabled: boolean
38
+ measurementId: string
39
+ submitEventName: string
40
+ startEventName: string
41
+ trackAsConversion: boolean
42
+ conversionValue: number
43
+ conversionCurrency: string
44
+ customParameters: Record<string, string>
37
45
  }
38
46
 
39
47
  const FIELD_TYPES = [
@@ -48,32 +56,32 @@ const FIELD_TYPES = [
48
56
  { value: 'url', label: 'URL' },
49
57
  { value: 'file', label: 'File Upload' },
50
58
  { value: 'hidden', label: 'Hidden' },
51
- ] as const;
59
+ ] as const
52
60
 
53
61
  export interface FormEditorProps {
54
- formId?: string;
55
- onNavigate?: (path: string) => void;
62
+ formId?: string
63
+ onNavigate?: (path: string) => void
56
64
  }
57
65
 
58
66
  export function FormEditor({ formId, onNavigate }: FormEditorProps) {
59
- const isNew = !formId;
67
+ const isNew = !formId
60
68
  const { data: existingForm, loading } = useApiData<any>(
61
69
  formId ? `/collections/forms/${formId}` : null,
62
- );
70
+ )
63
71
 
64
- const [name, setName] = useState('');
65
- const [description, setDescription] = useState('');
66
- const [status, setStatus] = useState('active');
67
- const [fields, setFields] = useState<FormField[]>([]);
68
- const [saving, setSaving] = useState(false);
69
- const [expandedSection, setExpandedSection] = useState<string | null>('fields');
72
+ const [name, setName] = useState('')
73
+ const [description, setDescription] = useState('')
74
+ const [status, setStatus] = useState('active')
75
+ const [fields, setFields] = useState<FormField[]>([])
76
+ const [saving, setSaving] = useState(false)
77
+ const [expandedSection, setExpandedSection] = useState<string | null>('fields')
70
78
 
71
79
  const [confirmation, setConfirmation] = useState<ConfirmationConfig>({
72
80
  type: 'message',
73
81
  message: 'Thank you! Your submission has been received.',
74
82
  redirectUrl: '',
75
83
  redirectDelay: 0,
76
- });
84
+ })
77
85
 
78
86
  const [analytics, setAnalytics] = useState<AnalyticsConfig>({
79
87
  enabled: false,
@@ -84,23 +92,23 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
84
92
  conversionValue: 0,
85
93
  conversionCurrency: 'USD',
86
94
  customParameters: {},
87
- });
95
+ })
88
96
 
89
97
  useEffect(() => {
90
98
  if (existingForm) {
91
- const d = existingForm.data ?? existingForm;
92
- setName(d.name ?? '');
93
- setDescription(d.description ?? '');
94
- setStatus(d.status ?? 'active');
95
- if (Array.isArray(d.fields)) setFields(d.fields);
99
+ const d = existingForm.data ?? existingForm
100
+ setName(d.name ?? '')
101
+ setDescription(d.description ?? '')
102
+ setStatus(d.status ?? 'active')
103
+ if (Array.isArray(d.fields)) setFields(d.fields)
96
104
  if (d.confirmation) {
97
- setConfirmation((prev) => ({ ...prev, ...d.confirmation }));
105
+ setConfirmation((prev) => ({ ...prev, ...d.confirmation }))
98
106
  }
99
107
  if (d.analytics) {
100
- setAnalytics((prev) => ({ ...prev, ...d.analytics }));
108
+ setAnalytics((prev) => ({ ...prev, ...d.analytics }))
101
109
  }
102
110
  }
103
- }, [existingForm]);
111
+ }, [existingForm])
104
112
 
105
113
  const addField = useCallback((type: string) => {
106
114
  setFields((prev) => [
@@ -111,28 +119,28 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
111
119
  label: `New ${type} field`,
112
120
  required: false,
113
121
  },
114
- ]);
115
- }, []);
122
+ ])
123
+ }, [])
116
124
 
117
125
  const removeField = useCallback((id: string) => {
118
- setFields((prev) => prev.filter((f) => f.id !== id));
119
- }, []);
126
+ setFields((prev) => prev.filter((f) => f.id !== id))
127
+ }, [])
120
128
 
121
129
  const updateField = useCallback((id: string, updates: Partial<FormField>) => {
122
- setFields((prev) => prev.map((f) => (f.id === id ? { ...f, ...updates } : f)));
123
- }, []);
130
+ setFields((prev) => prev.map((f) => (f.id === id ? { ...f, ...updates } : f)))
131
+ }, [])
124
132
 
125
133
  const moveField = useCallback((from: number, to: number) => {
126
134
  setFields((prev) => {
127
- const next = [...prev];
128
- const [moved] = next.splice(from, 1);
129
- next.splice(to, 0, moved!);
130
- return next;
131
- });
132
- }, []);
135
+ const next = [...prev]
136
+ const [moved] = next.splice(from, 1)
137
+ next.splice(to, 0, moved!)
138
+ return next
139
+ })
140
+ }, [])
133
141
 
134
142
  const handleSave = async () => {
135
- setSaving(true);
143
+ setSaving(true)
136
144
  try {
137
145
  const payload = {
138
146
  name,
@@ -141,35 +149,35 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
141
149
  fields,
142
150
  confirmation,
143
151
  analytics: analytics.enabled ? analytics : { enabled: false },
144
- };
152
+ }
145
153
 
146
154
  if (isNew) {
147
155
  await cmsApi('/collections/forms', {
148
156
  method: 'POST',
149
157
  body: JSON.stringify(payload),
150
- });
158
+ })
151
159
  } else {
152
160
  await cmsApi(`/collections/forms/${formId}`, {
153
161
  method: 'PUT',
154
162
  body: JSON.stringify(payload),
155
- });
163
+ })
156
164
  }
157
- onNavigate?.('/forms');
165
+ onNavigate?.('/forms')
158
166
  } finally {
159
- setSaving(false);
167
+ setSaving(false)
160
168
  }
161
- };
169
+ }
162
170
 
163
171
  const toggleSection = (section: string) => {
164
- setExpandedSection(expandedSection === section ? null : section);
165
- };
172
+ setExpandedSection(expandedSection === section ? null : section)
173
+ }
166
174
 
167
175
  if (loading) {
168
176
  return (
169
177
  <div className="p-4 flex items-center justify-center h-64">
170
178
  <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
171
179
  </div>
172
- );
180
+ )
173
181
  }
174
182
 
175
183
  return (
@@ -241,7 +249,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
241
249
  className="w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors"
242
250
  >
243
251
  <div className="flex items-center gap-2">
244
- {expandedSection === 'fields' ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
252
+ {expandedSection === 'fields' ? (
253
+ <ChevronDown className="w-4 h-4" />
254
+ ) : (
255
+ <ChevronRight className="w-4 h-4" />
256
+ )}
245
257
  <span className="font-medium text-gray-900">Form Fields</span>
246
258
  <span className="text-sm text-gray-500">({fields.length})</span>
247
259
  </div>
@@ -273,8 +285,8 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
273
285
  onDragStart={(e) => e.dataTransfer.setData('text/plain', String(index))}
274
286
  onDragOver={(e) => e.preventDefault()}
275
287
  onDrop={(e) => {
276
- const from = Number(e.dataTransfer.getData('text/plain'));
277
- moveField(from, index);
288
+ const from = Number(e.dataTransfer.getData('text/plain'))
289
+ moveField(from, index)
278
290
  }}
279
291
  className="flex items-center gap-3 p-3 border border-gray-200 rounded-lg bg-gray-50 hover:bg-white transition-colors"
280
292
  >
@@ -318,7 +330,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
318
330
  className="w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors"
319
331
  >
320
332
  <div className="flex items-center gap-2">
321
- {expandedSection === 'confirmation' ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
333
+ {expandedSection === 'confirmation' ? (
334
+ <ChevronDown className="w-4 h-4" />
335
+ ) : (
336
+ <ChevronRight className="w-4 h-4" />
337
+ )}
322
338
  <MessageSquare className="w-4 h-4 text-green-600" />
323
339
  <span className="font-medium text-gray-900">Confirmation</span>
324
340
  <span className="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded">
@@ -329,10 +345,16 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
329
345
  {expandedSection === 'confirmation' && (
330
346
  <div className="border-t border-gray-200 p-4">
331
347
  <div className="mb-4">
332
- <label className="block text-sm font-medium text-gray-700 mb-2">After submission</label>
348
+ <label className="block text-sm font-medium text-gray-700 mb-2">
349
+ After submission
350
+ </label>
333
351
  <div className="flex gap-3">
334
- <label className="flex items-center gap-2 px-4 py-2 border rounded-lg cursor-pointer transition-colors hover:bg-gray-50"
335
- style={{ borderColor: confirmation.type === 'message' ? '#2563eb' : '#d1d5db', backgroundColor: confirmation.type === 'message' ? '#eff6ff' : 'transparent' }}
352
+ <label
353
+ className="flex items-center gap-2 px-4 py-2 border rounded-lg cursor-pointer transition-colors hover:bg-gray-50"
354
+ style={{
355
+ borderColor: confirmation.type === 'message' ? '#2563eb' : '#d1d5db',
356
+ backgroundColor: confirmation.type === 'message' ? '#eff6ff' : 'transparent',
357
+ }}
336
358
  >
337
359
  <input
338
360
  type="radio"
@@ -345,8 +367,12 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
345
367
  <MessageSquare className="w-4 h-4" />
346
368
  <span className="text-sm">Show Message</span>
347
369
  </label>
348
- <label className="flex items-center gap-2 px-4 py-2 border rounded-lg cursor-pointer transition-colors hover:bg-gray-50"
349
- style={{ borderColor: confirmation.type === 'redirect' ? '#2563eb' : '#d1d5db', backgroundColor: confirmation.type === 'redirect' ? '#eff6ff' : 'transparent' }}
370
+ <label
371
+ className="flex items-center gap-2 px-4 py-2 border rounded-lg cursor-pointer transition-colors hover:bg-gray-50"
372
+ style={{
373
+ borderColor: confirmation.type === 'redirect' ? '#2563eb' : '#d1d5db',
374
+ backgroundColor: confirmation.type === 'redirect' ? '#eff6ff' : 'transparent',
375
+ }}
350
376
  >
351
377
  <input
352
378
  type="radio"
@@ -364,7 +390,9 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
364
390
 
365
391
  {confirmation.type === 'message' ? (
366
392
  <div>
367
- <label className="block text-sm font-medium text-gray-700 mb-1">Success Message</label>
393
+ <label className="block text-sm font-medium text-gray-700 mb-1">
394
+ Success Message
395
+ </label>
368
396
  <textarea
369
397
  value={confirmation.message}
370
398
  onChange={(e) => setConfirmation((c) => ({ ...c, message: e.target.value }))}
@@ -376,21 +404,29 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
376
404
  ) : (
377
405
  <div className="grid gap-3">
378
406
  <div>
379
- <label className="block text-sm font-medium text-gray-700 mb-1">Redirect URL</label>
407
+ <label className="block text-sm font-medium text-gray-700 mb-1">
408
+ Redirect URL
409
+ </label>
380
410
  <input
381
411
  type="url"
382
412
  value={confirmation.redirectUrl}
383
- onChange={(e) => setConfirmation((c) => ({ ...c, redirectUrl: e.target.value }))}
413
+ onChange={(e) =>
414
+ setConfirmation((c) => ({ ...c, redirectUrl: e.target.value }))
415
+ }
384
416
  placeholder="https://example.com/thank-you"
385
417
  className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
386
418
  />
387
419
  </div>
388
420
  <div>
389
- <label className="block text-sm font-medium text-gray-700 mb-1">Redirect Delay (ms)</label>
421
+ <label className="block text-sm font-medium text-gray-700 mb-1">
422
+ Redirect Delay (ms)
423
+ </label>
390
424
  <input
391
425
  type="number"
392
426
  value={confirmation.redirectDelay}
393
- onChange={(e) => setConfirmation((c) => ({ ...c, redirectDelay: Number(e.target.value) }))}
427
+ onChange={(e) =>
428
+ setConfirmation((c) => ({ ...c, redirectDelay: Number(e.target.value) }))
429
+ }
394
430
  min={0}
395
431
  step={500}
396
432
  className="w-32 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
@@ -410,10 +446,16 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
410
446
  className="w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors"
411
447
  >
412
448
  <div className="flex items-center gap-2">
413
- {expandedSection === 'analytics' ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
449
+ {expandedSection === 'analytics' ? (
450
+ <ChevronDown className="w-4 h-4" />
451
+ ) : (
452
+ <ChevronRight className="w-4 h-4" />
453
+ )}
414
454
  <BarChart3 className="w-4 h-4 text-purple-600" />
415
455
  <span className="font-medium text-gray-900">GA4 Analytics</span>
416
- <span className={`text-xs px-2 py-0.5 rounded ${analytics.enabled ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}`}>
456
+ <span
457
+ className={`text-xs px-2 py-0.5 rounded ${analytics.enabled ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}`}
458
+ >
417
459
  {analytics.enabled ? 'Enabled' : 'Disabled'}
418
460
  </span>
419
461
  </div>
@@ -430,7 +472,9 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
430
472
  />
431
473
  <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-blue-600" />
432
474
  </label>
433
- <span className="text-sm font-medium text-gray-700">Push events to Google Analytics 4</span>
475
+ <span className="text-sm font-medium text-gray-700">
476
+ Push events to Google Analytics 4
477
+ </span>
434
478
  </div>
435
479
 
436
480
  {analytics.enabled && (
@@ -447,25 +491,35 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
447
491
  placeholder="G-XXXXXXXXXX"
448
492
  className="w-64 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
449
493
  />
450
- <p className="text-xs text-gray-500 mt-1">Leave blank to use your site's default GA4 tag</p>
494
+ <p className="text-xs text-gray-500 mt-1">
495
+ Leave blank to use your site's default GA4 tag
496
+ </p>
451
497
  </div>
452
498
 
453
499
  <div className="grid grid-cols-2 gap-4">
454
500
  <div>
455
- <label className="block text-sm font-medium text-gray-700 mb-1">Submit Event Name</label>
501
+ <label className="block text-sm font-medium text-gray-700 mb-1">
502
+ Submit Event Name
503
+ </label>
456
504
  <input
457
505
  type="text"
458
506
  value={analytics.submitEventName}
459
- onChange={(e) => setAnalytics((a) => ({ ...a, submitEventName: e.target.value }))}
507
+ onChange={(e) =>
508
+ setAnalytics((a) => ({ ...a, submitEventName: e.target.value }))
509
+ }
460
510
  className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
461
511
  />
462
512
  </div>
463
513
  <div>
464
- <label className="block text-sm font-medium text-gray-700 mb-1">Start Event Name</label>
514
+ <label className="block text-sm font-medium text-gray-700 mb-1">
515
+ Start Event Name
516
+ </label>
465
517
  <input
466
518
  type="text"
467
519
  value={analytics.startEventName}
468
- onChange={(e) => setAnalytics((a) => ({ ...a, startEventName: e.target.value }))}
520
+ onChange={(e) =>
521
+ setAnalytics((a) => ({ ...a, startEventName: e.target.value }))
522
+ }
469
523
  className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
470
524
  />
471
525
  </div>
@@ -477,7 +531,9 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
477
531
  type="checkbox"
478
532
  id="trackConversion"
479
533
  checked={analytics.trackAsConversion}
480
- onChange={(e) => setAnalytics((a) => ({ ...a, trackAsConversion: e.target.checked }))}
534
+ onChange={(e) =>
535
+ setAnalytics((a) => ({ ...a, trackAsConversion: e.target.checked }))
536
+ }
481
537
  className="rounded"
482
538
  />
483
539
  <label htmlFor="trackConversion" className="text-sm font-medium text-gray-700">
@@ -488,21 +544,29 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
488
544
  {analytics.trackAsConversion && (
489
545
  <div className="grid grid-cols-2 gap-4 ml-6">
490
546
  <div>
491
- <label className="block text-sm font-medium text-gray-700 mb-1">Conversion Value</label>
547
+ <label className="block text-sm font-medium text-gray-700 mb-1">
548
+ Conversion Value
549
+ </label>
492
550
  <input
493
551
  type="number"
494
552
  value={analytics.conversionValue}
495
- onChange={(e) => setAnalytics((a) => ({ ...a, conversionValue: Number(e.target.value) }))}
553
+ onChange={(e) =>
554
+ setAnalytics((a) => ({ ...a, conversionValue: Number(e.target.value) }))
555
+ }
496
556
  min={0}
497
557
  step={0.01}
498
558
  className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
499
559
  />
500
560
  </div>
501
561
  <div>
502
- <label className="block text-sm font-medium text-gray-700 mb-1">Currency</label>
562
+ <label className="block text-sm font-medium text-gray-700 mb-1">
563
+ Currency
564
+ </label>
503
565
  <select
504
566
  value={analytics.conversionCurrency}
505
- onChange={(e) => setAnalytics((a) => ({ ...a, conversionCurrency: e.target.value }))}
567
+ onChange={(e) =>
568
+ setAnalytics((a) => ({ ...a, conversionCurrency: e.target.value }))
569
+ }
506
570
  className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
507
571
  >
508
572
  <option value="USD">USD</option>
@@ -518,9 +582,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
518
582
 
519
583
  <div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
520
584
  <p className="text-xs text-blue-800">
521
- <strong>Note:</strong> Your site must have the GA4 snippet or GTM container installed.
522
- Actuate pushes events via <code className="bg-blue-100 px-1 rounded">gtag()</code> /
523
- <code className="bg-blue-100 px-1 rounded">dataLayer</code> — it does not load the GA4 script.
585
+ <strong>Note:</strong> Your site must have the GA4 snippet or GTM container
586
+ installed. Actuate pushes events via{' '}
587
+ <code className="bg-blue-100 px-1 rounded">gtag()</code> /
588
+ <code className="bg-blue-100 px-1 rounded">dataLayer</code> — it does not load
589
+ the GA4 script.
524
590
  </p>
525
591
  </div>
526
592
  </div>
@@ -529,5 +595,5 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
529
595
  )}
530
596
  </div>
531
597
  </div>
532
- );
598
+ )
533
599
  }