@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,66 +1,71 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, type FormEvent } from 'react';
4
- import { Shield, Eye, EyeOff, CheckCircle2, AlertTriangle } from 'lucide-react';
3
+ import { useState, type FormEvent } from 'react'
4
+ import { Shield, Eye, EyeOff, CheckCircle2, AlertTriangle } from 'lucide-react'
5
5
 
6
6
  export interface SetupWizardProps {
7
- onComplete: (data: { name: string; email: string; password: string }) => Promise<{ success: boolean; error?: string }>;
8
- siteName?: string;
7
+ onComplete: (data: {
8
+ name: string
9
+ email: string
10
+ password: string
11
+ }) => Promise<{ success: boolean; error?: string }>
12
+ siteName?: string
9
13
  }
10
14
 
11
15
  function passwordStrength(pw: string): { score: number; label: string; color: string } {
12
- let score = 0;
13
- if (pw.length >= 12) score++;
14
- if (pw.length >= 16) score++;
15
- if (/[A-Z]/.test(pw)) score++;
16
- if (/[a-z]/.test(pw)) score++;
17
- if (/\d/.test(pw)) score++;
18
- if (/[^a-zA-Z0-9]/.test(pw)) score++;
19
-
20
- if (score <= 2) return { score, label: 'Weak', color: 'bg-red-500' };
21
- if (score <= 4) return { score, label: 'Fair', color: 'bg-yellow-500' };
22
- return { score, label: 'Strong', color: 'bg-green-500' };
16
+ let score = 0
17
+ if (pw.length >= 12) score++
18
+ if (pw.length >= 16) score++
19
+ if (/[A-Z]/.test(pw)) score++
20
+ if (/[a-z]/.test(pw)) score++
21
+ if (/\d/.test(pw)) score++
22
+ if (/[^a-zA-Z0-9]/.test(pw)) score++
23
+
24
+ if (score <= 2) return { score, label: 'Weak', color: 'bg-red-500' }
25
+ if (score <= 4) return { score, label: 'Fair', color: 'bg-yellow-500' }
26
+ return { score, label: 'Strong', color: 'bg-green-500' }
23
27
  }
24
28
 
25
29
  export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizardProps) {
26
- const [name, setName] = useState('');
27
- const [email, setEmail] = useState('');
28
- const [password, setPassword] = useState('');
29
- const [confirmPassword, setConfirmPassword] = useState('');
30
- const [showPassword, setShowPassword] = useState(false);
31
- const [submitting, setSubmitting] = useState(false);
32
- const [error, setError] = useState('');
33
- const [done, setDone] = useState(false);
34
-
35
- const strength = passwordStrength(password);
36
- const passwordsMatch = password === confirmPassword;
37
- const canSubmit = name.trim() && email.trim() && password.length >= 12 && passwordsMatch && !submitting;
30
+ const [name, setName] = useState('')
31
+ const [email, setEmail] = useState('')
32
+ const [password, setPassword] = useState('')
33
+ const [confirmPassword, setConfirmPassword] = useState('')
34
+ const [showPassword, setShowPassword] = useState(false)
35
+ const [submitting, setSubmitting] = useState(false)
36
+ const [error, setError] = useState('')
37
+ const [done, setDone] = useState(false)
38
+
39
+ const strength = passwordStrength(password)
40
+ const passwordsMatch = password === confirmPassword
41
+ const canSubmit =
42
+ name.trim() && email.trim() && password.length >= 12 && passwordsMatch && !submitting
38
43
 
39
44
  const handleSubmit = async (e: FormEvent) => {
40
- e.preventDefault();
41
- if (!canSubmit) return;
45
+ e.preventDefault()
46
+ if (!canSubmit) return
42
47
 
43
- setError('');
44
- setSubmitting(true);
48
+ setError('')
49
+ setSubmitting(true)
45
50
 
46
51
  try {
47
52
  const result = await onComplete({
48
53
  name: name.trim(),
49
54
  email: email.trim(),
50
55
  password,
51
- });
56
+ })
52
57
 
53
58
  if (result.success) {
54
- setDone(true);
59
+ setDone(true)
55
60
  } else {
56
- setError(result.error ?? 'Failed to create admin account');
61
+ setError(result.error ?? 'Failed to create admin account')
57
62
  }
58
63
  } catch (err) {
59
- setError(err instanceof Error ? err.message : 'An unexpected error occurred');
64
+ setError(err instanceof Error ? err.message : 'An unexpected error occurred')
60
65
  } finally {
61
- setSubmitting(false);
66
+ setSubmitting(false)
62
67
  }
63
- };
68
+ }
64
69
 
65
70
  if (done) {
66
71
  return (
@@ -81,7 +86,7 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
81
86
  </button>
82
87
  </div>
83
88
  </div>
84
- );
89
+ )
85
90
  }
86
91
 
87
92
  return (
@@ -95,7 +100,10 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
95
100
  <p className="text-gray-600 mt-2">Create your admin account to get started</p>
96
101
  </div>
97
102
 
98
- <form onSubmit={handleSubmit} className="bg-white rounded-xl border border-gray-200 p-6 shadow-sm space-y-5">
103
+ <form
104
+ onSubmit={handleSubmit}
105
+ className="bg-white rounded-xl border border-gray-200 p-6 shadow-sm space-y-5"
106
+ >
99
107
  {error && (
100
108
  <div className="flex items-start gap-3 p-3 bg-red-50 border border-red-200 rounded-lg">
101
109
  <AlertTriangle className="w-5 h-5 text-red-600 mt-0.5 shrink-0" />
@@ -104,7 +112,9 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
104
112
  )}
105
113
 
106
114
  <div>
107
- <label htmlFor="setup-name" className="block text-sm font-medium text-gray-700 mb-1.5">Full Name</label>
115
+ <label htmlFor="setup-name" className="block text-sm font-medium text-gray-700 mb-1.5">
116
+ Full Name
117
+ </label>
108
118
  <input
109
119
  id="setup-name"
110
120
  type="text"
@@ -119,7 +129,9 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
119
129
  </div>
120
130
 
121
131
  <div>
122
- <label htmlFor="setup-email" className="block text-sm font-medium text-gray-700 mb-1.5">Email Address</label>
132
+ <label htmlFor="setup-email" className="block text-sm font-medium text-gray-700 mb-1.5">
133
+ Email Address
134
+ </label>
123
135
  <input
124
136
  id="setup-email"
125
137
  type="email"
@@ -133,7 +145,12 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
133
145
  </div>
134
146
 
135
147
  <div>
136
- <label htmlFor="setup-password" className="block text-sm font-medium text-gray-700 mb-1.5">Password</label>
148
+ <label
149
+ htmlFor="setup-password"
150
+ className="block text-sm font-medium text-gray-700 mb-1.5"
151
+ >
152
+ Password
153
+ </label>
137
154
  <div className="relative">
138
155
  <input
139
156
  id="setup-password"
@@ -171,7 +188,12 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
171
188
  </div>
172
189
 
173
190
  <div>
174
- <label htmlFor="setup-confirm" className="block text-sm font-medium text-gray-700 mb-1.5">Confirm Password</label>
191
+ <label
192
+ htmlFor="setup-confirm"
193
+ className="block text-sm font-medium text-gray-700 mb-1.5"
194
+ >
195
+ Confirm Password
196
+ </label>
175
197
  <input
176
198
  id="setup-confirm"
177
199
  type={showPassword ? 'text' : 'password'}
@@ -198,10 +220,11 @@ export function SetupWizard({ onComplete, siteName = 'Actuate CMS' }: SetupWizar
198
220
  </button>
199
221
 
200
222
  <p className="text-xs text-gray-500 text-center">
201
- This form is only available during initial setup. Once an admin account exists, it will be replaced by the login screen.
223
+ This form is only available during initial setup. Once an admin account exists, it will
224
+ be replaced by the login screen.
202
225
  </p>
203
226
  </form>
204
227
  </div>
205
228
  </div>
206
- );
229
+ )
207
230
  }
@@ -1,72 +1,83 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import * as Dialog from '@radix-ui/react-dialog';
4
- import { Pencil, Trash2, UserPlus, Search, ArrowUpDown, ArrowUp, ArrowDown, Loader2, AlertTriangle } from 'lucide-react';
5
- import { useState, useMemo, type FormEvent } from 'react';
6
- import { toast } from 'sonner';
7
- import { sortByRelevance, type SortConfig, toggleSort } from '../lib/search.js';
8
- import { useApiData } from '../lib/useApiData.js';
9
- import { cmsApi } from '../lib/api.js';
3
+ import * as Dialog from '@radix-ui/react-dialog'
4
+ import {
5
+ Pencil,
6
+ Trash2,
7
+ UserPlus,
8
+ Search,
9
+ ArrowUpDown,
10
+ ArrowUp,
11
+ ArrowDown,
12
+ Loader2,
13
+ AlertTriangle,
14
+ } from 'lucide-react'
15
+ import { useState, useMemo, type FormEvent } from 'react'
16
+ import { toast } from 'sonner'
17
+ import { sortByRelevance, type SortConfig, toggleSort } from '../lib/search.js'
18
+ import { useApiData } from '../lib/useApiData.js'
19
+ import { cmsApi } from '../lib/api.js'
10
20
 
11
- type UserSortKey = 'name' | 'role' | 'status' | 'lastLogin';
21
+ type UserSortKey = 'name' | 'role' | 'status' | 'lastLogin'
12
22
 
13
23
  export interface UsersProps {
14
- onNavigate?: (path: string) => void;
24
+ onNavigate?: (path: string) => void
15
25
  }
16
26
 
17
27
  export function Users({ onNavigate }: UsersProps) {
18
- const { data, loading, error, refetch } = useApiData<any[]>('/users');
19
- const [showInviteDialog, setShowInviteDialog] = useState(false);
20
- const [inviteEmail, setInviteEmail] = useState('');
21
- const [inviteRole, setInviteRole] = useState('editor');
22
- const [searchQuery, setSearchQuery] = useState('');
23
- const [filterRole, setFilterRole] = useState('all');
24
- const [sortConfig, setSortConfig] = useState<SortConfig<UserSortKey> | null>(null);
28
+ const { data, loading, error, refetch } = useApiData<any[]>('/users')
29
+ const [showInviteDialog, setShowInviteDialog] = useState(false)
30
+ const [inviteEmail, setInviteEmail] = useState('')
31
+ const [inviteRole, setInviteRole] = useState('editor')
32
+ const [searchQuery, setSearchQuery] = useState('')
33
+ const [filterRole, setFilterRole] = useState('all')
34
+ const [sortConfig, setSortConfig] = useState<SortConfig<UserSortKey> | null>(null)
25
35
 
26
- const users = data ?? [];
36
+ const users = data ?? []
27
37
 
28
38
  const filteredAndSorted = useMemo(() => {
29
39
  let results = users.filter((user: any) => {
30
40
  const matchesSearch =
31
41
  (user.name ?? '').toLowerCase().includes(searchQuery.toLowerCase()) ||
32
- (user.email ?? '').toLowerCase().includes(searchQuery.toLowerCase());
33
- const matchesRole = filterRole === 'all' || (user.role ?? '').toLowerCase() === filterRole.toLowerCase();
34
- return matchesSearch && matchesRole;
35
- });
42
+ (user.email ?? '').toLowerCase().includes(searchQuery.toLowerCase())
43
+ const matchesRole =
44
+ filterRole === 'all' || (user.role ?? '').toLowerCase() === filterRole.toLowerCase()
45
+ return matchesSearch && matchesRole
46
+ })
36
47
 
37
48
  if (searchQuery.trim()) {
38
- results = sortByRelevance(results, searchQuery, (u: any) => [u.name, u.email, u.role]);
49
+ results = sortByRelevance(results, searchQuery, (u: any) => [u.name, u.email, u.role])
39
50
  } else if (sortConfig) {
40
51
  results = [...results].sort((a: any, b: any) => {
41
- const aVal = a[sortConfig.key] ?? '';
42
- const bVal = b[sortConfig.key] ?? '';
43
- const cmp = String(aVal).localeCompare(String(bVal));
44
- return sortConfig.direction === 'asc' ? cmp : -cmp;
45
- });
52
+ const aVal = a[sortConfig.key] ?? ''
53
+ const bVal = b[sortConfig.key] ?? ''
54
+ const cmp = String(aVal).localeCompare(String(bVal))
55
+ return sortConfig.direction === 'asc' ? cmp : -cmp
56
+ })
46
57
  }
47
- return results;
48
- }, [users, searchQuery, filterRole, sortConfig]);
58
+ return results
59
+ }, [users, searchQuery, filterRole, sortConfig])
49
60
 
50
61
  const handleInvite = (e: FormEvent) => {
51
- e.preventDefault();
52
- toast.success(`Invitation sent to ${inviteEmail}`);
53
- setShowInviteDialog(false);
54
- setInviteEmail('');
55
- setInviteRole('editor');
56
- };
62
+ e.preventDefault()
63
+ toast.success(`Invitation sent to ${inviteEmail}`)
64
+ setShowInviteDialog(false)
65
+ setInviteEmail('')
66
+ setInviteRole('editor')
67
+ }
57
68
 
58
69
  const handleDelete = async (userId: number) => {
59
- const res = await cmsApi(`/users/${userId}`, { method: 'DELETE' });
70
+ const res = await cmsApi(`/users/${userId}`, { method: 'DELETE' })
60
71
  if (res.error) {
61
- toast.error(res.error);
72
+ toast.error(res.error)
62
73
  } else {
63
- toast.success('User removed');
64
- refetch();
74
+ toast.success('User removed')
75
+ refetch()
65
76
  }
66
- };
77
+ }
67
78
 
68
79
  function SortHeader({ label, sortKey }: { label: string; sortKey: UserSortKey }) {
69
- const active = sortConfig?.key === sortKey;
80
+ const active = sortConfig?.key === sortKey
70
81
  return (
71
82
  <button
72
83
  type="button"
@@ -75,12 +86,16 @@ export function Users({ onNavigate }: UsersProps) {
75
86
  >
76
87
  {label}
77
88
  {active ? (
78
- sortConfig!.direction === 'asc' ? <ArrowUp className="w-3 h-3" /> : <ArrowDown className="w-3 h-3" />
89
+ sortConfig!.direction === 'asc' ? (
90
+ <ArrowUp className="w-3 h-3" />
91
+ ) : (
92
+ <ArrowDown className="w-3 h-3" />
93
+ )
79
94
  ) : (
80
95
  <ArrowUpDown className="w-3 h-3 text-gray-400" />
81
96
  )}
82
97
  </button>
83
- );
98
+ )
84
99
  }
85
100
 
86
101
  if (loading) {
@@ -88,7 +103,7 @@ export function Users({ onNavigate }: UsersProps) {
88
103
  <div className="p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64">
89
104
  <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
90
105
  </div>
91
- );
106
+ )
92
107
  }
93
108
 
94
109
  return (
@@ -97,7 +112,12 @@ export function Users({ onNavigate }: UsersProps) {
97
112
  <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
98
113
  <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
99
114
  <span className="text-sm text-red-800 flex-1">{error}</span>
100
- <button onClick={refetch} className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors">Retry</button>
115
+ <button
116
+ onClick={refetch}
117
+ className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
118
+ >
119
+ Retry
120
+ </button>
101
121
  </div>
102
122
  )}
103
123
 
@@ -151,91 +171,105 @@ export function Users({ onNavigate }: UsersProps) {
151
171
  <p className="text-sm text-gray-500">Invite your first user to get started.</p>
152
172
  </div>
153
173
  ) : (
154
- <div className="rounded-lg border border-gray-200 bg-white">
155
- <div className="overflow-x-auto">
156
- <table className="w-full">
157
- <thead className="border-b border-gray-200 bg-gray-50">
158
- <tr>
159
- <th className="px-4 py-2 text-left"><SortHeader label="User" sortKey="name" /></th>
160
- <th className="px-4 py-2 text-left"><SortHeader label="Role" sortKey="role" /></th>
161
- <th className="px-4 py-2 text-left"><SortHeader label="Status" sortKey="status" /></th>
162
- <th className="px-4 py-2 text-left"><SortHeader label="Last Active" sortKey="lastLogin" /></th>
163
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-700">Actions</th>
164
- </tr>
165
- </thead>
166
- <tbody className="divide-y divide-gray-200">
167
- {filteredAndSorted.map((user: any) => (
168
- <tr key={user.id} className="transition-colors hover:bg-gray-50">
169
- <td className="px-4 py-3">
170
- <div className="flex items-center gap-3">
171
- <div className="flex h-10 w-10 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-purple-600 text-sm font-medium text-white">
172
- {user.name.charAt(0)}
173
- </div>
174
- <div>
175
- <div className="text-sm font-medium text-gray-900">{user.name}</div>
176
- <div className="text-xs text-gray-600">{user.email}</div>
174
+ <div className="rounded-lg border border-gray-200 bg-white">
175
+ <div className="overflow-x-auto">
176
+ <table className="w-full">
177
+ <thead className="border-b border-gray-200 bg-gray-50">
178
+ <tr>
179
+ <th className="px-4 py-2 text-left">
180
+ <SortHeader label="User" sortKey="name" />
181
+ </th>
182
+ <th className="px-4 py-2 text-left">
183
+ <SortHeader label="Role" sortKey="role" />
184
+ </th>
185
+ <th className="px-4 py-2 text-left">
186
+ <SortHeader label="Status" sortKey="status" />
187
+ </th>
188
+ <th className="px-4 py-2 text-left">
189
+ <SortHeader label="Last Active" sortKey="lastLogin" />
190
+ </th>
191
+ <th className="px-4 py-2 text-left text-xs font-medium text-gray-700">Actions</th>
192
+ </tr>
193
+ </thead>
194
+ <tbody className="divide-y divide-gray-200">
195
+ {filteredAndSorted.map((user: any) => (
196
+ <tr key={user.id} className="transition-colors hover:bg-gray-50">
197
+ <td className="px-4 py-3">
198
+ <div className="flex items-center gap-3">
199
+ <div className="flex h-10 w-10 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-purple-600 text-sm font-medium text-white">
200
+ {user.name.charAt(0)}
201
+ </div>
202
+ <div>
203
+ <div className="text-sm font-medium text-gray-900">{user.name}</div>
204
+ <div className="text-xs text-gray-600">{user.email}</div>
205
+ </div>
177
206
  </div>
178
- </div>
179
- </td>
180
- <td className="px-4 py-3">
181
- <span
182
- className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
183
- user.role === 'Admin'
184
- ? 'bg-purple-100 text-purple-800'
185
- : user.role === 'Editor'
186
- ? 'bg-blue-100 text-blue-800'
187
- : 'bg-gray-100 text-gray-800'
188
- }`}
189
- >
190
- {user.role}
191
- </span>
192
- </td>
193
- <td className="px-4 py-3">
194
- <span
195
- className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
196
- user.status === 'Active' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
197
- }`}
198
- >
199
- {user.status}
200
- </span>
201
- </td>
202
- <td className="px-4 py-3 text-sm text-gray-600">{user.lastLogin}</td>
203
- <td className="px-4 py-3">
204
- <div className="flex items-center gap-2">
205
- <button
206
- type="button"
207
- onClick={() => onNavigate?.(`/users/${user.id}`)}
208
- className="rounded p-1.5 transition-colors hover:bg-gray-100"
209
- aria-label={`Edit ${user.name}`}
207
+ </td>
208
+ <td className="px-4 py-3">
209
+ <span
210
+ className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
211
+ user.role === 'Admin'
212
+ ? 'bg-purple-100 text-purple-800'
213
+ : user.role === 'Editor'
214
+ ? 'bg-blue-100 text-blue-800'
215
+ : 'bg-gray-100 text-gray-800'
216
+ }`}
210
217
  >
211
- <Pencil className="h-4 w-4 text-gray-600" />
212
- </button>
213
- <button
214
- type="button"
215
- onClick={() => handleDelete(user.id)}
216
- className="rounded p-1.5 transition-colors hover:bg-gray-100"
217
- aria-label={`Remove ${user.name}`}
218
+ {user.role}
219
+ </span>
220
+ </td>
221
+ <td className="px-4 py-3">
222
+ <span
223
+ className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
224
+ user.status === 'Active'
225
+ ? 'bg-green-100 text-green-800'
226
+ : 'bg-gray-100 text-gray-800'
227
+ }`}
218
228
  >
219
- <Trash2 className="h-4 w-4 text-red-600" />
220
- </button>
221
- </div>
222
- </td>
223
- </tr>
224
- ))}
225
- </tbody>
226
- </table>
229
+ {user.status}
230
+ </span>
231
+ </td>
232
+ <td className="px-4 py-3 text-sm text-gray-600">{user.lastLogin}</td>
233
+ <td className="px-4 py-3">
234
+ <div className="flex items-center gap-2">
235
+ <button
236
+ type="button"
237
+ onClick={() => onNavigate?.(`/users/${user.id}`)}
238
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
239
+ aria-label={`Edit ${user.name}`}
240
+ >
241
+ <Pencil className="h-4 w-4 text-gray-600" />
242
+ </button>
243
+ <button
244
+ type="button"
245
+ onClick={() => handleDelete(user.id)}
246
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
247
+ aria-label={`Remove ${user.name}`}
248
+ >
249
+ <Trash2 className="h-4 w-4 text-red-600" />
250
+ </button>
251
+ </div>
252
+ </td>
253
+ </tr>
254
+ ))}
255
+ </tbody>
256
+ </table>
257
+ </div>
227
258
  </div>
228
- </div>
229
259
  )}
230
260
 
231
261
  <Dialog.Root open={showInviteDialog} onOpenChange={setShowInviteDialog}>
232
262
  <Dialog.Portal>
233
263
  <Dialog.Overlay className="fixed inset-0 z-50 bg-black/50" />
234
264
  <Dialog.Content className="fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg">
235
- <Dialog.Title className="mb-4 text-lg font-semibold text-gray-900">Invite User</Dialog.Title>
265
+ <Dialog.Title className="mb-4 text-lg font-semibold text-gray-900">
266
+ Invite User
267
+ </Dialog.Title>
236
268
  <form onSubmit={handleInvite} className="space-y-4">
237
269
  <div>
238
- <label className="mb-1 block text-sm font-medium text-gray-700">Email Address</label>
270
+ <label className="mb-1 block text-sm font-medium text-gray-700">
271
+ Email Address
272
+ </label>
239
273
  <input
240
274
  type="email"
241
275
  value={inviteEmail}
@@ -278,5 +312,5 @@ export function Users({ onNavigate }: UsersProps) {
278
312
  </Dialog.Portal>
279
313
  </Dialog.Root>
280
314
  </div>
281
- );
315
+ )
282
316
  }
@@ -1,16 +1,16 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useCallback } from 'react';
4
- import { Sparkles, Loader2 } from 'lucide-react';
5
- import { toast } from 'sonner';
6
- import { cmsApi } from '../../lib/api.js';
7
- import type { BlockNode } from '@actuate-media/cms-core';
3
+ import { useState, useCallback } from 'react'
4
+ import { Sparkles, Loader2 } from 'lucide-react'
5
+ import { toast } from 'sonner'
6
+ import { cmsApi } from '../../lib/api.js'
7
+ import type { BlockNode } from '@actuate-media/cms-core'
8
8
 
9
9
  export interface AIBlockAssistProps {
10
- block: BlockNode;
11
- pageTitle?: string;
12
- businessName?: string;
13
- onUpdateData: (data: Record<string, unknown>) => void;
10
+ block: BlockNode
11
+ pageTitle?: string
12
+ businessName?: string
13
+ onUpdateData: (data: Record<string, unknown>) => void
14
14
  }
15
15
 
16
16
  export function AIBlockAssist({
@@ -19,10 +19,10 @@ export function AIBlockAssist({
19
19
  businessName,
20
20
  onUpdateData,
21
21
  }: AIBlockAssistProps) {
22
- const [generating, setGenerating] = useState(false);
22
+ const [generating, setGenerating] = useState(false)
23
23
 
24
24
  const handleGenerate = useCallback(async () => {
25
- setGenerating(true);
25
+ setGenerating(true)
26
26
 
27
27
  try {
28
28
  const res = await cmsApi<Record<string, unknown>>('/page-builder/generate-block', {
@@ -35,20 +35,20 @@ export function AIBlockAssist({
35
35
  businessName,
36
36
  },
37
37
  }),
38
- });
38
+ })
39
39
 
40
40
  if (res.error) {
41
- toast.error(res.error);
41
+ toast.error(res.error)
42
42
  } else if (res.data) {
43
- onUpdateData(res.data);
44
- toast.success('Content generated');
43
+ onUpdateData(res.data)
44
+ toast.success('Content generated')
45
45
  }
46
46
  } catch {
47
- toast.error('Failed to generate content');
47
+ toast.error('Failed to generate content')
48
48
  } finally {
49
- setGenerating(false);
49
+ setGenerating(false)
50
50
  }
51
- }, [block, pageTitle, businessName, onUpdateData]);
51
+ }, [block, pageTitle, businessName, onUpdateData])
52
52
 
53
53
  return (
54
54
  <button
@@ -57,12 +57,8 @@ export function AIBlockAssist({
57
57
  className="flex items-center gap-1.5 px-2.5 py-1 text-xs text-primary hover:bg-primary/10 rounded-md transition-colors disabled:opacity-50"
58
58
  title="Generate content with AI"
59
59
  >
60
- {generating ? (
61
- <Loader2 size={12} className="animate-spin" />
62
- ) : (
63
- <Sparkles size={12} />
64
- )}
60
+ {generating ? <Loader2 size={12} className="animate-spin" /> : <Sparkles size={12} />}
65
61
  {generating ? 'Generating...' : 'AI Fill'}
66
62
  </button>
67
- );
63
+ )
68
64
  }